Thursday, November 15, 2012

Working with multiple script parameters

When writing scripts in FileMaker Pro I feel that it is important to make as many reusable scripts as possible. A reusable script is not just a script that can be called from, say a list- and detail-view of the same table occurrence. According to me a fully reusable script is a script that can be called from wherever and whenever. The developer calling the script should not have to worry about what layout or context the user is in, not even which mode the current window is set to (browse, find or browse). It is also important to make it easy to understand if the script calls any GUI elements and if there is a silent mode for delicate processes or scheduled server scripts and the WPE.

This blogpost is not a lesson in writing reusable scripts, it is a guide to one of the ways to work with multiple script parameters. Being able to declare more then one script parameter in a fast and secure way and also to fetch those parameter values inside the script is a key element of writing reusable scripts. Everything inside the script that is configurable should be possible to set using script parameters.

One of the simplest ways of passing many parameters to a script is by simply using a list of values (values separated with line break). Inside the script the values is separated using getValue(). This however fails as soon as you want to pass a value that could contain line breaks.

The more complex way to do it is by defining your own separator or sending values in a XML like format or simular.  That would fix the line break issue but not the issue of storing the values inside script variables and not without using quite a lot of lines in the beginning of the script.

I wanted be able to declare several script parameters, named and ready to use, on the single textline that is available for us for passing a parameter to a script. Also I wanted to avoid making my script super long only because the need to divide string values into script variables. After thinking about it for a while I came up with two custom functions. One takes care of binding a value to a parameter name and the other takes care of defining the named parameters as script variables.

There are many ways to do this or things simluar to this and what I will show you here is just my way of doing it. It is fast, reliable and I use is all the time. It handles declaring both one- and two-dollar-variables and even repeated variables. You don´t have to worry about forbidden characters or patterns since there are none. It even works when returning values from a finish script kind of like using multiple script results.

The two custom functions looks like this

RegisterParam ( name ; value )


Let([
n = Substitute( name; ["¶";""]; [" ";""];["$";""];["-";""];[".";""];["+";""];["-";""];["*";""];["/";""];["\\";""];["\"";""];["'";""];["!";""];["#";""];["€";""];["%";""];["&";""];["(";""];[")";""];["{";""];["}";""];[",";""];["<";""];[">";""];["?";""];["´";""];["`";""];["=";""];[",";""];["§";""];["°";""]);

$$_RegisterParamController = Case(
PatternCount( "¶"&$$_RegisterParamController&"¶"; "¶"&n&"¶")<1 and Length(Value)>0; $$_RegisterParamController & n&"¶";
PatternCount( "¶"&$$_RegisterParamController&"¶"; "¶"&n&"¶")>0 and Length(Value)<1; Let($$_RegisterParamController[ValueCount(Left($$_RegisterParamController; Position("¶"&$$_RegisterParamController&"¶"; "¶"&n&"¶"; 0; 1))) + 1] ="";Replace($$_RegisterParamController; Position("¶"&$$_RegisterParamController&"¶"; "¶"&n&"¶"; 0; 1); Length(n)+1; "¶"));
$$_RegisterParamController);

r = ValueCount(Left($$_RegisterParamController; Position("¶"&$$_RegisterParamController&"¶"; "¶"&n&"¶"; 0; 1))) + 1;

$$_RegisterParamController[r] = If(r>1; value; $$_RegisterParamController[r])

];"")



RegisterParamsAsVariables ( )


Let([

n = GetValue($$_RegisterParamController; ValueCount($$_RegisterParamController));

e = If(n="";"";Evaluate("let($" & n & "=$$_RegisterParamController[ValueCount($$_RegisterParamController)+1];\"\")"));

$$_RegisterParamController[ValueCount($$_RegisterParamController)+1] = "";

$$_RegisterParamController = LeftValues ( $$_RegisterParamController; ValueCount($$_RegisterParamController)-1)

];

If(ValueCount($$_RegisterParamController)>0; RegisterParamsAsVariables;"")

)


I will not spend time explaining the syntax of the calculations. If you feel curious I´m sure you are able to reverse engineer the syntax and understand what is going on. I will however show you how to use the functions.

First of you need to create the two functions in your FileMaker file. Goto the Manage Custom Functions Dialog and add two new functions. The first one must be named RegisterParams and have two parameters, "name" and "value".
The second function must be called RegisterParamsAsVariables and it uses no parameters. You can simply copy and paste the syntax from above the the two functions.


You are now ready to go. To testdrive the two functions you can do the following. Create a button on your layout and make it perform a script. As parameter to the script pass the following example:

RegisterParam ( "test1" ; "Hello World" ) & 
RegisterParam ( "test2" ; "We love FileMaker" ) &
RegisterParam ( "test3" ; "Matt Petrowsky is a funny guy" ) &
RegisterParam ( "test4" ; "Brian Dunning got > 100 Custom Functions" )



As you might figure out this will pass four different parameters to your script (no offense ment to Matt or Brian!). Before you can use them though you must perform the second function called RegisterParamsAsVariables inside your script. How you perform it does not matter, the simplest way is to set a dummy script variable to the result of the metod. Since RegisterParamsAsVariables does not return any values the dummy variable will never exist. A simple test script looks like this


The first line is all we really need but to be able to show you in the Data Viewer what happens I also added a second script step after setting the dummy variable.
When stepping trough the script before setting the dummy variable the Data Viewer looks like this.


But after running the RegisterParamsAsVariables function (setting the dummy variable) the proper script variables has been set and are ready to use.



If you want to set a two-dollar-variable or repeated variable simple prepend your parameter name with a dollar sign or append brackets with the preferred repetition number, or both =)


RegisterParam ( "normalValue" ; "Hello World" ) & 
RegisterParam ( "$twoDollarVar" ; "We love FileMaker" ) &
RegisterParam ( "normalValueRepeated[5]" ; "Matt Petrowsky is a funny guy" ) &
RegisterParam ( "$twoDollarVarRepeated[5]" ; "Brian Dunning got > 100 Custom Functions" )


I hope you can use these functions for something good, they work well for me! Time for lunch!

No comments:

Post a Comment