Chapter 16. Advanced Scripting Techniques

In this chapter

What Is Advanced Scripting?

Script Parameters and Script Results

Script Variables

FileMaker Extra: Recursive Scripts

What Is Advanced Scripting?

Chapter 9, “Getting Started with Scripting,” presented an introduction to FileMaker Pro scripting techniques. It covered such topics as error trapping, linking scripts together via subscripts, conditional branching, looping scripts, and using custom dialogs. All these are essential scripting techniques that you should become familiar with.

This chapter explores several additional scripting techniques, including working with script variables, and script input/output techniques. Although we think that everyone can potentially benefit from learning these techniques, they do require a solid familiarity with general scripting techniques, calculation formulas, and the Relationships Graph. For this reason, we have opted to present these as advanced scripting techniques.

image To put these topics together with advanced layout and calculation techniques, see Chapter 18, “Advanced FileMaker Solution Architecture,” p. 517.

Script Parameters and Script Results

Beginning with FileMaker 7, FileMaker introduced features that allow you to write scripts that are more flexible and extensible than in the past. FileMaker 7 introduced script parameters, a means of passing inputs into a script. FileMaker 8 added to the picture by adding script results, the capability for a script to output a piece of data after it’s finished executing. In FileMaker 9, an enhanced script debugger and a significant redesign of the script editing interface bring it all together so that a truly powerful programming language is part of FileMaker.

The capability to move data in and out of scripts is desirable because it means that scripts can be written more abstractly and thus can be reused. By abstractly, we mean scripts written to solve general problems rather than specific ones. Using script input/output saves you time, reduces the number of scripts that are necessary in your files, and makes your scripts easier to maintain.

By abstracting the information you can create a script that, for example, goes to a layout as specified by a script parameter. Such a script can replace a multitude of other scripts such as GoToCustomerLayout, GoToGroupLayout, and so forth. If you are converting an older FileMaker solution to a current version of FileMaker, you will probably find that you can remove a lot of scripts by converting them to use parameters (parameterizing them).

That being said, the use of script input/output is completely optional. FileMaker developers did quite well for years without script parameters and script results, and we can think of no scenario in which you couldn’t still muddle through without them. Script input and output 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.

Much of what there is to say about script input/output applies equally well to script parameters (inputs) and script results (outputs). We’ll discuss script parameters first, and then delve into a consideration of script results.

Script Parameters

Before we get 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 Navigate script that navigates to a layout specified by the script parameter passed to it. Then, when setting up the buttons themselves, you would simply call the Navigate script, specifying the destination as the parameter. This approach has the advantage of requiring only 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 Navigate 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 set in several places: as part of a button definition, as an option for invoking a subscript within the Perform Script script step, or as part of the definition of a custom menu item. Figure 16.1 shows the first of these: the dialog for specifying which script should run when a button is clicked. The interface for specifying a subscript is the same; it, too, gives you a place to specify a parameter when calling a script. This is from the Email Campaign Management starter solution; note that the scripts have been grouped using the new FileMaker Pro 9 scripting interface.

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

image

At the bottom of this dialog, you have the option to specify 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, 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 completely depends on what you’re trying to accomplish. Later in this section, you’ll see some sample applications of script parameters.


Note

Only scripts triggered by buttons or called as subscripts of other scripts can have script parameters passed to them. Scripts triggered through the Script menu, by an external source (such as via Custom Web Publishing), or as startup/shutdown scripts (under File, File Options) cannot have script parameters passed to them.


Retrieving a Script Parameter

The Get(ScriptParameter) function can be used to retrieve the value of the parameter passed to a script. If no parameter was specified, 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) always returns abc. Within Child Script, Get(ScriptParameter) always returns xyz.

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

Passing Multivalued Parameters

The interface for specifying script parameters allows only a single value to be passed to a script. For many situations, that 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 Fred|123|Monkey, 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 GetValue 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:

GetValue (Get (ScriptParameter) ; 3 )

image For more on text parsing functions, see Chapter 8, “Getting Started with Calculations,” p. 249, and Chapter 15, “Advanced Calculation Techniques,” p. 433.

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 each position in the array represents. Does the value Monkey represent 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.

image For more on the Let and Evaluate functions, seeLogical Functions,” p. 434.

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’re retrieved by their name rather than by their position within the parameter.

You’ll notice that within the parameter are backslashes before all the internal quotation marks. This process, known as escaping your quotes, is necessary anytime you want to pass a string that contains internal quotes. For this technique, you need to escape the quotes surrounding any text values in your parameter; numeric values (such as the 123) do not need quotation marks and hence don’t 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 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 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 multivalent 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 16.2 shows the definition for a custom function called GetParam.

Figure 16.2. The custom function GetParam abstracts the script parameter parsing routine even more.

image

image You need FileMaker Pro 9 Advanced to create custom functions. For more on creating custom functions, seeCustom Functions,” p. 461.

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 multivalued script parameters with ease.

Passing Structured Data Elements

The final method in this discussion for passing multivalued 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 preceding section, you might specify the following as your script parameter:

"<First Name>Fred</First Name><Favorite Number>123</Favorite Number><Favorite
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 an 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:

image

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.

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 writing 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.

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), and then have the buttons or other scripts that trigger the script specify the particular value.

For example, say that 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 that 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 sample script, if you change the + 3 to + Get (ScriptParameter), you need only a single script to do the work of the seven 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 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 sample scenario, you might set up a script in the TransactionArchive file that calls a subscript in the Transaction file, passing a multivalued parameter (using one of the methods described in the preceding 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, this example 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 versions of FileMaker before version 7).

Script Results

Script results are, if you like, the flip side of script parameters. A script parameter lets you feed data into a script; a script result lets you pass data back out of a script. In the past, you might have done this by putting some data into a global field or a global variable for other scripts to look at later. But the best choice now is generally to use a script result.


Note

The reason why this is the best choice is because the script result is not stored automatically unless you choose to do so. Thus, a subscript can return a value, and the calling script can test that value and decide what to do next. If you use a global variable or global field, the value persists after you test it. In the future, you or someone else might look at the global field or variable and use its value for an unrelated purpose, possibly jeopardizing the logic of the script that relies on it.


To return a result from a script, you’ll use the Exit Script script step to specify a result to return when the script exits. Much as when specifying the value for a Set Field or Set Variable script step, you can create a calculation expression that defines the result to return.

That takes care of how to return a script result. To access the returned result, you have to use the Get(ScriptResult) function, a sort of a twin to Get(ScriptParameter). Get(ScriptResult) hands back whatever result was returned by the most recently completed script or subscript.

Let’s consider a full example. As we’ve suggested, one of the main reasons to use script input/output is to increase the reusability of your scripts. Consider a solution with a large number of reports. When allowing users to print reports, it’s common to display the report in Preview mode first, pause the script, and then, on resuming, pop up a dialog box asking whether the user wants to print the report. The task of prompting the user for print confirmation might happen over and over again in a report-intensive solution. Using script results, you can write a single script to query the user, and then return the user’s choice as a script result. Here’s what such a script might look like:

image

Notice the difference in the Exit Script step. As part of this step, the script specifies that a calculated result be returned from the script. The calculation looks at the numeric result of the dialog box choice, converts it into text using the Choose function, and returns the corresponding text result.

To use this script’s modular functionality, another script has to call it. A script to display and optionally print a single report might look like this:

image

This script performs all the usual sort of management common to previewing reports: navigating to a layout, sorting the records in some way, entering Preview mode, pausing for the user to look over the report. When the user resumes the script, though, the script goes straight into the confirmation subscript. Thereafter, the outer script uses Get(ScriptResult) to determine the result of the confirmation dialog, and prints the displayed report, or not, accordingly.

With such a script, instead of having a dozen print dialogs coded all over your system, you now have just one. If a user reports a problem with the print dialog, you now know where to start looking. And any changes or improvements made to the print confirmation process immediately benefit all reports that use this functionality.

Final Thoughts on Script Input/Output

The script input and output capabilities of FileMaker Pro represent a major advance in the capability to construct streamlined, reusable routines within a FileMaker solution. Mastering the use of these techniques is critical to getting the most out of FileMaker Pro. We recommend that you study these features carefully, and that you aggressively look for opportunities to use them. Anytime a script does similar work with different input values, consider using script parameters. Anytime a script might be better structured as a tool that does some work and then reports on the results, consider reporting those results via a script result. Your solutions will become cleaner, simpler, and more elegant.

Script Variables

If you’ve worked with other languages or development environments, you’re familiar with a variable as a type of named, temporary storage. For example, in the PHP programming language, you might write this:

image

Here $x, $y, and $z are all variables—temporary storage elements to which values are then assigned (the $ in PHP indicates that these are variable names, and FileMaker uses a similar convention for variable names). They contrast with the permanent storage of fields in databases. In later expressions, the variable names stand in for the values stored in them. So, you’d expect that when the preceding program runs, the variable $z will end up storing a value of 16.

Often, as you build up a program or routine, you’ll find yourself wanting to rely on named, temporary storage elements like these. In previous versions of FileMaker, the only place to cache such data has been within FileMaker’s database structures, by putting the data into one or another kind of field.

Consider the simplistic example of a script that beeps 10 times in succession. Previously, you might have defined a field with global storage to act as a counter, and written the script like this:

image

This has always worked fine, but it has some drawbacks:

  • Even though the counter field is used only in this script, it has to be defined within the field definitions for the table as a whole. It will always be there, cluttering up the list, even though it might apply to only a single script.
  • The storage is not as temporary as you would like. The field gCounter goes on holding its value and being accessible after the script completes. This is one reason it’s necessary to reset the field to 1 at the start of the script. If the script has run previously, it might still have its old value of 11, or it might have some other value altogether if someone edited the field directly and stored it in the database.

Note

If you are working with a FileMaker database that has its roots in the past, you might encounter a number of global fields. Converting them to variables is a routine part of conversion to the current versions of FileMaker; it can make the databases smaller and the scripts simpler and most robust. One of the great recommendations of variables is that they are temporary, so they cannot hang around to take up storage and confuse future developers who work on the database.


About Local Variables

A local variable is one that exists and has meaning only within a single script: exactly what you want for the loop counting example shown previously. If you were to rewrite the looping script using script variables, it might look like this:

image

Local variables are named using a single dollar sign ($), and they’re created and manipulated using the Set Variable script step. Figure 16.3 shows the options for the Set Variable script step.

Figure 16.3. The capability to set variables is a powerful feature in FileMaker Pro.

image

You’ll notice that the Set Variable script step allows you to set the variable’s value dynamically, using the Specify option. This means that a variable can be used to hold the results of any expression you can define using FileMaker’s Calculation dialog. You could store the current username, the current date, or the results of an expression such as $counter + 1. You’ll note also, by the way, that variables can be referenced from within such calculations just by using the variable name. For example, the following are perfectly valid calculation expressions:

image

If a variable of the specified name is not currently defined, a reference to the variable returns an empty string (or a null result, if that term is more familiar). The first expression of the preceding two would give a result of 1, whereas the second would give a result of "Name: " if the respective variables were not defined.

About Variable Scope

Variable scope is the area in which a variable has meaning and can be accessed. Variables in FileMaker have one of two kinds of scope: either local scope or global scope.

So far, the variables we’ve examined have local scope. It’s most common to refer to them as local variables. A local variable exists and has meaning only within the context of a single script. Consider the example of the $counter variable discussed previously. This variable exists only within the script in which it’s defined and manipulated. After the script completes, the $counter variable is undefined and cannot be accessed. Likewise, if you called a subscript from within that script, the subscript would not have access to the value of $counter contained in the parent script.

Because local variables exist only within the context of a single script, this can lead to subtle confusion. Consider a parent script that uses a $counter variable that then also calls a subscript. If you were to try to access the value of $counter within the subscript, you’d get a null value because you’d be trying to access a variable that had never been set within the context of the subscript. And if you were to try to set the value of $counter within the subscript by using the Set Variable script step, this would create a new variable, local to the subscript, with the same name, $counter. There would consequently be a total of two $counter variables: one local to the parent script, one local to the subscript. The two exist simultaneously and independently; they don’t conflict, and they don’t affect one another.

Local Variables Summary

So, to summarize what has been said about local variables in FileMaker 8:

  • Local variables are set using the Set Variable script step.
  • Local variables must have names beginning with $.
  • Local variables can be referenced within calculation expressions.
  • Local variables are limited in scope to the script in which they are defined (via the Set Variable script step). Neither any subscripts nor any parent scripts can access the value of a local variable.
  • Local variables do not appear in the Define Database dialog.

About Global Variables

Global variables, denoted with a double dollar sign ($$userName, $$currentLayout) share many features with local variables. The only difference is in their scope. Whereas local variables are limited in scope to a single script, global variables retain their value no matter what script is running or whether a script is running at all. They can store values that persist across any or all scripts for the duration of a user’s session.

The last point bears repeating. Whereas local variables have script scope, meaning that they are limited in scope to a single script, global variables have file/session scope. Like globally stored fields, global variables are unique to an individual user: Each user has his own copy of a global variable, so the variable $$userName can have a different value for each active user. In addition, global variables cease to exist when a user session ends. If you work with a global variable, quit FileMaker, and then open the same file again, the global variable will disappear, until some logic in the files creates it again.

Global variables also have scope only within a single file. There is no way to “reach across” to pull a global variable’s data from one file into another. Such a thing is, by contrast, possible with globally stored fields. Global variables from other files cannot be accessed via relationships because they don’t appear in the field list.

So, what good are global variables? When does it make sense to use them? We recommend that, by and large, you use global variables for user session data: data specific to one user that is intended to persist for just that user session. Examples include things such as the name of the currently logged-in user, user preferences such as a user’s chosen default layout, or any other user-specific data you might be storing, such as a user’s department or sales region—particularly when this information is not available from a database.

Global variables cannot completely obviate the need for globally stored fields. Globally stored fields have several capabilities not shared by global variables:

  • Globally stored fields can be accessed across files by using relationships.
  • Globally stored fields can accept user input.
  • Globally stored fields can be used to drive relationships.
  • Globally stored fields can be used to store the content of an input field from a custom dialog.

For example, if you were implementing a filtered portal (a portal whose contents change in response to user input), you would have to use a globally stored field to do so, both because you would need to capture user input and because you would need to use that input to drive the portal relationship.

image For more on filtered portals, seeFiltered Portals,” p. 505.

Other Ways to Work with Variables

When you’re first starting out with variables, we recommend you try to stick to the following precepts until you feel you’ve mastered the basics:

  • Use local variables for temporary storage used within the context of a single script.
  • Use global variables to store user-specific session data (with the exceptions noted in the next point).
  • Use globally stored fields, not variables, to store user-specific session data that must be captured directly from the user, must drive a relationship, or must be shared heavily across files.

Now that we’ve said all that, if you have mastered the basic concepts of variables, there are some advanced points to be made about them.

About Dynamic File Paths

There’s another nice feature of variables in FileMaker Pro that’s very much worth mentioning. Certain script steps, such as Export Records, as well as the new Save Records as Excel/PDF script step, allow you to specify the location of an output file by typing in a file reference. In FileMaker Pro, that file reference can be taken from a variable, rather than being hard-coded.

If the usefulness of that isn’t obvious, let it sink in for a moment. In the past, it hasn’t been possible to create names for exported files on the fly: You either had to let the user enter a filename, or had to hard-code a single specific filename into the script step. If you wanted to name exported or saved files dynamically (say you wanted to include the current date in the filename), you were out of luck, unless you chose to use a third-party plug-in.

To save files to a dynamically specified file path, you’ll need to create that file path in your script and put it into a variable. (The path begins with the user’s desktop, so that is where the file is placed.) That variable can then be used in specifying a file path, as the following script example illustrates:

image

Viewing Your Variables

One final note on variables in FileMaker Pro. We’ve made the point a few times that variables are beneficial in that they don’t add clutter to the database schema: They don’t appear in Define Database dialog, nor in the field lists that go along with operations such as Sort or Import Records. There’s a disadvantage to this as well: There’s currently no way to see a list of all the variables currently active in a FileMaker solution.

It is possible to view the values of individual variables in the FileMaker Pro Advanced Data Viewer, but you must enter the variable names one at a time, as with any other expression.

FileMaker Extra: Recursive Scripts

Chapter 15, “Advanced Calculation Techniques,” discusses how you could make custom functions recursive by including calls to themselves within their formulas. In a similar manner, you can use script parameters to create recursive scripts. Although this isn’t something you need to do on a daily basis, there are some interesting applications for recursive scripts.

A recursive script is one that calls itself repeatedly until some exit condition is satisfied. Each time the script calls itself as a subscript, it passes a script parameter that can be used as part of an exit condition test. In many ways, recursive scripts are quite similar to looping scripts, and many tasks you can accomplish with one can be done as easily by the other. As an example of a recursive script, consider this Recursive Add script:

image

This script adds 100 new records to the current table. It’s first called without a script parameter, so the first time through, the script calls itself as a subscript, passing a parameter of 1. The parameter increments each subsequent time through until eventually the exit criteria (Get (ScriptParameter) >= 100) is met.

If there are any steps in the script after the recursive subscript call, these are all executed, from the inside, out, after the exit criteria has been met. Try to predict what would happen if you added the following steps to the end of the preceding script:

Beep
Show Custom Dialog ["The parameter is:" ; Get (ScriptParameter)]

The 100 records would be created exactly as they were originally. But after they were all created, you’d hear a beep and see a message telling you that the script parameter value is 99. After clicking OK, you’d then hear another beep and a message telling you that the parameter is 98. This would continue for some time, and eventually the last message you’d see would be that the parameter is empty, which, of course, was the condition on the very first trip through the script.

As a final example of recursive scripting, consider the following script, which flags duplicates among a set of records. Assume that the set contains a list of names, which has been sorted by name before this script is called:

image

During each iteration through the script, the current record’s name is compared against the value of the script parameter, which was set to the value of the previous record’s name. The exit condition here is the Exit after last option on the fourth line; the script continues through the set of records, stopping only when there’s no next record to go to.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.17.18