"No Holding Back FileMaker Blogging"


Support this site by clicking on a sponsor below or becoming a patron!

Create a Complete Contact Manager

Become a patron of this FREE web site!

Recent Blogs:

Popups and Pickers
Popups and Pickers

Window Locking
Window Locking

Everything Changes
Everything Changes

Subsummary Unique Count
Subsummary Unique Count

Scripted Change Log
Scripted Change Log

Meta-consulting is a service Database Pros offers to help other developers over programming hurdles via GoToMeeting. Email John Mark Osborne or call John Mark at (909) 393-4664 to find out more about this service.

Tips & Tricks Videos

Quick Tip:

Container Comparison
FileMaker Pro can actually compare two container to see if they are equal. A true or false or false result is returned. This can be handy if you are trying to create a multi-state or conditional button. FileMaker Pro is also smart enough to realize that the same graphic is used on multiple layouts or records and should only be stored once. This saves file space and speeds up the display of graphics.

FileMaker 20 Video Tutorials

Fun Stuff:

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.

The Philosophy of FileMaker recommends PCI!

RSS Feed
Robust FileMaker Design
Level: Expert
Version: FileMaker 15
Category: General
Tuesday, March 21, 2017
Have you ever inherited a system built by someone else, changed a field’s name and everything stopped working? The issue, hardcoded names used in indirection, makes the system fragile. FileMaker provides developers many methods to add flexibility using indirection. However when these instances of indirection are not treated properly they will raise all sorts of problems. In this article we will discuss good practices regarding indirection that will help you build a dynamic and robust FileMaker system.

Robust FileMaker Design

What is indirection (and what could go wrong with it)?
Indirection in FileMaker refers to the ability to reference an object (table, layout, value list, field, script) by its name, instead of its internal id. For example, I can use a few lines of code to tell a script to do something if the user is in field "CONTACT::firstName".

If [ Get ( ActiveFieldTableName ) & "::" & ( ActiveFieldName ) = "CONTACT::firstName"]
     Do Some Code
End If

It looks normal at first glance but there are actually two issues with this approach and with many other uses of indirection: The first issue is that if not treated carefully, renaming objects may break indirection. In our example, if I rename the field "firstName" to "first_Name", it will break my script because there are no fields named "firstName" anymore. The second issue is that indirection is not considered as a reference in DDRs. So if you use analysis tools like BaseElements to check where field CONTACT::firstName is referenced, that script will not be included.

How to write robust indirection
With that being said, how do we write robust indirection? Robust indirection will try to dynamically grab an object name and use it in your solution.  So we should try to avoid hardcoding the following in our solutions:
  • Table occurrence names
  • Layout names
  • Field names
  • Window names
  • Value list names
  • Script names

Following this guideline, for our example we want to get rid of the hardcoded TO names and field names and instead, dynamically grab the field's name.

If [ Get ( ActiveFieldTableName ) & "::" & Get ( ActiveFieldName ) = GetFieldName ( CONTACT::firstName ) ]
     Do Some Code
End If

In this case, if I change the field name to first_Name, that script will still work. Also now field CONTACT::firstName is considered as referenced by this script in DDRs. The magic is being done by the function GetFieldName (). This function actually takes a direct reference to the field and translates it into a name.
However, not all objects in FileMaker have a function like GetFieldName to translate direct references into a name. For example, if I want to have one script perform different activities on different layouts, in order to determine which layout the user is on, it seems unavoidable to use something like:

If [ Get ( LayoutName ) = "Contact - Data Entry" ]
     Do Some Code
End If

which suffers from the same problems as the first example: you can't rename your layout and it won't be recognized as a reference in DDRs. What do we do now? Well, in this case it will be hard to solve the second issue. But we can do something about the first issue so we can rename our objects with confidence.

Internally FileMaker assigns an internal ID for every object in the system. When you use script steps like Set Field [] and point that to a field, FileMaker will store the ID of the field with that script step. That is why no matter how you rename your field, Set Field [] script step will never be broken.

FileMaker has a series of design functions that provide you with information about these internal IDs. With some custom functions built upon them, we can grab the internal ID for any table, layout, value list, field or script and use them in our calculations and scripts. Be sure to try them out in the demo file of this article.
So let's say the internal layout ID for layout "Contact - Data Entry" is 2. With the help of our custom function "getLayoutName" (getLayoutName will take an internal layout ID and translate it to that layout's name). I can rewrite my script to be:

If [ Get ( LayoutName ) = getLayoutName ( 2 ) ]
     Do Some Code
End If

This way I can rename the layout and still have the script working. As mentioned before, referencing internal IDs still can not be seen by DDRs as a reference. Also it makes reading the code harder. So be sure to comment your calculation or your script when you use internal IDs to enhance readability. Here is an article if you want to learn more about using internal IDs in your solution.

One last example I want to mention here is about using the ExecuteSQL function. ExecuteSQL is a context independent way to retrieve data. It can save a lot of time when developing complex reports or charts. However ExecuteSQL requires indirection by nature. If not treated carefully, renaming of fields or tables will break the SQL statement used in your ExecuteSQL. In the demo file I included two scripts showing how to use some custom functions to make your SQL statement dynamic and robust.

How do I identify indirection in my own solution?
Now that we have went through two examples of how to write robust indirection, you might want to take a look at your own solution and see if there are any potential problems in there caused by indirection. How do I find all those instances? Use an DDR analysis tool like BaseElements or InspectorPro to search for indirection.

Here are the functions you should be searching for:
  • Get(LayoutName)
  • Get(ActiveFieldName)
  • ValueListItems ( )
  • Evaluate( )
  • ExecuteSQL( )
  • DatabaseNames
  • FieldBounds( )
  • FieldComments ( )
  • FieldIDs( )
  • FieldNames( )
  • FieldRepetitions ( )
  • FieldStyle( )
  • FieldType( )
  • Get(ActiveFieldTableName)
  • Get(ActiveRepetitionNumber)
  • Get(LayoutNumber)
  • Get(LayoutTableName)
  • Get(ScriptName)
  • GetField( )
  • GetFieldName( )
  • GetNextSerialValue( )
  • GetNthRecord( )
  • LayoutObjectNames( )
  • Lookup( )
  • RelationInfo( )

and here are the script steps you should be looking for:
  • Set Field by Name[ ]
  • Go to Layout[ ] (By Name option and By Number option)
  • Go to Related Record[ ] (By Name option)

Once you find all the instances that could potentially use indirection you can go over each one of them and determine if they uses hardcoded names and should be updated.

Using indirection in FileMaker definitely gives your solution more flexibility, allowing you to accomplish complicated tasks with fewer lines of code. If you follow what we discussed in this article carefully, you should be able to build a dynamic yet robust FileMaker system.

Weihao Ding

Example File (available to patrons at $5.00 per month): Download here if you are a patron

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!


Steve M 05/17/2018
  Fantastic Article and great Custom Functions for returning internal layout ID.

I was able to take a script that had to check hard-coded If/Else If statements (about 42 script steps) and drop it down to 3 (Set Variable, Close Window, Go to Layout (Name by Calculation). Thanks again JMO.
Response by:   John Mark Osborne 05/17/2018
Only FileMaker geeks (myself included) get excited about this kind of stuff. You know what I mean. Great to hear this article helped you out. Indirection, adaptive or dynamic scripting is one of the hallmarks of professional design.
Rob 03/28/2017
  Hi John Mark, Thanks for putting this blog together. I sincerely appreciate your efforts. FYI, the sample file for "Robust File Design" has a bug in the script attached to the "Show Result" button for the "Bad Example". It returns a "?" instead of a list of contacts. Thought you might like to know. Rob
Response by:   John Mark Osborne 03/29/2017
Thanks so much for the feedback. The sample file has been fixed and uploaded to the site. Happy FileMaking!
Rebecca Johnson 03/24/2017
  John Mark you have always been right there with help and direction. Thank you for this WONDERFUL blog.
Richard DeShong 03/24/2017
  From a programming best practice, a constant, "This", should be replaced by a variable, This.

For each major function in your system (or even at the individual script level), you can have an "environment setup" script that captures the current names of layouts and such in global variables.
Pedro Rezendiz 03/24/2017
  Wow and wooow, thank you very much for sharing those wonderfouls tips. Regards. Pedro
Response by:   John Mark Osborne 03/24/2017
You are most welcome. The FileMaker Community is all about supporting each other.
Beverly Voth 03/24/2017
  I bet Eric could arrange a remote presentation at DIGFM.
Response by:   John Mark Osborne 03/24/2017
Remote presentations seem so impersonal but I'll give it some thought. I know you have done some remote presentations Beverly. I think it works well when everyone else is on a computer and can interact but when they are in the crowd they seem so removed from the event. Might as well just watch my videos lol.
Jerry Gonzales 03/24/2017
  It's been ingrained in me to watch out for indirection within ExecuteSQL function calls, but I was surprised to learn of the other "gotcha" areas to watch out for. Great eye-opener. Thanks for sharing!
Eric Matthews 03/24/2017
  Nice FileMaker Blog!

You should come share it and some of its content at DIGFM.
Response by:   John Mark Osborne 03/24/2017
I would love to visit DIGFM. It's the first place I ever did public speaking. Problem is I live in southern California which is 6 hours away by car. Next time I'm up that way for business, I'll be sure to see if a meeting coincides with my visit.
Anatole Beams 03/23/2017
  I use these techniques more and more in my coding. It makes for reliable automation and also really portable functions and scripts that can be lifted and dropped from one solution to another.
Richard Stuart 03/23/2017
  Wow! GREAT article! Thank you!

Add Comment:

First Name: *
Last Name:
Email: *
Web Site:
Comment: *
 Email Addresses will not be shared on the web site!