Jump to content

My First Recursive Complex Custom Function


This topic is 6958 days old. Please don't post here. Open a new topic instead.

Recommended Posts

This single function, will recreate the folder structure, copy, and unlock the file. For instance:

You have a cd that has a file on it that goes to: Disk1:Folder1:Folder2:Folder3:file.txt

You want to move the complete file structure to: Macintosh HD:MyFolder:

Your result after running this function would be: Macintosh HD:MyFolder:Folder1:Folder2:Folder3:file.txt

All with one function!

Recursive_Create_Folder ( start; stop; DrivePath; Save Path; Fpath; OS; FL_Name )

Start = (I always start at 1 to make this work right.)

Stop = (I always start with 2 to make this work right.)

DrivePath = The name of the Disk

SavePath = where you want to Save

Fpath = The path to the file that you want to copy (- the filename in my db)

OS = What OS u on? MAC OR WIN?

FL_Name = Filename.

*****YOU MUST HAVE Troi File Plug in For this to actually work for you.*****


Let ([ 

a = DrivePath;  *Get DrivePath (Disk Name)*

b = Save Path;  *Get SavePath*

c = Fpath;        *Path to the file*

d = Substitute ( c ; a ; "" );   *Remove the disk name, and replace it with the name of the folder to save into*

e = If (Left(d; 1) = ":" or Left (d; 1) = ""; Replace ( d ; 1 ; 1 ; "" ); d);  *Just incase i have a leading *

f = If (OS = "MAC"; ":"; "");      *Set the folder separator*

g = Substitute ( e ; f & f & f ; f );     *Remove duplicate :'s or 's*

h = Substitute ( g ; f & f ; f );          *Remove them again (Just incase).

i = f & h;                                        *Add 1 : or  to beginning(So we can start at 1'st occurance)*

j = GetAsNumber(PatternCount ( i ; f ));    *See how many folders deep we are*

l = OS;                                                 *I use this to carry over to the function next time*

n = GetAsNumber(start);                       *Just setting the Start and stop as n and o so I can add to it when I recall script*

o = GetAsNumber(stop);

p = FL_Name;                             *Get File Name*

y = GetAsNumber(Position ( i ; f ; 1 ; n ));                *Get position of the Start : or *

z = GetAsNumber(Position ( i ; f ; 1 ; o ));                *Get position of the Stop : or *

m = If( n = 1; b; b & Left ( i; Position ( i ; f ; 1 ; n )));        *This gets the path to where we are now in script*

k = TrFile_CreateFolder( "" ; m  & Middle ( i ; y + 1 ; z - (y + 1)));      *Create the folder*

abc = If ( j = n ; TrFile_CopyFile(""; c & p; m  & Middle ( i ; y + 1 ; z - (y + 1)) & ":" & p ); "");     *Copy the file, if were done coping folders.

def = If (abc = 0; TrFile_SetFileAttribute( "-unlock"; m  & Middle ( i ; y + 1 ; z - (y + 1)) & ":" & p; ""; "" ); abc)       *Unlock the file if we've copied it with no errors*

];







If ( j = n ; 

def;

Recursive_Create_Folder ( n + 1; o + 1; a; b; c; l; p ) 



)) 

Now realize, that i've done some things that might seem wierd, but its because of how i've set up my database (which is under contract, can't post it.)

So, I could have gotten the filename in my let statment, and not had to carry it over each time, I could have combined my Filename and my File path to do this, but since I had them broken down into seperate fields already I didn't see the big deal.

What do you guys think? Anything I messed up, this is my first recursive function so any pointers would be great.

Also, I added my comments for you guys, I realize they won't work like that in FM.

Link to comment
Share on other sites

First of all, congratulations. BigThumbUp.gif

This looks like a real eye-crosser.

A few comments:

You may have caught on to my preference for not exposing "utility" parameters.

Recursive_Create_Folder ( start; stop; DrivePath; Save Path; Fpath; OS; FL_Name )

is just too confusing.

I would pare it down to this for the "exposed" function:

TrFilePath ( FileName ; SrcPath ; DstDrive ; DstPath )

Or better yet:

TrFilePath ( FileName ; SrcPath ; DstPath )

Notice that I renamed the parameters that I kept to be more explicit about what input is needed. Second, I got rid of the counters, as they could be religated to a sub-function, or piggybacked if you really want to get insane. Third I got rid of the OS parameter, because I would just use Get ( SystemPlatform ) inside the function for this. Lastly, as you are requiring that the source disk be included as part of the source path, why not include the destination disk as part of the destination path? Lastly, why the huge function name? I picked something both more terse and descriptive.

I'm not sure I totally get your objective here (is it to recreate the directory structure?), but I think you can still see my points with regard to simplifying and standardizing your parameter nomenclature.

Last comment:

You can markup your CF with actual comments that make it cut/pasteable. Example:

Let ([ 

a = DrivePath;  //Get DrivePath (Disk Name)

b = Save Path;  //Get SavePath

c = Fpath;        //Path to the file

d = Substitute ( c ; a ; "" );   //Remove the disk name, and replace it with the name of the folder to save into

<etc>




... or you could use this style:




Let ([ 

a = DrivePath;  /*Get DrivePath (Disk Name)*/

b = Save Path;  /*Get SavePath*/

c = Fpath;        /*Path to the file*/

d = Substitute ( c ; a ; "" );   /*Remove the disk name, and replace it with the name of the folder to save into*/

<etc>

Either method of commenting your CF can be kept inline with the real code, and is highly recommended.

Link to comment
Share on other sites

Thanks for the feedback, I realize I could have used a 2nd function instead of carrying some of the information over, but I was trying to do this with just one function, just for my own mind.

Basically, I use this function in a custom application that scans disks. I scan the disk, and then copy the files down into a specified folder. But, the files need to keep their exact structure that they had on the disk. This does that for me all at once.

I didn't even think about my function nameing convention, just put something in there. Thanks for the input on that though, I can see where that could get annoying to use.

Also, the reason I'm carrying all of those paramaters with the Function name is because I've already used them so many times in the scan (It has to look a certain way), that I ended up just setting them to fields. I didn't see the point of redoing a calculationi that I've already done somewhere else. For instance, Operating system. I've used that so many times that I went ahead and made it part of my startup script to set it as a field.

The reason I need the source disk and not the destenation disk.

The Filepath Source part has the destenation disk in it, Already set to a field elsewhere. I replace that one part of the Path to the source file, with just the dest path. That way, I keep the rest of the folder structure, but replace the Disk name with say "Macintosh HD:MyDB:Files:" This is because I need the exact path to the file on the disk, and i'm recreating that path at the Destenation path.

So, the Dest path isn't actually where the file is going, its where the folders are going.

Thanks again for your feedback!

Link to comment
Share on other sites

This topic is 6958 days old. Please don't post here. Open a new topic instead.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.