FlowFields in Business Central are virtual, their values aren't stored in the table, so AL has to explicitly calculate them. The common pattern is CalcFields, but calling it inside a loop is one of the most frequent performance mistakes in AL code, because each call fires its own SQL query against the database.
Before
Customer.SetFilter(Balance, '>%1', LargeCredit);
if Customer.FindSet() then
repeat
Customer.CalcFields(Balance);
if Customer.Balance > MaxCreditLimit then begin
Customer.Blocked := Customer.Blocked::All;
Customer.Modify();
end;
until Customer.Next() = 0;After
Customer.SetFilter(Balance, '>%1', LargeCredit);
Customer.SetAutoCalcFields(Balance);
if Customer.FindSet() then
repeat
if Customer.Balance > MaxCreditLimit then begin
Customer.Blocked := Customer.Blocked::All;
Customer.Modify();
end;
until Customer.Next() = 0;Same result, one SQL query difference. With CalcFields inside the loop, every single iteration triggers its own database round-trip to fetch Balance. With SetAutoCalcFields called once before FindSet, the FlowField calculation gets folded straight into the original query that loads the customers. Why is that something we ant to do? The whole loop runs against data that's already there. ✌️
SetAutoCalcFields has to be set before the records are loaded (before FindSet/FindFirst/etc). Calling it after the record set is already loaded won't help - the fields need to be part of the original query.The fix is a one-line change, but the performance difference scales directly with how many records you're processing. The more rows in the loop, the more SQL round-trips you're saving.
Resources
