Use Validate() instead of direct field assignment

Properties
PC0037 Warning Design Code Fix Ignore Obsolete

When a value is assigned to a record field with :=, the AL runtime writes the value directly without executing the field’s OnValidate trigger. Any event subscribers attached to that trigger — from Microsoft, partners, or per-tenant extensions — are silently skipped.

On the Sales Line table, for instance, the OnValidate trigger on "Unit Price" recalculates "Line Amount" from Quantity * "Unit Price". A direct assignment to "Unit Price" leaves "Line Amount" stale — the posted invoice carries the wrong total.

Use Validate() to assign field values so the full validation chain executes regardless of which extensions are installed.

Example

procedure SetUnitPrice(var SalesLine: Record "Sales Line"; NewPrice: Decimal)
begin
    SalesLine."Unit Price" := NewPrice; // Use Validate() instead of direct field assignment [PC0037]
    SalesLine.Modify(true);
end;

Replace the direct assignment with Validate():

procedure SetUnitPrice(var SalesLine: Record "Sales Line"; NewPrice: Decimal)
begin
    SalesLine.Validate("Unit Price", NewPrice);
    SalesLine.Modify(true);
end;

Code fix

The code fix replaces Record."Field" := Value with Record.Validate("Field", Value) preserving the original value expression as the second argument.

Exception

The rule is not raised when:

  • The record variable is declared as temporary. Temporary records do not persist and their OnValidate triggers are typically irrelevant.

Use a pragma when you have a documented reason to bypass validation on a non-temporary record:

#pragma warning disable PC0037 // Justify why we don't execute the validation on the "Unit Price" field
SalesLine."Unit Price" := NewPrice;
#pragma warning restore PC0037

See also