Demo file: 2010-12-21 getfieldname – requires fm11
When FileMaker introduced the Set Field By Name script step in version 10, they wisely included a complementary function, GetFieldName, to help prevent database breakage due to field renaming.
This is the standard use for GetFieldName, and it’s a very good use… in fact, in FM 10, that was just about all you could do with it.
I had high hopes when I first heard about this function, because the ability of a field to know its own name presents some intriguing possibilities. Unfortunately in 10, GetFieldName(Self) did not resolve properly in unstored calculations, as per the highlighted field below.
The good news is that this shortcoming was fixed in FileMaker 11.
This means that for the first time, we have the ability to modify the output of a calculated field merely by renaming the field itself. And while I offer no apologies, I do ask the reader’s indulgence for what follows. We’re exploring a “proof of concept” involving the GetFieldName function, which is not necessarily the optimal solution to this particular reporting challenge. Still, I think it’s worth exploring.
Here’s an example of how we might take advantage of this new capability. Below is a table of tour bookings. Pax is tour-speak for “number of passengers”, and currently we’re looking at some March departures for three consecutive years.
Note the three rightmost columns: pax_2009, pax_2010 and pax_2011, which exist to help produce a report comparing three years side by side. These are calculated fields, and in the Dark Ages (i.e., FileMaker 10 and earlier), we would have defined these fields along these lines:
pax_2009: if ( year ( date_depart ) = 2009 ; pax ; "" )
pax_2010: if ( year ( date_depart ) = 2010 ; pax ; "" )
pax_2011: if ( year ( date_depart ) = 2011 ; pax ; "" )
But now in this enlightened (post-10) era, we can define all three fields identically as:
Let ( [
a = Year ( date_depart ) ;
b = GetFieldName ( Self ) ;
c = Right ( b ; 4 )
If ( a = c ; pax ; "" )
) // end let
And while we’re at it, let’s make sure the storage type for these fields is “unstored”. In a nutshell, each field will compare the rightmost four characters of its name against the year of the date in date_depart, and if they’re the same, the field will show the pax value; otherwise it will show nothing.
We’ve also defined three summary fields to total these three fields, which allows us to produce a comparison report, showing totals for last year, this year, and next year side by side.
What happens next year, when we want to increment each of our pax_YYYY fields by 1? We simply rename the fields (pax_2011 to pax_2012, pax_2010 to pax_2011, and pax_2009 to pax_2010). Give that a moment to sink in: we can now update our business logic by renaming fields.
What about the column labels in the report? Can we use GetFieldName to make them update automatically? The answer is a resounding yes. And we can use “merge variables” (another new-in-FM-11 feature) to help. Here’s our report in layout mode:
The year column labels are merge variables named $$year1, $$year2 and $$year3, and we could have populated them via script, but how boring would that be? Instead we use conditional formatting — not to format the labels, but to cause the merge variables to refresh so they always indicate the correct years.
The conditional formatting formula is basically the same for all three labels, so let’s just look at how we’ve applied it to $$year3:
To reiterate: no conditional formatting has been applied. We just wanted a way to “tickle” the merge variables on the report. And there’s even a bit more trickery perhaps worth drawing attention to: the Let statement is being used to update (or create) the $$year3 variable, and that’s all the Let statement is doing, which is why the actual calculation part of the statement is empty.
As far as I’m concerned, this use of conditional formatting is taking “cleverness” a bit too far (given that a script runs to generate this report, why not just set the variables there?), and I intend to sternly reproach myself at the earliest convenient opportunity.
But using GetFieldName to bind $$year3 to the rightmost four characters of the pax_2011 field name, in such a way that renaming the field doesn’t break things? Nothing clever about that… that’s just common sense.