UPDATE: this post is quite old. I still thing custom functions are not as portable as they should be. However in any complex solution I use the custom functions. The ones I use are from modularfilemaker.org

Whats the best way to pass multiple parameters to a script?  Many people use custom functions to package up name value pairs into a text string, and another custom function to parse them out. Other people write name value pairs in the form of a Let Function so they can be easily turned into $script variables in the script being called. I would like to argue for much simpler approach that employs pure built in FileMaker functions, and is very easy to use.First, lets discus Custom Functions.  Custom Functions have their place. There are times when nothing else will do. But  for something  that is so basic and fundamental to good system design as passing multiple script parameters to a script, they are more trouble then they are worth.

Custom functions are not as portable as they should be.  If you don’t have FileMakwer Advanced, you can’t put them into your file. There is no way to automatically install them.  This makes your code fragile.  It will break when it is moved into a new file that doesn’t have the custom function.  Also lots of people insists on using their own custom functions for passing parameters. These different implementations are often compatible with one another. This makes it harder to share code with other developers.

Another common technique is to pass parameters in the form of a Let Function Variable Declaration.  This look something like this

“$firstName=”Todd”; “$lastName = “Geist””

Then the script being called can wrap that string in the rest of the Let function and use Evaluate() to declare the variables as $Variables in the script being called.  This is better than using custom functions. Your code is more robust because there are no dependancies that may or may not be in place.

But constructing these strings is pretty difficult there is a lot of escaping that has to go on to get everything quoted correctly.  This can be improved somewhat by using other code to take care of adding the dollar signs and the quoting later just before you use Evaluate. Then you can write the multi-parameter string like this:

“firstName=Todd; lastName= Geist”

This might be easier to write, but we have just introduced a dependency.  I have to have code in my solution in a custom function, script, or just calculation snippet that can correctly handle this string. So I don’t think I am better off than using custom functions.

Another thing to consider is that probably 50 percent of the time you are only passing one single parameter to a Script. I don’t think it makes much sense to have to write that in the form of a name value pair. Its overkill.

So what do we do?  How do we handle this with the least amount of fuss?

I think the easiest thing is to pass multiple parameters using the List f() Function, and then use the GetValue() function in the calling script to parse the parameters out into discrete variables in the script being called.  That looks like this:

List( “Todd”; “Geist”)

or if you prefer

List(
  “Todd”;
  “Geist”
 )

Then the script being called I can just do this.

Set Variable $firstName = GetValue( Get(ScriptParameter ); 1 );
Set Variable $lastName = GetValue( Get(ScriptParameter ); 2 );

This is simple to write and simple to parse. It is easy to read and easy to understand. It has no dependancies, and therefor will not break as you pass it around from file to file.

It does have some downsides, although I don’t think they are significant.  One is that sometime you have to pass empty parameters because the order matters. If you leave the first parameter out, then the second one becomes the first, and so on.  But this is how all built in FileMaker functions work, so I don’t see this as a big deal. The only other case where using something like Name Value pairs might make some sense is when you need to pass a large number of parameters, many of which are optional.

So the next time you-rethink your Multiple Parameter strategy,  I hope you will consider using the simple, native functions that Filemaker provides rather than introducing unnecessary complexity and fragility into your code.  You will help make the FileMaker world a friendlier place :>)

(See MultipleParameters.fp7 for example scripts)

ARVE Error: id and provider shortcodes attributes are mandatory for old shortcodes. It is recommended to switch to new shortcodes that need only url

 

13 responses to “Passing Multiple Parameters”

  1. Lee Smith says:

    Hi Todd

    I’ve noticed a couple of links for your demo files, including this one, are broken and I’m getting the 404 message. I tried altering the link some but couldn’t get it to work.

    The file in this case is multipleparameters.FP7

    Best wishes, Lee

  2. toddgeist says:

    Thanks Lee,

    Its Fixed now

  3. toddgeist says:

    Lee, Can you tell me what other files you couldn’t download? I looked around but everything I could find worked

    Thanks

  4. Lee Smith says:

    Hi Todd

    I posted a quick response in your live code topic, as that was the other one that I was having trouble with. Talk to you later, Lee

  5. Tom Fitch says:

    Great article, Todd — but wasn’t there a big discussion about this topic in your comments before? Is that all lost now? That’s too bad, I think there was some good info there (and not just from me 🙂 ). Or was that on a different blog?

  6. Dan Smith says:

    I think you left out the biggest downside to using this method; values cannot contain new lines.
    It may not be an issue most of the time, but if you are ever to use a field value as a parameter, it could cause your script to fail intermittently if that field was ever to contain a new line.
    You also limit the types of values that can be passed to a script. Personally, I like the flexibility that custom functions offer, and with the import custom function feature in FileMaker Pro Advanced 11 it’s now easier than it has ever been to add custom functions to a file.

    • toddgeist says:

      Hi Dan,

      Yes you can’t use raw user input as a parameter. because it might use returns in it. But how often is that the case? Not often. And even if it is you can easily protect against it with the Quote function. problem solved.

      But here is the thing that is really hard for people who have FileMaker Advanced to understand. Your code written with all of those nifty custom functions is useless to the vast majority of the people using FileMaker. They don’t have advanced, they can’t use your scripts in their own file. You might as well have been writing java to them. I know its weird, I know it doesn’t make sense, but it is nonetheless true that most people who write filemaker scripts have never used script debugger, have never seen the data viewer and have never seen a custom function.

      As I said in the article I put a very high premium on portability and share-ability. So high in fact that I only use custom functions of there is no other way. And in my opinion there are plenty of ways to pass multiple parameters without custom functions.

      Todd

  7. Hal Gumbert says:

    Cool idea Todd!

    I think that dealing with returns in Parameters and Parameter order is very important. This could be handled by adding a little overhead in the parameters and the receiving script, but not much.

    Both could be fixed by passing parameters in pairs like this:

    List(
    “$FirstName” ; Substitute ( “Todd” ; “¶” ; “Char(13)” ) ;
    “$LastName” ; Substitute ( “Geist” ; “¶” ; “Char(13)” )
    )

    Then the receiving script could simply loop thru the pairs to build the local variables and substitute the returns back in place. It would also handle an unlimited amount of parameter pairs too.

    • Alec Gregory says:

      That’s neat extension Hal, I think I’ll use the value pair approach as my default from now on. As far as I can work out, though, the substitution does the equivalent of nothing, as it’s just replacing a carriage return with a carriage return. To ensure any parameters that include carriage returns are passed intact, you could replace carriage returns with a different character such as Char ( 29 ), the group separator. This substitution could then be reversed as you suggest. Keeping with your example:

      List(
      “$FirstName” ; Substitute ( “Todd” ; “¶” ; “Char(29)” ) ;
      “$LastName” ; Substitute ( “Geist” ; “¶” ; “Char(29)” )
      )

      Then to set a given parameter in an loop (where $i is 1, 3, 5 …):

      Substitute ( GetValue ( $params ; $i + 1 ) ; Char ( 29 ) ; Char ( 13 ) )

  8. calmer says:

    Hi
    I’m very interested in your solution but unfortunately the file download link is no longer valid.
    Is there any solution to recover it please?
    Thank you!

Leave a Reply