I can think of hundreds of times when I found myself pounding my head against the desk because I had to define yet another global field just to pass a simple value from one script to another. Like you, I myself hate to have lots of cruft clogging up my databases. Luckily, FileMaker 7+ gave us the wonderful addition of script parameters to help relieve this plight. Sometimes, even this isn’t enough and that’s where passing multiple parameters takes over.
Whenever a script is chosen in a perform script step, Filemaker shows a box for an optional script parameter. You can type in whatever your programming heart desires or you can click the edit button and take advantage of Filemaker’s many built-in functions to construct a parameter. Many times, when presented with this option you probably find yourself thinking . . . Boy, I wish I had space for a bunch of different parameters. Well with the use of that tiny edit button, a couple of Filemaker’s functions and a little bit of ingenuity this actually ends up being doable. To pass multiple parameters in filemaker we are basically going to make a ¶ delimited list and then crowbar individual parameters out using the `MiddleValues()`.
Ok, let’s say we are trying to create a new line item for an order we are going to fulfill for 3 iPhones at a price of $499. We don’t want to have to put the part number (iPhone), the description (“The coolest phone I have ever seen. Wow, it’s also really cheap!”) the quantity(3) and the price($499) in a bunch of different globals to pass our script, so we will just send them in using the script parameter. To do this, select the perform script step and pick the script you are going to call. Then hit the edit button next to the “Optional Script Parameter” box. Filemaker’s trusty old calculation window will pop up and you’re ready to roll. All you have to do is make the parameters you would like to pass into a list like so:
“iPhone” & ¶ &
“The coolest phone I have ever seen. Wow, it’s also really cheap!” & ¶ &
3 & ¶ &
499
Hit Ok and you are done with your parameter passing. Now comes the part where you pop the values you want from the script parameter. To do this we are just going to simply use the `MiddleValues()` function. The complete signature of `Middlevalues()` is:
MiddleValues ( text ; startingValue ; numberOfValues )
>Note: Thanks to David Richards (from the comments) and Genx (from [FMForums.com][1] for pointing out that you can simplify these calcs using `GetValue` instead of `MiddleValues`. We needed FileMaker 7 support for this particular setup, but if you can live with 8+ only, they’re absolutely right. `GetValue` does not include the trailing ¶ so you can avoid all the mumbo jumbo about cleaning that up.
[1]:http://fmforums.com/
The sole purpose of this function is taking a list of ¶ separated values, exactly like we created in the previous step, and select the values you specify from it. For instance, let’s say we are in the script we called in the first step and we want to get the quantity out of the script parameter. All we would need to do is execute the following bit of code:
MiddleValues( Get ( ScriptParameter ) ; 3 ; 1 )
This step tells Filemaker to start from the third value in the script parameter and return one value which is effectively just saying give me the third value in the list. If you want the fourth value, the price, just change the number 3 to a 4. The one will always stay the same because you wouldn’t really want to get more then one value out of the script parameter at a time. It wouldn’t really make sense in a typical script.
We have the value out, we still aren’t quite finished. The `MiddleValues` function doesn’t get ride of the annoying ¶ that we tacked on the end of our parameters so to delete it we have to add the following code:
Let(
parameter = MiddleValues( Get ( ScriptParameter ) ; 2 ; 1 ) ;
If (
right ( parameter ; 1 ) = ¶ ;
left( parameter; length( parameter ) – 1 ) ;
parameter
)
)
This code is a little confusing but it is basically saying if we have a ¶ on the end of our parameter take it off.
Now that you have seen how we plan on getting the values out, you are probably thinking to yourself… What happens if I pass a ¶ in the middle of one of my parameters. This isn’t exactly out of the realm of possibility and it would clearly break your code. For instance if you changed the description on the iphone to read:
“iPhone” & ¶ &
“The coolest phone I have ever seen.¶Wow, it’s also really cheap!” & ¶ &
“” & ¶ &
499
Unfortunately, Filemaker will mush (concatenate for you technical types) everything together and create the following list:
iPhone¶
The coolest phone I have ever seen.¶
Wow, it’s also really cheap!¶
¶
499
Now, everything has been shifted down one because of that extra ¶ and we can no longer get the price, quantity nor description that we expect. To take care of this we have to escape the ¶ so that it turns it into just a symbol rather then turning it into a new line in your text. To implement this change we will have to change how we create our list. I know I lied to you, you weren’t quite done with creating your parameter list. Here is the function you will need:
Name: Parameter
Parameters: value
Formula: Substitute( value ; “¶”; “\¶” ) & ¶
Using our new code we would rewrite our last list to:
parameter( “iPhone” ) &
parameter( “The coolest phone I have ever seen.¶Wow, it’s also really cheap!” ) &
parameter( “” ) &
parameter( 499 )
Not only does this list look a heck of a lot cooler, but it is more functional and a LOT easier to read. OK, we have a custom function to add parameters to a list, we should probably create one to get all that information out so we don’t have to type that horrible blob of code ever again:
Name: GetParameter
Parameters: number
Formula:
Let(
parameterValue = MiddleValues( Get ( ScriptParameter ) ; number ; 1 ) ;
substitute( left( parameterValue; length( parameterValue ) – 1 ) ; “\¶” ‘ “¶” )
)
Before you go off and pass around parameters all willy nilly, there is one final warning when using this style of parameter passing. To demonstrate it, Let’s go back to our iPhone example. Say that you don’t want to include the quantity just yet, but you still want to send over the price and description. If you tried the following:
Parameter(“iPhone”) &
Parameter(“The coolest phone I have ever seen. Wow, it’s also really cheap!”) &
Parameter(499)
The $499 will go into the quantity field because your script that creates the line item thinks that the quantity is the third value, but because the quatity isn’t there the price has shifted up into the third position. To alleviate this problem you just need to make sure that you ALWAYS pass all the parameters to a script, even if one is empty. So your parameter list should look like this:
Parameter(“iPhone”) &
Parameter(“The coolest phone I have ever seen. Wow, it’s also really cheap!”) &
Parameter(“”) &
Parameter(499)
Hopefully, many of you find this quite useful and it will help you build more powerful and less cluttered databases. For those who would like a more technically advanced way of passing parameters, where you can actually associate each parameter with a name, such as qty = 2, then check back soon for another article.
Use the ‘GetValue’ function instead of ‘MiddleValues’, you won’t need to remove the carriage returns.
@david: You are absolutely right. The only trouble is GetValue doesn’t exist in FileMaker 7, and for reasons client-inspired, this technique needed 7 support. Maybe someday we’ll update the calcs to be a little cleaner in 8+. Thanks for the input 🙂
PS: Jesse will be posting his even cooler advanced multi-parameter system shortly. This is the one we use in every project now. It makes complex scripting so much more fun…
Geoff
A solution I’ve been using since FP7 is more or less your code, but as a simple “one liner” 🙂
Substitute ( MiddleValues ( Get( ScriptParameter );n;1) ; ¶ ; “” )
where n is the parameter you want to get.
The parameters are sent the same way :
Parameter1 & ¶ & Parameter2 & ¶ & Parameter3 … etc.
It’s perhaps just a little tidier than your way 😉
@Charles – That is exactly how we do it in our fp7 solutions…. To tell you the truth I have no idea why I wrote it the way I did for this article. 🙂 Thanks for the tip.
I ran into a need for this function recently, converting a FM9 solution to IWP deployment, and the requirement for the non-supported custom dialog boxes, of which I had used 42 in the FM application. 35 of which, however, were pure informational on failure to complete something (OK is the only response, met with a resume script step to handle the modal response), but were of 2 different sizes; one with 20+- words, and the other with 200+- words. In IWP, this doesn’t matter – it’ll use the entire browser window. However, some clients will be using the FMremote, and, rather than leave the custom dialog function, and trapping the web access user in a conditional statement, I put a S_ or L_ in front of the script parameter. Parsing for the first character, gives me the conditional for Small or Large window size, while the remainder of the now field-level-metadata script parameter provides the conditional to pick up the right text to display in a single global field. The underscore is not as pretty as the paragraph delimiter, but is easy to read, and displays on a single line.
Not having any problems, but have I “screwed-the-pooch” someplace in this approach??
Kirk:
No harm done to the pooch, so far as I can tell. Jesse’s solution is just a more generalized approach that can be used:
1: For as many parameters as you want
2: Reliably with any data
3: Consistently across many different scripts with no specialized knowledge
The idea is that you can use custom functions to easily handle the “tricky” part of passing parameters, so that when you actually pass and receive them, it is simple.
Geoff
Richard;
The GetValue will only grap the first line of a passing parameter which contains paragraph:
Example:
PassPara : ” The fox jump up the moon
and the moon shine on the fox”
GetValue(Get(Scriptparameter);1) will grap “The fox jump up the moon”
How can I get the rest of the words or paragraph?