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:
CalcFieldsSetAutoCalcFields
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
CalcFieldsfor a single record when you need a FlowField value once. - Use
SetAutoCalcFieldsbefore 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.
