Summary Fields - Never Again

Over the last couple of weeks some customer requests have allowed me to work on two pet projects I’ve been wanting to commit to for a long time.

One is to eliminate the use of summary fields. Val and I have disagreed ‘energetically’ about the use of these for ages, but every time I accidentally go to a layout with one or more of these on it and have to wait for the darn progress bar to complete, or to a report where I’m constantly waiting for screen refreshes, the same conversation starts - me: “we should never use these things”, Val: “they just work”.

Personally, I thing Claris should add a new compatibility feature: “Not Recommended For WAN use” and summary fields would be top of my list for this.

An overview of my solution to this consists of:

A new generic reports table including key fields to link to tables that would normally include one or more summary fields, a quantity of ‘subtotal1’, subtotal2’, etc. fields, and a few global ‘grandtotal1’, ‘grandtotal2’, etc. fields and a batch number field.

A new global batch field added to any table that would normally have a summary field included within it.

A dedicated table occurrence group containing only the tables required for the report and the new generic reports table linked to the table, that should have had the summary fields included, via the keyfields and the batch fields with create records on the side of the reports table.

Within the report creation script after the finds, layout navigation and sorts have completed, there is a generic ‘create summary’ script that is called using JSON parameters with an array for each sub summary part included within the report. Within the JSON the following are passed to the generic script: the sort field (that each subsummary part is based on) leading or trailing, the names of the fields to be totaled, the names of the reports table fields that are to store the results and the name of the batch field.

The generic script first creates a UUID batch number in the global field that the report is based on and loops through each record totaling the specified fields into variables. Loops are exited if a change of value within the specified sort fields is found and the script either populates the specified subtotal field in the ‘reports’ related record of the first or last record within the loop depending on whether leading or trailing has been specified. This also creates the key and batch fields within the reports table (hence when exiting the report layout the related records created can be found and deleted by finding the batch number field).

The script isn’t mature enough as yet to publish an example but the reason for providing this overview is to report on the results.

After testing the values comparing this approach with the same data set using summary fields we carried out some speed tests.

The problem with layouts containing summary fields is that the end of script is reported prior to the date of being rendered, therefore at the end of the report script, before recording the end time we included a go to first record go to last record go to half white point and then back to the first record refreshing the window each time, which would be a common thing to do while checking the results.

We design on the premise that data processing performance is prioritised over report generation, but were still a bit nervous how this approach would compare to using summary fields. To say we were surprised would be an understatement. Using a resulting found count of only about 1200 records and a layout with 2 subsummary parts and a total in only the trailing one, the test took 28 seconds using the summary fields but only 9 seconds using the scripted approach.

The other benefit is that we have completely smooth scrolling in the report, whereas the summary field version is constantly pausing to refresh.

The only negative we can currently see is that this is not dynamic if the data set is adjusted by omitting records. However, I don’t believe I’ve seen a customer do this and we’d customise the menus to prevent it.

A little setup is required, but once done all we have to do is call a script passing parameters as JSON and can delete all our summary fields.

To finish up, I could have run the grand totals alongside the above to set the final global totals fields. However, I’ve a complementary subscript that is called passing the field names as JSON, which builds up another JSON object passed back to the calling script containing the fields names and their totals using this to calculate each total:

While (

//initialVariables

[

~counter = 0 ;

~count = Get ( FoundCount ) ;

~theField = GetField ( $totalField ) ;

~val = ""

] ;

//Condition

GetAsNumber ( ~counter ) < GetAsNumber ( ~count ) ;

//logic

[

~counter = ~counter + 1 ;

~val = ~val + GetNthRecord ( ~theField ; ~counter )

];

//result

~val

)

I like this calculation, as it has always frustrated me that we can’t sum a list like the Excel Sum() function without workarounds. With the introduction of While() we can now do this without looping through records and it is pretty quick.

I hope some of the above is of interest.

Regards

Andy

5 Likes

That right there is the crux; it's one of the reasons why FM appeals to people who know their job well but know nothing about proper architecture. It lets them build a tool that just works.

But it is also the one thing that prevents FM from being easily scalable. When the solution's complexity, the data load or the user count (any combination thereof) grows it becomes very expensive to roll the bad design choices back. It is tough to convey to people that they basically shot themselves in the foot, it is easier for them to blame the platform.

6 Likes

@AndyHibbs This all sounds great, but without a demo file to understand, test, look for pitfalls, benchmark against summary fields, the text makes it hard for me to see in my head how this will play out. I do understand it is early for you to share something, but hope you will reach that point.

As for myself, I am not for or against summary fields, but must admit some design choices can lead to a bad experience.

The worst experience I got is from a system where the original architect implemented selector-connector + listOf summary fields to list id. He uses those fields in scripts all the time, so each time I summon the "current" tab of the data viewer in a script, there is a 98% chance the summary field gets listed. Normally it would be out of context and show nothing, but because of selector-connector, it technically is within context and starts listing IDs for the whole table. There is about 10 tables with more than 200k records. So basically, I can only use the "watch" tab of the data viewer, bringing the "current" tab is prohibited as it requires me to force quit the application. I hope I will never meet that developer or any of his other work.

By the way, who's Val?

2 Likes

I will put something together, I’m sure someone will be able to take it further, which would be good. Currently still testing and early results are very good.

Val (Valerie) is my wife, mother to our 2 children, co-director, and fellow FileMaker developer. We met at work amid the Hypercard days 35 years ago and started using FileMaker then. For the last 16 years we’ve been sitting at desks beside each other developing in FileMaker, now firmly cloud based (so we have been able to travel during the old normal). We’ve trained and employed our nephew for the last 6 years, who is based in Northern Ireland (we’re in the East of England, currently in a field with a tent), and our son is currently helping out with some development work part time due to the the pandemic affecting his job. So very much a FileMaker family.

After all this time I still can’t spot when an internal business discussion becomes a ‘husband and wife’ disagreement, to my detriment😉

I tend to use ~val for ‘value’ as a bit of a laugh to myself.

2 Likes

ps, I feel your pain on the system you described

1 Like

Hi Andy,

I'm completely with you and your approach, haven't used a summary field since 2005 or 2006 when changing FM developement with going from 5.5 to 7.

Holger

With one very notable exception: the ListOf summary field is extremely useful and fast and a very useful tool to produce a list of IDs from a found set - ever since it was introduced not too long ago. I favor While() now if for no other reason that it saves me from having to create a schema element

5 Likes

I have two approaches. The first uses a hide condition which is true by default. The summary field is only exposed when the user requests it. The second uses slide panels, again, it requires manual activity to reveal the summary fields. Both of these methods are effective. They are easy to retrofit and easy to train up users.

The hide condition can includes tests to see if the user is on the LAN, desktop, etc.

6 Likes

Progressive disclosure is great for summarizing data on-demand.

I moved a clients' legacy file to the cloud recently and a set of summaries on their layout got really slow. So, we put them in a popover, and instead of displaying the summary fields themselves, opening the popover calls a PSOS script to calculate the summaries server-side. Then the result is stored in variables and displayed in button bar calcs within the popover.

Client was happy.

4 Likes

I don't use that either although I see it is useful but your argument of cluttering the schema made me going from script loop to MBS-Loop which is about the same age as ListOf...

we have them.
we are swearing.
we ask to not use them.
we still have them.

We are supporting quite some companies with their own FileMaker solution, often with an inhouse supporter (but FM is never his/her main job). They keep on creating summary fields.

We can do a 'redesign' without summary fields - a month later, they appear again - because the workarounds are too complicated for some of the inhouse supporters

so, we have to live with them.

A workaround (often used - if possible) is to have pure number fields without any calculation (set by script at some point in the workflow). At least scrolling becomes smooth(er)

:+1:

You're saying you can use While to get a list of ID's in a found set, and it's as quick as ListOf? How do you do that? With GetNthRecord or something?

Yes, GetNthRecords since you still have to iterate over the actual records to grab the ID.

The old HyperList comparison is still relevant though: Gathering FileMaker Records with HyperList v2.0
so the big caveat is that there is not a single approach that is best for all scenarios. The bigger the found set the more the speed of the approaches differs.
I obviously will not hesitate to create a ListOf summary field if the performance warrants it, but I will try to minimize the schema if serves no relevant purpose to add a field.

3 Likes