Creating Scripts
Creating and editing scripts in FileMaker is fairly straightforward. Simply choose Scripts, ScriptMaker and the Define Scripts dialog opens. You can also use the keyboard shortcut (one of our favorite features added in FileMaker 7) of (
After you're in ScriptMaker, you'll see a list of existing scripts and can manage all the scripts in your file (you can delete, reorder, and so on). From there you can delve into a single script and edit its individual script steps.
Writing an actual script requires first that you have a goal in mindwhat purpose is the script intended to accomplish? A script will step through a series of instructions, one at a time, until the script either reaches its last instruction or reaches some exit condition. Exit conditions can vary, and many of their implementations are covered in this chapter.
Here's an example of the logical outline of a script you might use to take users to a Main Menu layout after they log in. Presumably this script would be set to run when a file is first opened by an individual user. Assume that someone named Kim has just logged in.
After valid login, carry out these steps:
- In a table of users, set the LastLoginDate field in Kim's record to today's date.
- Set the gUserNameDisplay field to "Kim".
- Set the gUserMessage field to "Welcome back, Kim".
- Perform Go to Layout: Main_Menu.
This simple four-step process takes care of some background tasks first, and then from a user's standpoint navigates to the main menu on which, presumably, a welcome message sits. All the user would see is that the system landed him on the Main Menu layout.
To implement a script like this, a developer would open ScriptMaker, create a new script, give it a name, and then use the Edit Script dialog to insert various steps into the script. The actual script that would manage the preceding logic could look like this:
Go to Layout [ "zdev_GlobalAdmin" (Globals) ] Set Field [ Globals::gAccountName; Get (AccountName) ] Set Field [ Current_User::LastLoginDate; Get (CurrentDate) ] Set Field [ Globals::gUserNameDisplay; Current_User::Name_First ] Set Field [ Globals::gUserMessage; "Welcome Back, " & Globals::gUserNameDisplay & "." ] Go to Layout [ "Main Menu" (Globals) ]
There are a number of ideas contained in the preceding example that we'll detail in the forthcoming pages. The important thing in this case is to become more familiar with reading a script and following its logic.
This script first goes to a layout called zdev_GlobalAdmin. It then posts information into four fields. One of these steps draws data from a related field in a Current_User table occurrence, and another sets information in that related record. The script then last navigates again to a Main Menu layout. This conforms to the flow we mapped out previously; you might think of the original four pseudocode steps as an outline for the finished script.
The ScriptMaker Interface
The Define Scripts dialog (see Figure 9.1) allows you to manage all the scripts in your current file. To reorder scripts, simply drag individual scripts up or down along the list. Unfortunately, there's no means of sorting scripts, so you need to do your best to stay organized. We generally advocate keeping scripts either grouped by function (for example, all your Invoicing scripts in a group) or organized alphabetically.
Figure 9.1. The Define Scripts dialog box allows you to create, edit, and organize your scripts, and decide which ones to display in FileMaker's Script menu.
Tip
Use (
You can perform various actions in the Define Scripts dialog box as outlined in the following list:
- You can create new scripts, edit existing scripts, or delete those you no longer need.
- By selecting a given script and clicking Perform, you can execute scripts directly from this dialog. Using this button to initiate scripts saves you the extra step of having to close the dialog and launch them from within your database.
You can now copy and paste scripts and script steps, using FileMaker Pro 8 Advanced; note that this works perfectly well across different files. You are likely to find yourself writing scripts that are similar to those you've written before, or needing to migrate from an older file into a newer. Luckily, you need not reassemble all your scripts by hand. In this latest version of FileMaker, copied scripts match field, relationship, layout, and other references by name. It's a good idea to look at any script steps that refer to fields, layouts, subscripts, related records, or anything that is layout-driven and assumes that the object in question is on a given layout to be sure that they function correctly after they are copied into a new file. Tip
If you use FileMaker Pro 8 Advanced, one of the easiest ways to confirm that a script has imported or copied well is to run it the first time with the Script Debugger turned on.
- You can use the Print button to print a script. Printing a script is a good way to create documentationespecially in combination with Adobe Acrobat's capability to create PDFsor spot problems more easily.
- You can import scripts in batches from one file to another. This feature works similarly to copying scripts. For FileMaker Pro 8 users (not Advanced), this is your only option for moving scripts from file to file.
- The Edit button opens the Edit Script dialog for any selected script. A much faster way to work is to simply double-click the script you want to edit.
- The Duplicate button can be used to duplicate a script so that you need not start from scratch when writing a new script. We recommend creating a script template and duplicating it to begin new scripts.
For an example of the script template that the authors use in their consulting practice, see Chapter 27, "Documenting your FileMaker Solutions," p. 841.
- The check-box column along the left of the dialog controls whether a given script appears in FileMaker's standard Script menu. If you hide a script by unchecking its check box, you need to provide the user with another means of performing, or executing, the script. Typically this entails either associating the script with one or more button objects that appear on various layouts or tying the script to a custom menu item.
Note also that just as in other areas of FileMaker, a single hyphen becomes a menu divider. If you create a script named -, you insert a divider in your list. This is useful in organizing your scripts visually. Plan to have a good many scripts; it is a good idea to keep them well organized.
Tip
Notice that by using (
Script Naming Practices
Keeping your scripts well organized and following good script naming practices is even more important in FileMaker 7 and 8. Versions of FileMaker Pro prior to 7 generally involved more individual files than today, and hence scripts tended to be naturally distributed throughout a given system. In a system in which one file can contain many tables, all your scripts may very well live in a single file.
Note
FileMaker 8's capability to store many tables in one file has many implications, but in particular with scripts, you won't be constantly closing and reopening ScriptMaker in different files as you would have with FileMaker 6 or earlier. Fewer scripts are also required in many cases: Many operations that would have required executing a series of external subscripts across several files can now be accomplished by a single script in FileMaker 8.
Script naming practices vary quite widely from developer to developer; even the authors of this book find it difficult to agree to a common standard. It's less important that you follow any particular naming convention than that you use a logical and consistent system. We do, nonetheless, recommend you consider some of the following ideas:
- Use hyphens, underscores, and so on to divide your scripts into logical groupings. As in other areas of FileMaker Pro, a single hyphen displays as a menu separator in the Scripts menu.
- Don't show all your scripts to your users. Choose deliberately which scripts you want to make available to users in the Scripts menu. Note that FileMaker Pro 8 Advanced allows developers to create custom menu sets. Quite often you may want to have a menu item run a certain script. You may want to use custom menus to hide the regular Scripts menu altogether, and attach your scripts to other menu items throughout other menus.
To learn about how to implement custom menus in a solution, see Chapter 13, "Advanced Interface Techniques," p. 353.
- Think of adding headers as shown previously in Figure 9.1. Organize your scripts into groups and then label them accordingly.
- When using subscripts that are exclusively subordinate to another "main" script, you might consider indenting the names of the subscripts with underscores or using a prefix naming style to indicate that a set of scripts is to be used as a unit.
- Scripts are often intended to operate on a specific table occurrence (for example, if you're using a script to control the creation of a new customer record, you want to make sure that a new record gets created in the Customer table, not the Product table). It's a good idea to use short table prefixes or suffixes when a script applies to only a given table, and "all" when it doesn'tfor example, New_Record_contact_to, Report_invoices_to, or Resize_Window_all.
- If you plan to use Custom Web Publishing, we encourage you to avoid spaces and special characters in your script names. They're a pain to parse if you plan to call these scripts from the Web. (Clearly those scripts you allow to be displayed in the Scripts menu need to follow user-friendly naming conventions.)
Script Editing
After you create a new script in ScriptMaker, or edit an existing script, the Edit Script dialog opens (see Figure 9.2). Here you construct the actual script by inserting script commands from the list on the left into the window on the right. Nearly every script step has additional options you need to specify, such as the name of a layout to go to, or the name of a file from which to import. These options appear under your script when you highlight a given step in it.
Figure 9.2. The Edit Script dialog presents you with additional dialogs as needed to configure settings for specific steps in your script.
Tip
You can (
To reorder script steps, simply drag them by the two-headed arrow icon located to the left of the step.
In FileMaker Pro 8 Advanced you can copy and paste script steps (and the same Shift-click and Ctrl-click behaviors apply as elsewhere). This works perfectly well from script to script and from file to file. This is also an alternative way to reorder script steps in a large script. |
If Indicate Web Compatibility is enabled, script steps that are incompatible with web publishing display in gray.
As an example, Go to Layout is a common step you'll use quite often. Notice that when you insert it into a script, a menu appears in the Script Step Options area at the lower right, from which you can choose an existing layout, the layout on which the script began, or one determined by calculation.
Full Access Privileges
Notice the Run Script with Full Access Privileges check box at the bottom of the Edit Script dialog. Designating that a script run with full access privileges means simply that for the duration of that script, FileMaker will override all security restrictions. When this option is not enabled, scripts run subordinate to whatever privilege set the currently signed-in user has. For instance, if a script makes a call to delete a record and the user who is running that script cannot do so based on his current security privileges, the script usually presents an alert message to the user and ignores that step of the script. The rest of the script is still performed.
Note that when this option is checked, the security privilege set for the current user actually does change for the duration of the script: If you use the calculation function Get ( PrivilegeSetName ), it will return [Full Access] as long as the script is running. If your script contains logic in which you need to check a user's assigned privilege set, you'll need to capture the user's privilege set information elsewhere before running the script and refer to it however you've stored or captured the information.
Error management in scripts is an important element in all scripting. For more detail, see "Set Error Capture," p. 257. |
To understand FileMaker security and privilege sets, see Chapter 12, "Implementing Security," p. 325. |
Commenting Scripts
Keeping track of what scripts do is a difficult task. What seemed perfectly intuitive at the time you wrote a given script may become hopelessly obscure a few weeksor sometimes even hourslater. Although developers vary in how they use comments, nearly all developers recognize the value of commenting their work.
Remember that you're not coding in a vacuum. We can virtually guarantee that although you may never intend that a given database be seen by someone else's eyes, if it stands the tests of time and proves useful, at some point you'll crack it open with the infamous words, "Let me show you how I did this...." Likewise, professional-grade systems are nearly all collaborative efforts. Comments exist to help your peers understand what your caffeine-sodden brain was thinking at the time you wrote a particular routine.
A simple example of a commented script is seen in Listing 9.1. Notice that in FileMaker Pro comments are prefixed by the # symbol.
Listing 9.1. Script with Comments
[View full width]
# Purpose: initiate the running of a report while allowing users
# to choose what sort order they want
# History: sl 2004 02 04; bb 2004 02 05
# Dependencies: Invoices: Monthly Report layout
#
# prompt user for sort order
Show Custom Dialog [ Title: "Sort Order"; Message: "Do you want to sort by amount or
|
Using a Script Template
It is often helpful to create a template script that you can duplicate when you need to create a new script. In our templates, we include several comment lines at the top where we record information about the purpose and revision history of the script. A template script looks something like this:
# purpose: TYPEHERE # dependencies: TYPEHERE # history: XXX DATE # # set error handling Allow User Abort [ Off ] Set Error Capture [ On ] # # establish context Go to Layout [ Original Layout ] # #
Although it is simple, this template does save time and promote good code. If you don't need a particular piece of it, it's easy enough to delete.
Adding the Go to Layout step to your template can help ensure that the script begins on the correct layout and thus is associated with the proper base table attached to that layout. Including this step in the template prompts developers to make a conscious decision and reminds you that context needs to be managed.
Using Subscripts
One of the most useful things in ScriptMaker is the Perform Script step itself. One FileMaker script can call another script, which is then commonly known as a subscript. This then allows you to divide scripts into smaller logical blocks and also break out discrete scripts for anything you are likely to want to use again. This degree of abstraction in your system is one that we very much recommend. Abstraction makes scripts easier to read, easier to debug, and modularin that a subscript may be generic and used in a variety of scripts.
Here's an example:
[View full width]
Sales_Report # purpose: to run the Sales Report, weekly or monthly # history: scl 2-5-2004 # Perform Script [ "CheckPermission_forSales" ] Perform Script [ "Find_CurrentSales" ] # Show Custom Dialog [ Title: "Run Report"; Message: "Would you like this report broken out
Notice that the script actually doesn't do much on its own. It will first run a permission check script, and then run another script to establish a found set. It then prompts the user to make a choice and runs one of two report subscripts based on what choice the user makes. This approach is quite common and demonstrates a flexible approach to programming. The Find_CurrentSales subscript could well be used elsewhere in the database. Creating separate routines for weekly and monthly reports makes the script more readable; imagine seeing all the logic for those two reports embedded here as well.
As another example of script abstraction, imagine sorting a contacts database by last_name then first_name for a given report. If you've written a script to produce that report, sorting is a step in the process; however, odds are that you'll want to be able to sort by last_name, first_name againperhaps for a different report, perhaps as a function that lives on a list view or in a menu, or perhaps before running an export script (or perhaps all the above). Whenever reasonable, we recommend looking for ways to abstract your code and foster reuse. It saves time and complexity if suddenly your client (or boss) comes to you and says you need to now present everything by first name. If that logic lives in one place, it's a one-minute change. If you have to hunt for it, the change could take days and require extensive debugging.
Even if you're not planning to reuse blocks of code, it's still a good idea to break scripts into subscripts. They're easier to read, they're easier to enable and disable during testing, and they allow you to name them in logical ways that are comprehensible even at the Define Scripts dialog level.
Some other good candidates for subscripts are sort and find routines; these are often reusable by a wide range of scripts or by users as standalone functions. Other uses of subscripts might be for the contents of a loop or If function. Sometimes it's easier to separate logic into separate paths by dividing logical groups into separate scripts, as in the example we gave a little earlier. When you have a branching script (covered later in the chapter), it's helpful to encapsulate a single branch in a subscript. This allows you to see the flow of logic in the parent script and cover each branch in its own respective subscript.
Common Scripting Topics
|