Cancelling Dialogs Under the Windows operating system, the Show Custom Dialog script step shows a message box with a close box. If users click the close box, then the message dialog will be dismissed. At first, this appears to cause problems but, once you realize that the close box returns a message choice of "1", then you can trap for it with the Get(LastMessageChoice) function. Your best bet is to interpret the close box as a cancel. This will allow you to place your Cancel button for the dialog at the rightmost position which also returns a message choice of "1".
Jaymo David Knight (aka Speedy) started calling me JoMo years ago, because of my initials, and it kinda stuck. Over the years, it's evolved to the current Jaymo but you can call me anything as long as you are friendly. Other nicknames include Hoss, n2 and Wiz.
When you start writing scripts for the first time, they are fairly simple and can be understood quickly. Even weeks or months down the line, the name of the script should be enough to identify the functionality. As your scripts increase in complexity, you need to consider modular scripting. Modular scripting is essentially writing your scripts in pieces and connecting the pieces with a parent script.
Take a look at the "Print Report" script. It is not very complicated but it's hard to give a simple example of modularity since modular scripting implies complexity. With that said, compare it to the modularized version titled "Print Report [Modular]" to understand how much easier it is to conceptualize. For simplicity sake, this script doesn't actually print. It just enters preview mode. But, you get the idea. Modular scripting makes the script easier to read, like chapter titles in a book. If you don’t want detail, you don’t have to look at it. If you need to see the specific steps of the sub-scripts, drill down. In fact, FileMaker 16 has a new feature that allows you to quickly open a sub-script from the calling script without searching for it.
SIDE TIP: To open a sub-script, just Command-Double-Click (Macintosh) or Ctrl-Click (Windows) on the script specified in the Perform Script step. As long as the script is in the same file, a new tab will be opened containing the sub-script. If a tab for the sub-script already exists, it will be simply be activated.
Print Report [Modular]:
Return to Original State:
Why Modularize? One reason to modularize, other than readability, is the ability to reuse code. Let's say you always want to maximize the window when you visit a layout. Since you visit this layout through a number of different scripts, you have decided to modularize it rather than add the same script step into every script.
This may not seem like a big help until you consider what happens when you want to add one more script step to your Go to Layout script. For instance, let's say you also want to make sure the layout is always viewed in Browse mode. If you didn't modularize the script, you would have to locate every script that utilizes the Go to Layout script steps and add the Enter Browse Mode step. Since you have modularized, only one change is needed and all scripts that reference the Go to Layout sub-script are updated.
Another reason to modularize is to enable easier testing. By isolating code in a sub-script, it can be easily run independently of the rest of the script. This can be very helpful in long complicated scripts instead of trying to disable all the script steps involved in a procedure.
Some also say modular scripting makes scripting easier. Being able to define each area of a script in isolation allows the developer to focus in on the task at hand. I personally don’t find it helpful but to each his own. There is no single best way to approach the writing of a script. Use what methods work best for you as an individual.
The most important reason to modularize is likely code reuse. If you have a set of script step programming that is used more than once with different surrounding code, it's a good idea to isolate those steps in a sub-script. This allows you to edit the code in a centralized area when the inevitable change or bug occurs.
When and Where to Modularize You don't need to modularize every script. A general benchmark rule is start consider modularizing when the scroll bar activates in the script. Since FileMaker Pro offers resizable dialogs, let's set that number at around twenty script steps. That doesn't mean you should always modularize at twenty steps, just start thinking if it makes sense when your scripts get longer and more complicated.
Common break places for modularizing scripts include looping code, If statements or any series of script steps that perform a unique task. If you can think of a concise name for a piece of code, consider modularizing it. If you are commenting a segment of script steps, it might be time to modularize it for one or more of the reasons already mentioned.
Be careful not to over modularize your scripts. I have worked on many adopted FileMaker solutions over my career and one of my pet peeves is modularizing to such a degree that it is nearly impossible to analyze what a script does. There is something to be said about the simplicity of a script without sub-scripts. Each script is unique but keep in the back of your mind the thought that somewhere in between is the best approach.
I once worked, and still do, on a solution where it was over modularized. I remember one script that had approximately five levels deep of modularity. I’m not talking five modular scripts branching off the parent but five scripts all linked in a chain. It was so difficult to determine what was going on I almost rewrote the script from scratch. Don’t be that guy who programs a solution and then passes your headache onto another developer.
Real Life Modularization The most important modularization is often the simplest. It doesn’t take a complicated script to make modularization incredibly useful. I find just the opposite. Some of the most invaluable modularized scripts are only a few lines long. Case in point are two modularized scripts I can’t live without: Set Error Capture and Allow User Abort. It's very important to note that these two script steps return to their default on each new script. If you don't want the default settings, which I most often don't, they need to be set at the beginning of each script.
The Set Error Capture step stops FileMaker error messages from appearing, such as the one that could occur if a dialog is canceled or no records are found. The default for Set Error Capture is "Off" so it needs to be set to "On" to disable error messages at the beginning of each script. It’s your job to decide what to do with the error that is generated but more about that if you read the Ultimate Find blog article on this web site.
So... why do you need to modularize this script step? Well, imagine visiting each script to turn Set Error Capture off when you are developing so you can see error messages and then on when you ship it so users don't see error messsages and then off when you update it and so on and so on. That's a lot of work if you have a couple dozen scripts or more.
Modularizing the Set Error Capture script step is easily done by creating a one line script. Other scripts simply need to Perform the sub-script at the beginning. To turn off Set Error Capture for all scripts, just set the modularized script to off, in one place, and the change flows through to all the scripts that call the Set Error Capture modularized script.
The modularized Set Error Capture script can be designed to be even easier to use with the addition of a condition. Using an IF statement to control the Set Error Capture setting, there is never a need to modify the modular script once it is created. A test of the current privilege set name allows developers to see any new error messages that might rear their ugly heads while users don't ever see messages.
SIDE TIP: There are two similar functions that often cause confusion: Get(AccountPrivilegeSetName) and Get(CurrentPrivilegeSetName). The former returns the privilege set attached the account that logged on to the solution. The latter identifies the privilege set that is currently in use, specifically when mtemporarily modified using the "grant full access" option via a script.
It’s also a good idea to apply the same logic from the Set Error Capture sub-script to Allow User Abort. Allow User Abort has the same behavior as Set Error Capture in that it defaults to the On setting each time a script is run.
Every script should prevent cancelation either by Command-Period on the Macintosh or Esc on Windows. If a user can cancel a script in the middle, they might get left on a layout you don’t want them to see or leave a process unfinished. On the other hand, developers often need to cancel a script such as when it enters an endless loop. Force quitting a FileMaker solution can result in a corrupt file and should always be avoided.
Reusing code is the hallmark of modular scripting and the primary benefit in these two indispensable examples. Since Set Error Capture and Allow User Abort should be used in just about every script, modularizing them makes it easy to change all scripts calling these sub-scripts in one fell swoop. All changes flow through the single sub-script to all the calling scripts, centralizing your code. Small changes to a repetitive piece of code is not a nightmare of locating every script with the same piece of code.
Keep it Simple Modular code can take on many faces outside of scripting including calculations (Custom Functions and Let function), layout design (layouts with calculated content rather than multiple layouts with different fields) and features combining all of them. Programmers often make modular button bars that can be changed with simple text input. The trick is not to get too tricky. When your adaptive code grows to monstrous proportions and requires a PHD to dissect the code, you have done a disservice to the client and the FileMaker community. While it may make it easier for you change the button bar on each new solution, it can introduce performance issues, especially over a remote connection. And, if another developer takes over the project, the dynamic code, it may cause the new developer migraines trying to understand the code if some change is required to the programming.
I’ve seen modular code for storing the current tab so when you return to a layout you can re-select the tab that was last active. The complexity of the code was unnerving. This is not a hard feature to program, requiring two scripts, a couple of script steps and a script trigger. It's just not modular. But, is the modularity worth the ability to copy and paste the code from layout to layout or file to file without any changes really worth it in this case. Sometimes I just can’t fathom the reasoning behind complicated code other than a developer tooting their own horn.
I beg all of you reading this blog article, keep your code simple. Sometimes it needs to be complex. Maybe it needs to be adaptive. Modular scripting is also good. Just don’t overdo it. It’s good for you, me, the client and the FileMaker community if you don't get carried away. Just step back and consider whether what you are doing is worth it or not. are you creating more problems that you are solving.
Over-Modularization In my many adventures in FileMaking, I came across this example of a file that was severely over-modularized. It was so modularized that it hindered me, as a developer, from updating it in a timely fashion. If I looked at a script, it would often call dozens of other scripts. This would be an issue except that the modularization wasn't one level deep. Each child script often called several child scripts of their own. Trying to track down what was happening so I could make a simple modification was like pulling teeth. My kingdom for the simplicity of a single script!
Above is just a taste of that solution I dreaded working on every day. Curse the developer who thought it was a good idea. Let's make a script that calls a one line script that never gets used anywhere else. While we're at it, let's modularize a script that has a very simple IF statement. While I would have preferred to show examples of scripts that had multiple layers of child scripts, I couldn't fit it all into one screen shot. You'll just have to believe me and empathize my pain.
This blog is completely free. Please support it by clicking on one of the advertisers at the left side of the window or becoming a patron. Thanks so much!
Having error messages from already debugged scripts can be a real pain. If you are on the fifth subscript have unnecessary error messages from the first four can be a real problem and cause you to miss read a real error.
I cut my teeth as maintenance Cobol programmer and even worked with Wayne Stevens, one of the fathers of Structured Design in the early 1980's/ Modularization is a must for good programming ... One of FM greatest assets is the ability to add comments in the scripting code exe specially when you revisit something two years later. Right on...