EmailPro Icon



FileMaker’s Send Mail script step allows you to send plain text emails through SMTP or the user’s mail client. You need to look beyond native functionalities if you’d like to use HTML formatting or send multiple attachments. HTML-formatted emails in particular can provide some fantastic polish to your solutions.

There are some great email plug-ins out there, but sometimes I don’t think my needs justify the cost. This module handles the following scenarios free of cost:

  • HTML-formatted content
  • Multiple attachments
  • SMTP authenticate over SSL
  • Multiple To, CC and/or BCC recipients
  • Custom From and Reply-To headers
  • Server-side compatible


Just call the “. emailPro . send” script. It takes its parameters in Let format. If you prefer to use a different parameter format, please see the ParamConverter module for an easy bridge between formats.


  • bBox plug-in (Free)
  • Mac OS only! (Sorry. bBox is only compatible with OS X. Let me know if you’d like to talk about adding compatibility for some other plug-in.)

If your server is running OS X, then you can install the plug-in there and send emails via Perform Script on Server. This option does not yet support attachments, however.


Just find a place to store the plug-in file in your solution, import the module scripts, and customize the Configuration and Settings scripts.


This project is hosted on GitHub. Download the latest release directly as a .zip package below.

Download EmailPro

Release history and previous versions are available here.

Query Builder



  • This module provides a simple utility for writing and troubleshooting SQL queries, including abstracting field and table names, for use with FileMaker’s ExecuteSQL function.
  • Use this module if you prefer typing out your query manually instead of using a wizard (like the excellent SeedCode SQL Explorer) but would like to make the troubleshooting and field/table name abstraction process faster. There’s also a simple query formatter to help you keep your queries readable.
  • Read more about this module here.


  • See video.
  • Don’t forget to check out the sample queries available in the Scripts menu.


  • The installation takes about a minute.
  • See installation instructions in the readme script.
  • Note: This module includes three custom functions that require a copy of FileMaker Pro Advanced to install in another FileMaker file.
  • Requires FileMaker version 12 or higher.


  • MIT License – see the readme script.


  • Download from here.



As outlined here, suggests using “Let Variables” for passing named parameters to scripts. This method for constructing name-value pairs is popular in large part because it leverages native functionality and doesn’t require any custom functions.

//-- Let Format --
"$name = \"Calvin\" ;
$age = 5 ;"

Still, others prefer to use alternative dictionary formats. One such format is the one created and popularized by Jesse Antunes of Six Fried Rice. (Let’s call it SFR format.)

//-- SFR Format --

This module provides a means for systems employing SFR format to easily integrate Let-based modules with minimal effort. You can also integrate SFR-based scripts into Let-based systems if you wish. Let me know if you’re interested in other conversions and we can talk about extending the functionality.


The ParamConverter module provides one script for converting from SFR format to Let Variables and one for converting from Let Variables to SFR format. The most straightforward approach is to create a wrapper script for each Let-based script you’d like to call. This wrapper script will convert the parameters and script results for you. The module includes an example script that shows you how. You can also see it in action in the enhanced demo file for the ErrorHandling module.

To call a Let-based script, just copy the example script from this module and redirect it to the Let-based one.


Just import the ParamConverter script folder and begin making wrapper scripts.

Issues and To-Do’s

There is an issue converting multi-dimensional (nested) values. Thanks to Jeremy Bante for pointing that out. I will post an update when the issue has been resolved.

Release History

  • 1.0.0 – 11/27/13 – Initial release
  • 1.0.1 – 12/04/13 – Fixed bug translating pairs without whitepace between them
  • 1.0.2 – 12/05/13 – More strict when testing for SFR format
  • 1.1.0 – 1/09/14 – Added ability to temporarily override variable prefix
  • 1.2.0 – 5/13/14 – Added support for multi-dimensional arrays


This project is hosted on GitHub. View the latest release and download it as a .zip package below.

Download ParamConverter

Release history and previous versions are available here.


Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
— Martin Golding

Error log layout

Error log layout


Your code is at some point going to fail you and your users. Some people don’t bother to trap for errors while others check every single action. This module is for the rest of us – those who want moderate functionality without being overburdened with extra script steps and decisions.

The module provides two primary scripts; one for logging errors to a table, and another for displaying errors to the user. Much of the power in this module is in the conventions it proposes.

Guiding Assumptions

  • Error handling should require very little overhead on the developer’s part. It should be habitual.
  • Error handling should not distract from the overall goals of the code.
  • Errors should be logged as close to the event as possible. This allows us to gather better diagnostic information and prevents other errors from interfering.
  • Errors should be reported as close to the initiating action as possible. This allows errors from a generic subscript to bubble up to the button script, for example, where it can be customized for the context.
  • Any particulars about an error (how to abort, message to the user, workflow decisions, etc) should be handled where the affected logic resides. In other words, it should be transparent and customizable for the developer – not buried in a subscript somewhere.

How It’s Used (In a Nutshell)

  • Scripts are wrapped in a single-pass loop so that it’s easy to skip straight to error handling and clean-up.
  • Error codes are always posted to $_error.
  • If you want to display a message to the user, post it to $_error_message.
  • All scripts check for and log errors just before exiting.
  • User-facing scripts check for error messages to display to the user. A subscript may declare an error message, but it passes the message up the chain for the user-facing script to use or modify.
  • When presented with an error dialog, the user can choose to email a bug report to the admin.
  • All errors are logged to a table along with diagnostic information.


See the README script for installation instructions.

Release History

  • 1.0.0 – 11/27/13 – Initial release
  • 1.0.1 – 11/30/13 – Respects open records
  • 1.0.2 – 12/04/13 – Error dialog allows user to press “Report” and email details to admin
  • 1.0.3 – 12/04/13 – Upgraded ParamConverter to 1.0.2; Enhanced control over error display
  • 1.1.0 – 08/19/14 – Restore original capture state; Don’t show dialogs when Error Capture is set to On


Download the latest version on GitHub.

The demo below provides additional examples that demonstrate more robust parameter parsing. The additional examples use the Six Fried Rice parameter format, so they also employ the wrapper scripts in this module.

ErrorHandling 1.0.3 Enhanced

Permission Granted

Permission Granted

Security Matrix

Security Matrix

Version History

1.1 – 01/03/2013 – Fixed typo in set variable declaration, added new comments to Readme

1.0 – 11/25/2013 – First Release


This module exists for two main reasons:

  • It’s difficult if not impossible to preemptively check whether a user has permission to perform certain actions in FileMaker Pro.  Typically the developer has to let the user attempt the action and then check for errors.
  • System administrators often want an easy way to reconfigure their users access privileges.


How It Works

This module provides you with tables, scripts, a layout, and a few custom functions that make it easy for you to define a template.  Once defined, you’ll be able to insert security checks throughout your system to determine whether or not your users are supposed to perform certain actions… before they actually try to perform them (this works great for custom formatting among other things).  The layout provided makes it easy for system administrators to define permissions on a security group level (and using the template that you define for them).



  1. Copy and Paste these tables into your solution ( the users table is optional , though if you don’t use it, be sure to adjust the opening script –> “Retrieve My Security Settings” accordingly )
  2. Update the next serial number for vSecurityMatrixTemplate::zc__recordSerial__n.
    (When implementing this table into your solution, it will probably not have any records, so the next serial number should be “1”)
  3. Copy and Paste the custom functions from this file into yours
  4. Recreate the value list in your solution
  5. Copy and Paste ( or import ) the scripts in the Navigation Module in this file into your solution
  6. Copy the main layout –> “Groups” into your solution
  7. Hook up the OnFirstWindow script –> “Retrieve My Security Settings” to your solution’s OnFirstWindowOpen Script
  8. Edit the “Configure Security Matrix Template For All Users” script in the “Configuration and Setup” folder.


Download –>

DynamicNavigation 2

DynamicNavigation 2 is a table based navigation with a top navigation and a sub navigation to every top entry. The solution allows you “to go somewhere” and also “to do something” on the landing page. The basic idea is quite simple: Every line in the navigation table has a layout name and a script call. The layout name is used in a scriptstep “Go to layout > layout name by calculation”, while the script call is a word that is transformed into a global variable – which can be evaluated on the landing page, if there is an active script trigger “OnLayoutEnter”. The combination of the two let you not just navigate, but trigger actions as well.

More information:

I just moved all downloads to a new improved website. Registration no longer is required.






Multilingual ValueLists

MultiLingual ValueLists Interface




In a former post, I provided a simple technique to allow FileMaker Developers to put multilingual labels on their layouts.  That tackles the majority of the multilingual requirements for the average system.  In some cases however, we need a little bit more multilingual integration in our systems.  This module will provide you with a means to create and edit multilingual valuelists in your solution.


Integrating this module into your existing solution should be relatively simple.

You will need to:

Relationships To Copy

  1. Copy/Import tables from this module into your solution (no need to copy the “~Contacts” table as it’s just a sample
  2. Recreate the relationships in your solution (see sample image)
  3. Copy the “Edit Value Lists” layout into your solution (It’s based on “Defaults” )
  4. Attach “Get List Of VL Tables” script to the OnLayoutEnter script trigger for that new layout
  5. Run the “Get List Of VL Tables” script



Creating New Value Lists

This will also be extremely easy.  You will need to:

  1. Duplicate one of the existing “VL_” tables (new table name must begin with “VL_” and field names must remain the same)
  2. Ensure that a new layout got created when you created that table (it doesn’t have to show up in the menu, but it must have a name that matches the table name)
  3. Create a relationship to the new TO (starting from “Defaults” relate it to your table with a cartesian product)
  4. Create a value list (I recommend duplicating one of the existing value lists, and just repointing the zc__recordSerial and userValue fields to the same fields in your new table)



The values in the value lists that you use throughout your system will be dependant on the value chosen in the global field in the “Defaults” table.
If the value is 1, then it will use the first column of values (the first language), 2 will represent the 2nd column of values… and so on.

This system is currently set up using 5 repetitions, and this allows it to support up to 5 languages.  If you need more languages, simply increase the number of repetitions on all the repeating fields, and make sure that those new repetitions also show up on your layouts.


Special Notes

This technique relies heavily on the usage of Virtual List tables, and uses “Get ( RecordID )” instead of an actual serial number within the tables.  This makes it easier to setup and use, but because it’s set up like this, I want to make sure that you do not provide any interface for your users to delete records from your “VL_” tables.  You could provide buttons that would make them think they’re deleting records from that table, and really just clear the values from the record instead if your users require that kind of functionality


Download –>


Time Picker


I saw that a date picker has already been posted to this site, so I figured that a time picker was in order.
This one’s pretty simple, looks half-decent, and is incredibly easy to implement.


  1. Copy Scripts
  2. Create A Layout Named “Time Picker”
  3. Copy/Paste Layout Objects to “Time Picker” Layout
  4. Attach “Display Time Picker” As An OnObjectEnter Script Trigger, or call it from a button. If calling the script from a button, please also specify the fully qualified field name to modify as a parameter

Download –>

Migration Assistant





This is simply a utility that will help you tally up the total record counts in each of your tables.  It will also help you identify what fields are using the auto-enter serial number option, and let you know what the next serial number is set to.  Implementing this into your ‘source’ table prior to performing a data migration usually takes only a minute or two, and can save you the headache of tracking down this valuable information manually.



Here’s what you need to do to implement it:

  1. Copy the “MigrationAssistant” table from this solution to yours
  2. Copy the “MigrationAssistant” layout from this solution to yours (or feel free to roll your own)
  3. Copy the “Migration Assisstant” script folder from this solution to yours

That’s it!
Once you’ve completed those steps, simply run the “Run Migration Assistant Report” script, and you will be presented with your own MigrationAssistant report



Please note, that compiling this report makes heavy use of the ExecuteSQL function.  While use of this function was necessary to help make this as portable as it is, its performance is not amazing.  For example – I implemented this recently into one of my larger projects (over 100 tables, many of which are fairly wide), and running the full-blown report takes somewhere around 7 minutes.  Should you suspect that you will need to run this report multiple times however, there is an optional flag which you can toggle to speed things up.

One of the first script steps in “Run Migration Assistant Report” will be to “Set Variable $refreshTableAndFieldNames”.
If after you’ve run the full report once, you decide to toggle its value to “0”, you will notice that you get your results much faster.
When set to “0”, the script will no longer dynamically grab a list of table names or field names.

Once toggled to “0”, that same script’s duration was reduced to about 1 second (down from 7 minutes).
I hope some of you will find this helpful, and maybe even offer up some suggestions as to how to improve upon this.

Download –>

Multilingual LabelMaker



LabelMaker Pro

This is my attempt at providing a simple, modular tool to FileMaker Pro developers that will translate all your field labels into the selected language.  It’s scalable, efficient, and much easier to use than any of the other solutions I’ve found that aim for the same goal.  Once implemented into your system, creating new labels is as easy as creating a new record, assigning it a variable name, and providing the various translations for it.

Try it out, let me know what you think, and definitely send any suggestions my way.  I’ll be happy to implement them.

Download –>


2014-07-07 –> Added a “Refresh All Windows” option as requested by Giedrius.  Windows are refreshed in reverse order so as to maintain consistent order

2013-11-18 –> Altered field definition for Labels::LabelsByLanguage – Field now has an auto-enter calc that will prohibit entry of double quotes.  It will replace them will single quotes (Double-quotes were breaking my call to Evaluate)