Looping through and filtering lists of values turns out to be a common task in FileMaker. Having a few different techniques at your disposal is quite useful. In this post, we are going to look at a set of related techniques for processing lists. First we look at how to loop through each item and perform some function or task on each item. Then we will move on to a custom function for filtering lists by any valid FileMaker expression. Finally we will use another Custom Function to easily parse Layout Object Names from a layout and use them in a dynamic slide navigation scheme.
Looping Through and Filtering Lists
Let me start off by saying that this demo file is for FileMaker 13 only, but almost all of the techniques demonstrated have value in FileMaker 12 and possibly back to FileMaker 10, and 11. Really it is only the final part that uses FileMaker 13 specific features.
Video
Here is the video of the techniques in action. You can read more about the techniques below.
Recursive Custom Functions Aren’t Always the Answer
One way you could loop through and filter lists is by using a recursive Custom Function. While this certainly works, sometimes it can be slow or sometimes you can’t create a custom function ( maybe you don’t have access to FileMaker Advanced ). We are going to look at another method for iterating through lists that doesn’t use recursion. As a result, it can be pretty fast. The very popular CustomList custom function uses a technique similar to the one we are going to work through.
Substitute Can Simulate Looping
The first key idea is that the substitute function can serve as a rudimentary iterator. By taking advantage of the fact that each item in a list is separated by a carriage return, we can insert whatever we want in between each item by using Substitute. If we start off with the following list:
- Apple
- Orange
- Banana
- Pineapple
And then apply the following function:
Let([ theList =Demo::ListOfText ; prefix = "Some "; suffix = "s are good." ]; prefix & Substitute ( theList ; "¶" ; suffix & "¶" & prefix ) & suffix )
We will get the following back:
- Some Apples are good.
- Some Oranges are good.
- Some Bananas are good.
- Some Pineapples are good.
Pretty simple, right? Note how we add the “prefix” and “suffix” to the top and bottom of our final substitute respectively.
Build then Evaluate
While the above technique can be useful sometimes, it’s somewhat limited. What we really want to be able to is perform is some kind of FileMaker logic on each and every item in the list. What if we took the approach of building a valid FileMaker expression and then evaluating it? We can build a valid FileMaker expression for each item in the list using Substitute. Then we wrap that new list with a List() function and evaluate it. It looks like this:
Here is our list:
- 12
- 34
- 56
- 1
- 1000
- 3
Here is our function:
Let([ theList =Demo::ListOfNumbers ; prefix = "100 + " ; suffix = " * 2 ;" ]; Evaluate( "List(¶" & prefix & Substitute ( theList ; "¶" ; suffix & "¶" & prefix ) & suffix & "¶)" ) )
And our result looks like this:
- 124
- 168
- 212
- 102
- 2100
- 106
Great! Now we can do any kind of FileMaker login on each item in our list. What else can we do with this idea?
Filtering By Expression
I wanted to take this same concept and apply it to the filtering of lists. We have to filter lists a lot in FileMaker and often filtering by some arbitrary logic is pretty hard. I set out to create a custom function that would let me filter a list by any valid FileMaker expression. The idea would be that if I the if the expression returned true for a given item, then it would appear in the resulting list. If it didn’t, then it wouldn’t.
The custom function is called FilterByExpression. It provides a special key word “item” that you use in when crafting your filter expression. A filtering expression might look like this:
"LeftWords( item ; 1 ) = "Top""
Apply that to a list of values with the Custom Function and you will get every item in the list whose first word is “Top”. Check out the video, and see the example file for more information.
Getting Layout Object Names
FileMaker 13 brings with it a couple of new Layout Objects: one called Slide Panels and the other called “PopOvers”. These are quite simply awesome. While they work pretty great right out of the box, you can get even more use out of them with the Go To Object script step. This step lets you activate these “sliders” and “pop overs” from a script. Since this works by targeting the object by it’s Layout Object Name, having a custom function that can quickly and easily snatch the Layout Object Names of the layout comes in handy. That’s just what GetLayoutObjectNames() does. It was built using the same techniques as described above. Here is its full signature.
GetLayoutObjectNames ( type ; nameStartsWith ; enclosedBy ; isFrontPanel ; nameOfFile ; nameOfLayout )
Each of the parameters is optional. The idea is that it will Filter the list of named layout objects and give you only the objects that match. For example:
GetLayoutObjectNames ( "slide panel" ; "" ; "" ; "" ; "" ; "" )
will give us all the slide panels on the Layout. This a truly useful little function. For more information on how this works or to see it in action, watch the movie and try the demo file.
Thanks !!!
[av_promobox button=’yes’ label=’Download’ link=’manually,http://www.geistinteractive.com/wp-content/uploads/2014/02/ListProcessing.fmp12.zip’ link_target=” color=’green’ custom_bg=’#444444′ custom_font=’#ffffff’ size=’large’ icon_select=’yes’ icon=’ue801′ font=’font-awesome-subset’ av_uid=’av-2r7ibu’]
Example File Download
[/av_promobox]
Todd, this is really great stuff…!
Presumably having some way to grab the object name of the button pressed would mean significantly better abstraction as there would be no need to edit each version of the script parameters..
Am already using slide panels in preference to tabs, as there is so much more control and creativity possible – so this was a great bit of learning.
Went off and changed ‘item’ to ‘it’ to match all my Groovy programming
Thanks 🙂
Sadly there is no way to get the name of the button that was pressed. BUT you can use “Self” to get the label of the button. I’ll show that in another movie.
I thought of using “it”, for the same reason. But I decided to go with “item” because it is the “list item”. I thought it would make more sense to more people 🙂
Awhhh, come on. Let’s use “this”, “it”, “me”, “myself” all those nice OOP terms. 😉
Downloading your file and adding to to filemakerstandards CF repo. You want to add under your own github name or have me do it. I can’t just let valuable custom functions lie around out there on the Internets.
Nice video work you’re doing Todd.
Hey Matt!
I suppose I should add it to github, huh? I’ll send you a pull request.
Thanks for compliments on the video! We are have some fun!
Awesome! Thank you for sharing the great technique and the video.
Thanks for this great post. BTW there is a missing closing parenthesis for the first code listing.
& suffix
)</strong)Thanks! fixed.