Use different field functions in AL

Completed

When you're working with data from the database in AL, you need to use other statements that are used on fields, such as:

  • CalcFields

  • CalcSums

  • FieldError

  • Init

  • TestField

  • Validate

CalcFields and SetAutoCalcfields statements

When you retrieve FlowFields in AL code, their value is always zero. The reason for this value is because the calculation formula of FlowFields isn't run in AL code. When you use FlowFields on a page, the FlowField is calculated automatically, but not in AL code. Therefore, you need to use the CalcFields function. By using the CalcFields function, you can specify which FlowFields need to be calculated during the implementation of your code.

In the following example, only the Balance and Net Change FlowFields are calculated. Outside the repeat until statement, the FlowFields are no longer calculated, only within their scope.

customer.SetRange("Date Filter", 0D, Today());

// Using CALCFIELDS
if customer.FindSet() then
    repeat
        customer.CalcFields(Balance, "Net Change");
       // Do some additional processing
    until customer.Next() = 0;

If you always want to calculate certain FlowFields (within the function scope), you can use the SetAutoCalcFields function.

// Using SETAUTOCALCFIELDS
customer.SetAutoCalcFields(Balance, "Net Change");
if customer.FindSet() then
    repeat
    // Do some additional processing
    until customer.Next() = 0;

CalcSums statement

The CalcSums function is used to calculate a total for a specific field, based on the filters of the dataset.

In the following example, the Sales Invoice Header table is filtered on the Bill-to Customer No. field between 10000 and 50000 and the Document Date between 0D (the beginning) up to Today. The CalcSums function summarizes all amount fields.

salesInvoiceHeader.SetCurrentKey("Bill-to Customer No.");
salesInvoiceHeader.SetRange("Bill-to Customer No.", '10000', '50000');
salesInvoiceHeader.SetRange("Document Date", 0D, Today());
salesInvoiceHeader.CalcSums(Amount);

Message('The total is %1', salesInvoiceHeader.Amount);

FieldError statement

The FieldError function stops implementation of the code, causing a run-time error, and creates an error message for a specific field. The field displays a red border, indicating that an error has occurred with the value of this field.

if item."Unit Price" < 10 then
    item.FieldError("Unit Price", 'must be greater than 10');

Init statement

The best approach is to start by using the Init command on the record. This action initializes all fields on the record.

Initializing means that each field gets its default value (0 for numeric data types, empty string for text, and so on). However, if you specified an InitValue on the field in the table, the Init function initializes your field with that value and not with the default value.

customer.Init();
customer.Name := 'John Doe';
customer."E-Mail" := 'john.doe@contoso.com';
customer.Insert(true);

TestField statement

With the TestField function, you can check if a field has a value or if it's blank. If the field is empty, the TestField function generates a run-time error.

customer.TestField("Salesperson Code");

You can also use the TestField function to test whether a field contains a specific value or not. If it doesn't, the field generates an error. In the following example, the TestField checks if the Salesperson Code contains the value ZX. In this case, it doesn't contain the value because the value is set to DK.

customer."Salesperson Code" := 'DK';
customer.TestField("Salesperson Code", 'ZX');

Validate statement

When you assign a value to a field, the OnValidate trigger of that field isn't run. If you want to run the OnValidate trigger, use the Validate function.

Customer."Phone No." := '1234567891234'
customer.Validate("Phone No.");

You can also use the Validate function to assign a value and run the OnValidate trigger.

customer.Validate("Phone No.", '1234567891234');