Script Parameters

 <  Day Day Up  >  

graphics/new_icon.jpg

Script parameters, new to FileMaker Pro 7, are a mechanism for passing inputs into scripts. This is desirable because it means that scripts can be written more abstractly and thus can be reused. By "abstractly," we mean that scripts are written to solve general problems rather than specific ones. Using script parameters saves you time, reduces the number of scripts that are necessary in your files, and makes your scripts easier to maintain.


That being said, the use of script parameters is completely optional. FileMaker developers did quite well for years without them, and there's no scenario we can think of where you couldn't still muddle through without them. Script parameters represent a considerable advance for FileMaker Pro scripting; the extent to which you want to take advantage of that depends on the needs of your users and the scope of your files.

Before getting into the details of how and why to use script parameters, a short example will give you a concrete sense of what script parameters are all about and why you want to learn this. Imagine that you want to create several navigation buttons that take users to a specified layout. One way to do this is to create a separate script that's hard-coded to go to a particular destination. You'd need as many scripts as you have destination layouts, and every time you wanted to add a new destination, you'd create a new script.

Another way to accomplish this task is to create a generic "Go to" script that navigates to a layout specified by the script parameter that was passed to it. Then, when setting up the buttons themselves , you would simply call the "Go to" script, specifying the destination as the parameter. This approach has the advantage of requiring but a single script. To add another destination in the future, you simply specify the new destination as the parameter. There is no need to add a new script or to edit the original "Go to" script.

It's clear from this example that extracting hard-coded values from a script and placing them instead into script parameters has a tangible benefit. Keep this example in mind as you read further about script parameters.

Specifying Script Parameters

Script parameters can be defined in two places: either as part of a button definition or as an option for invoking a subscript within the Perform Script script step. Figure 15.1 shows the first of these: the dialog for specifying what script should run when a button is clicked. The dialog for specifying a subscript is exactly the same.

Figure 15.1. When attaching a script to a button, you can also specify an optional script parameter, which is passed into the script.

graphics/15fig01.gif


At the bottom of this dialog, you have the option of specifying a script parameter. The parameter can be some text string you type into the space provided, or you can enter a calculation formula as the parameter. Clicking the Edit button brings up a standard calculation formula dialog box. If you use a calculation formula as your script parameter, then when the button (or subscript) is triggered, the formula is evaluated, and the results are used as the parameter.

The actual string or formula you use as your parameter depends completely on what you're trying to accomplish. Later in this section, you'll see some example applications of script parameters.

NOTE

Only scripts that are triggered by buttons or that are called as subscripts of other scripts can have script parameters passed to them. Scripts that are triggered through the S cript menu, by an external source (such as via Custom Web Publishing), or as startup/shutdown scripts (under F ile, F ile O ptions) cannot have script parameters passed to them.


Retrieving a Script Parameter

The Get(ScriptParameter) function can be used to retrieve the value of the script parameter passed to a script. If no parameter was specified, then this function simply returns an empty string. The value of the script parameter can be accessed anywhere from within the script in this way. It can't be changed or altered in any way, and it " expires " as soon as the script is complete.

Any subscripts called by a script can have their own independent script parameters ”they do not "inherit" the parameter of the script that calls them. As an example, say that the string abc was designated as the parameter to be passed to a script called Main Script . Assume further that Main Script called a subscript called Child Script as its second step, and that the parameter xyz was specified as part of the Perform Script step. Within Main Script , Get(ScriptParameter) will always return abc . Within Child Script , Get(ScriptParameter) will always return xyz .

The parameter passed to a script can be the result of a calculation, so by using Get(ScriptParameter) as the parameter, you can pass a script's parameter down to the subscripts it calls, as shown in Figure 15.2.

Figure 15.2. If you want a subscript to "inherit" a parameter, set the parameter to Get(Script Parameter) .

graphics/15fig02.gif


Passing Multi-valued Parameters

The interface for specifying script parameters allows for only a single value to be passed to a script. For many situations, this is sufficient to achieve the desired outcome. Other times, however, you will find that you want to be able to pass multiple parameters to a script. Although this isn't directly possible, there are several methods to achieve such a result.

Parsing a Text Array

The simplest way to pass multiple values in a script parameter is to specify a delimited array as the script parameter. For instance, if you wanted to send a parameter that contained the values Fred , 123 , and Monkey , you could send the string Fred123Monkey , or even Fred 123 Monkey .

NOTE

The delimiter you use (here we've used pipe characters and carriage returns) is up to you; just choose something that you know won't be found in the data you're passing.


To retrieve a portion of the passed parameter, use the built-in text parsing functions of FileMaker Pro. If you've used carriage returns as your array delimiter, the MiddleValues function is the easiest way to extract a particular value. Say that you want to grab the third value ( Monkey ). From within your script, anytime you wanted access to this value, you would use the following formula:

 

 Substitute (MiddleValues (Get (ScriptParameter) ; 3 ; 1), "", "") 

For more on text parsing functions, see Chapter 8, "Getting Started with Calculations," p. 213 , Chapter 14, "Specialized Calculation Functions," p. 381 , and Appendix B, "Calculation Function Reference," p. 807 .


NOTE

The Substitute function is necessary because the output of the MiddleValues function always contains a carriage return at the end of it.


For more on the MiddleValues function, see "Array Functions," p. 403 .


The nice thing about using delimited lists to pass multiple values is that you can set them up very easily. Even if some of the values are derived as calculated results, it's still quite easy to set up a formula that concatenates all the appropriate pieces together. For instance, if you wanted to pass the current layout name and the current time as the two values of your script parameter, you would use the following formula:

 

 Get (LayoutName) & "" & Get (CurrentTime) 

The main drawback of this method is that the burden is on you, the developer, to know what the values in the array represent. Is "Monkey" a favorite animal, a password, or a Halloween costume? There's nothing in the parameter itself that offers any assistance. This can (and should!) be clarified with script and/or calculation comments.

Using the Let Function

Another method for passing multiple values in a script parameter involves the Let and Evaluate functions. If you have a good understanding of those functions, you'll likely appreciate the elegance of this technique.

For more on the Let and Evaluate functions, see "Logical Functions," p. 382 .


Imagine that you pass as your script parameter the following string:

 

 "First Name = \"Fred\"; Favorite Number = 123 ; Favorite Animal = \"Monkey\"" 

What you have here is a set of name/value pairs, separated by semicolons. Immediately you can see one of the benefits of this method over the previous one: When you pass both names and values, the parameter becomes more meaningful. In six months when you need to troubleshoot or enhance your script, you won't have to rack your brain to remember what the elements in your parameter represent. Another benefit of this method is that the order of the values doesn't matter. They'll be retrieved by name rather than by their position within the parameter.

You'll notice that within the parameter, there are back slashes before all the internal quotation marks. This process, known as escaping your quotes, is necessary any time you want to pass a string that contains internal quotes. For this technique, you need to escape any text values in your parameter; numeric values (such as the 123) do not need to be escaped.

You might recognize that the parameter specified previously is structured similarly to the first parameter of a Let function. This isn't a coincidence . Recall that the Let function allows you to set variables within a calculation formula. Imagine you had the following formula:

 

 Let ([First Name = "Fred"; Favorite Number = 123 ; Favorite Animal = "Monkey"] ; Favorite Animal) 

This formula sets three local variables ( First Name , Favorite Number , and Favorite Animal ) and then returns the value of the Favorite Animal variable. It would, in fact, return Monkey .

By combining the Let and Evaluate functions, you can build a formula that pulls out a named value from within a script parameter. The Evaluate function executes a dynamically constructed calculation formula. Therefore, within your script, anytime you want to retrieve the value of the Favorite Animal , you would use the following formula:

 

 Evaluate ("Let ([" & Get(ScriptParameter)  & "]; Favorite Animal)") 

As you can see, a string containing a Let function is dynamically assembled from the value of the script parameter. The Evaluate function is then used to execute it. To return one of the other variables within the script parameter, you would simply need to change the end of the formula to reference the proper variable name.

If you foresee a need to do much parsing of multi-value script parameters, you should consider creating a custom function to simplify the process even more. That way, you won't have to remember the syntax for the Let and Evaluate functions every time you need to retrieve a parameter value. Figure 15.3 shows the definition for a custom function called GetParam .

Figure 15.3. The custom function GetParam abstracts the script parameter parsing routine even more.
graphics/15fig03.jpg

For more on creating custom functions, see "Custom Functions," p. 409 .


The GetParam function takes a single argument, paramName . The formula for the function is the same as the Evaluate formula shown previously, but with the paramName inserted in the place of the hard-coded parameter name:

 

 Evaluate ("Let ([" & Get(ScriptParameter)  & "]; " & paramName & ")") 

Now, within your script, to retrieve the value of the Favorite Animal , you just need the following formula:

 

 GetParam ("Favorite Animal") 

This final abstraction provided by the GetParam custom function certainly makes the parameter parsing more convenient . After it's in place, you can pass and retrieve multi-valued script parameters with ease.

Passing Structured Data Elements

The final method in this discussion for passing multi-valued script parameters involves creating your own structured data elements. It's really a hybrid of the other two methods, in that it requires standard text parsing to retrieve an element (like the first method), but the elements are meaningfully named (as in the second method).

The syntax you create for naming elements is up to you. We generally prefer an XML-like structure because it's easy to use and organize. For instance, to pass the same three values discussed in the previous section, you might specify the following as your script parameter:

 

 "<First Name>Fred</First Name><Favorite Number>123</Favorite Number><Favorite graphics/ccc.gif Animal>Monkey</Favorite Animal>" 

This is, of course, simply another way of specifying element names and values. But you don't need to worry about escaping any quotes, as you do with a string that will be used in a Evaluate statement. To retrieve the value of a particular element of the script parameter, you would need to use standard text parsing functions. This is best accomplished with the creation of a custom function; you then need to write the parsing logic just once. The following formula could be used as the definition for such a custom function; the function's only parameter is paramName :

 

 Let ([     openElement = "<" & paramName & ">";     closeElement = "</" & paramName & ">" ;     startPos = Position (Get(ScriptParameter) ; openElement ; 1; 1) + Length (openElement);     endPos = Position (Get (ScriptParameter) ; closeElement ; 1; 1)] ; Middle (Get(ScriptParameter) ; startPos ; endPos - startPos)) 

If this function were called GetParamXML , the value of one of the script parameter elements could then be retrieved with the function GetParamXML("First Name") . The custom function is hard-coded to parse out a value from a script parameter.

TIP

You could easily turn this into a more generic XML parsing tool by passing a text string in which to search as another parameter.


Strategies for Using Script Parameters

Using script parameters can greatly reduce the number of scripts in a file and can make your database much easier to maintain. You should consider using script parameters in several common programming scenarios.

Modularizing Scripts

The first ”and most important ”reason for using script parameters is to add a layer of abstraction to your scripts, thereby making them more modular and reusable. Rather than write scads of single-purpose scripts, if you can generalize your scripts by using script parameters, you will need fewer scripts and your solution will be easier to maintain.

Practical Script Parameter Examples

Elsewhere in this book are several examples of script parameters being used to modularize scripts. For instance, in Chapter 10, "Reporting with Grouped Data," one of the reporting techniques involved turning the column headings on a list view into buttons that would sort by the values in that column. All the buttons called a single script, passing in a different script parameter. Without script parameters, that routine would have required separate scripts for each column, each with a single hard-coded sort specification. Not only would that take longer to set up, but if the behavior ever needed to be modified, changes would need to be made to multiple scripts rather than a single, abstract script.

Script parameters were also central to the navigation routine described in Chapter 13, "Advanced Layout Techniques." There, a generalized navigation script was passed a destination layout as a script parameter.


You will know if you have encountered a situation that can potentially be simplified and strengthened by using script parameters if you find yourself writing several scripts that do basically the same thing, differing only in some specific value. In place of that specific value, use Get (ScriptParameter) , then have the buttons or other scripts that trigger the script specify the particular value.

For instance, say you've developed a system that contains a calendar, and that one of your layouts shows all the scheduled appointments for a given week. You'd like to be able to place a button above each of the seven days of the week (Sunday through Saturday) that users can click when they want to create a new appointment on that particular day. Assume you have a field that contains the date of the Sunday of the week. Therefore, a script that would create a new appointment on Wednesday would do something like the following:

 

 New Record/Request Set Field [Appointments::AppointmentDate ; SundayDate + 3] 

The scripts for creating appointments on the other days of the week would differ from what's shown in the preceding formula only by the constant that's added to the SundayDate .

You could therefore write seven scripts, link them to your buttons, and move on to your next task.

We hope you can already see how and why script parameters can be used here. In the example script, if you change the + 3 to + Get (ScriptParameter) , then you need only a single script to do the work of the seven that would be required without script parameters. Each of the seven buttons calls the generic version of this Add Appointment script, passing as a parameter an integer from 0 to 6 to differentiate them from each other. By using this method, you've replaced seven hard-coded scripts with a single generalized one.

Passing Data Between Files

Another situation in which script parameters can be beneficial is for passing data between files. Using script parameters for this purpose saves you from needing to create extra fields and relationships in your files.

As an example, imagine that you have a file called Transactions and another called TransactionArchive (each with a single table with the same name as the file). You periodically archive old transactions into the archive file, but occasionally you have a need to pull a record back from the archive into the main production file. Further, you'd like to avoid placing a table occurrence from the archive file in the main file because the two need to be able to function independently.

Because you can call scripts in another file without having a relationship to that file, script parameters make an ideal transfer mechanism for moving data between unrelated files. In the example scenario, you might set up a script in the TransactionArchive file that calls a subscript in the Transaction file, passing a multi-valued parameter (using one of the methods described in the previous section) that contains the pertinent data elements from the transaction. In the Transaction file, then, your subscript would create a new record and populate it, using the parsed-out parameter data.

In this example, importing the record from one file to the other would have been another solution within the defined constraints. Nonetheless, it still clearly demonstrates the role that script parameters can play in moving data around. It's certainly preferable to copying and pasting data, or even parking data in global fields for later retrieval (both of which were common techniques with previous versions of FileMaker).

Protecting Subscripts

A final strategy for using script parameters is as a means of protecting subscripts from inadvertently being called improperly. Imagine that you have a pair of scripts, Script A and Script B, and that Script B is called as a subscript from Script A. As it stands, nothing would prevent another script from calling Script B, or even from Script B being called directly. In some cases, there may be undesirable consequences that can occur if subscripts are called directly.

To "protect" Script B, and ensure that it's called only as a subscript of Script A, you can pass a script parameter that "authorizes" Script B to run. It really doesn't matter what value you pass. You can check at the beginning of Script B to see whether the script parameter is set correctly. If it isn't, exit the script or show a warning dialog to the user .

CAUTION

Of course, any user who has access to the scripts in question can discover what parameter Script B expects, so this method isn't intended to be used as a security measure. It merely protects against accidental execution of subscripts (and also direct invocation from the Web).


 <  Day Day Up  >  


QUE CORPORATION - Using Filemaker pro X
QUE CORPORATION - Using Filemaker pro X
ISBN: N/A
EAN: N/A
Year: 2003
Pages: 494

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net