Level: Advanced, Version: FM 16 or later

Set Variable By Name Re-Revisited

Demo files: set-var-by-name-v4 and set-var-by-name-md5

Background

This is a quick follow up to last December’s Set Variable By Name Revisited, and to avoid repetition will assume the reader is familiar with the material that was presented in that article. But to briefly recap:

1. FileMaker does not provide an obvious way to programatically name a variable.

2. We can work around this limitation using a combination of Evaluate + Let.

3. For convenience, we can accomplish the preceding via a custom function.

4. The goal, last time, was to be able to instantiate any text string as a script ($) or global ($$) variable, on the fly, without having to worry about so-called illegal characters or reserved words.

Incidentally, a use-case for this technique would be a situation where you are “scoping” your variables to window names but don’t have any control over the names of the windows. (All of this is discussed in greater detail in my article from last December.)

Why A New Approach Is Needed

So why a new article and new demo files? To remedy a few shortcomings with the approach I previously advocated.

For example, did you know that there is a maximum variable name length limit of 100 characters (including the leading $ or $$)? I only recently learned this thanks to Geoff Gerhard and Charlie Bailey. Here the proposed variable name is 101 characters in length…

…and if we try to create a variable using this name, FileMaker balks.

But if we remove a single character, e.g., the space between the AAAAAAAAA and the BBBBBBBBB, then our variable name length (including the leading $$) will be exactly 100 characters and our attempt will be successful.

Bear in mind that the overall goal for this technique is be able to translate any text string into a variable name. Previously the focus was on dealing with illegal characters and reserved words, but now we have a second challenge as well: translate ridiculously long names into something that FileMaker won’t reject.

My solution last time, i.e., for the first challenge, was, when necessary, to HexEncode the name during the “Set” phase, and then autodetect that transformation during the “Get” and “Clear” phases. But hex encoding does not address challenge #2… in fact, it actually makes things worse, since hex encoded strings are always longer than their unencoded equivalents.

Hex encoding to avoid an “illegal” hyphen in a potential variable name.

The New Approach

The new approach is to encode the name as an MD5 hash rather than hex encoding it. As you can see in this example, MD5 encoding always returns a 32 character string, regardless of the length of the input string.

More Info About The Demo Files

If you’re wondering about the difference between the two demo files, “Set Variable by Name, v4” encodes the variable name as MD5 only when necessary, but “Set Variable by Name as MD5” always encodes the variable name.

Also, and this pertains to both demos, if you want to see dynamic naming of a “script” ($) variable, turn on the debugger, click one of the “Set Var” buttons, step to the “End If”, and view it on the “Current” tab of the data viewer.

Other Resolved Issues

In addition to the preceding, there were two other issues, which I only recently became aware of:

1. There was a nasty bug where…

  • generating a variable with a rep number of 1, and then
  • generating a variable with the same name but a different rep number
  • would nuke the original variable

2. There was a flaw in the variable clearing logic where under certain conditions instead of being cleared they would show up in the data viewer like this.

Both of these issues have now been resolved.

3 thoughts on “Set Variable By Name Re-Revisited”

  1. Researching on this subject and mighty Google let me found you. Thanks for the post.

    Wondering if you have a way to programatically declare a variable but the content inside the variable is whatever is inside a container field? (example: $cont = container::container1). I have a use case where I need to integrate a fm solution to a web service with cURL. We set the content of a container field (say a file) in to a variable (under Claris’ recommendation) then use that variable as part of cURL. Problem: the web service uses the variable name as the file name but never the original file name. And you guessed it, I cannot know the file name before hand hence I can’t hardcode the file name as variable name.

    1. If the container field contains a file named “test.pdf” do you want the variable to = “test.pdf” (i.e., the text string)? Or should the variable consist of the actual PDF contents?

      1. $test.pdf

        Actually right after I left the comment I came up with an idea to solve this issue and it works. 😅.

        I set a variable using standard way, say $TempVar = container::container. So the actual PDF is inside this variable now. Then combine with your technique to programmatically declare a variable say $test.pdf but inside this variable the content initially is just a random string (say “dummy”). Then I again programmatically set this variable $test.pdf = $TempVar. Solved !!. It works and I am implementing it in my solution now.

Leave a Reply to Kevin HwangCancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.