FlowFields in Business Central are not stored in the database. Every time you need their value in AL code, you have to ask for it explicitly.

There are two ways to do that:

  • CalcFields
  • SetAutoCalcFields

They are not interchangeable, and using the wrong one in the wrong context is one of the more common performance mistakes in AL development.

CalcFields: explicit, immediate, one record at a time

CalcFields calculates the FlowFields you specify on the current record at the moment you call it. It is the right choice when you need a FlowField value once, on a single record, outside of a loop. The calculation is explicit and happens exactly when you call it.

CustomerRec.SetRange("Date Filter", 20240101D, 20241231D);
CustomerRec.CalcFields(Balance, "Net Change");

Inside a loop, calling CalcFields on every iteration means a separate database call per record. For small result sets that is acceptable. For larger ones, it becomes a performance problem fast.

SetAutoCalcFields: declare once, calculate automatically

SetAutoCalcFields tells Business Central to automatically calculate the specified FlowFields every time a record is retrieved, whether through FindSet, Find, or Next. You declare the fields before the loop, and the platform handles the rest.

Customer.SetAutoCalcFields(Balance, "Net Change");
if Customer.FindSet() then
    repeat
        // Balance and "Net Change" are already calculated here
    until Customer.Next() = 0;

The result is the same as calling CalcFields inside the loop, but the intent is clearer and the platform can optimize the retrieval. This is the pattern to use whenever you need a FlowField on every record in a loop.

One thing that trips people up

Calling SetAutoCalcFields without parameters clears the list. If you have set auto-calculation earlier in the same procedure and want to remove it for a subsequent operation on the same record variable, an empty call resets the state. This matters when you reuse a record variable for different queries in the same codeunit.

The other thing worth knowing: SetAutoCalcFields is scoped to the record variable, not the table. A different variable pointing to the same table does not inherit the setting.

RecordRef support since BC26

Until Business Central 2025 release wave 1, SetAutoCalcFields was only available on the Record data type. As of BC26 (AL runtime 15.0 and higher), it is also available on RecordRef. If you write generic code that works with any table through RecordRef and FieldRef, you can now apply the same pattern without falling back to per-record CalcFields calls.

The short version

  • Use CalcFields for a single record when you need a FlowField value once.
  • Use SetAutoCalcFields before any loop where you need a FlowField on every record.

If you are reviewing AL code and see CalcFields inside a loop that processes more than a handful of records, that is the first place to look when a report or batch process is slower than it should be.

The Microsoft documentation on AL Database Methods and Performance on SQL Server covers both methods with additional context on SIFT and index interaction, which is worth reading alongside this post.

 


Discover more from think about IT

Subscribe to get the latest posts sent to your email.

Leave a Reply

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

Post Navigation