bcquality/community/knowledge/performance/case-true-of-for-long-condition-chains.good.al
António Silva f7a00bf0b6 Comma-group the pure value sets in the case false of sample
Review feedback: the five value sets sharing exit(false) should be comma
separated. Applied to the three that are pure field reads with no order
dependency.

The Get and the Blocked read keep their own value sets. The documentation
guarantees that the first matching value set executes, which orders matching
across separate value sets; it says nothing about evaluation within one
comma-separated set, and the natural lowering of that is an equality-or
chain — where AL's or does not short-circuit. Grouping the Get with the
checks that must precede it would rest the sample's correctness on
undocumented behaviour, which is the defect these two articles exist to
prevent.

Encodes the boundary in the Best Practice section so the grouping is applied
where it is safe and not where it is not, and scopes the repeated-exit
detection signal explicitly to nested chains so the case sample does not read
as its own anti-pattern.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 12:05:29 +01:00

52 lines
2.1 KiB
AL

codeunit 50542 "Perf Sample CaseChain Good"
{
procedure IsShippableLine(SalesLine: Record "Sales Line"): Boolean
var
Item: Record Item;
begin
// 'case false of' matches the value sets in order and stops at the first
// match, so each value set is reached only when the previous one passed —
// and Item.Get is never called for a non-item line.
case false of
// Pure field reads with no side effects and no order dependency, so
// they share one value set and one action.
(SalesLine.Type = SalesLine.Type::Item),
(SalesLine."No." <> ''),
(SalesLine."Qty. to Ship" > 0):
exit(false);
// These two keep their own value sets even though the action repeats:
// ordering across separate value sets is what the documentation
// guarantees. The Get must not run until the checks above pass, and
// Blocked must not be read until the Get succeeded.
Item.Get(SalesLine."No."):
exit(false);
(not Item.Blocked):
exit(false);
end;
exit(true);
end;
procedure FindOpenDocumentType(CustomerNo: Code[20]): Text
begin
// 'case true of' stops at the first condition that holds, so the later
// lookups never run once an earlier one matched.
case true of
HasOpenDocument(CustomerNo, "Sales Document Type"::Quote):
exit('Quote');
HasOpenDocument(CustomerNo, "Sales Document Type"::Order):
exit('Order');
HasOpenDocument(CustomerNo, "Sales Document Type"::Invoice):
exit('Invoice');
end;
exit('None');
end;
local procedure HasOpenDocument(CustomerNo: Code[20]; DocumentType: Enum "Sales Document Type"): Boolean
var
SalesHeader: Record "Sales Header";
begin
SalesHeader.SetRange("Document Type", DocumentType);
SalesHeader.SetRange("Sell-to Customer No.", CustomerNo);
exit(not SalesHeader.IsEmpty());
end;
}