Basic C/AL programming
As an example, let's create a simple function that receives a checksum as a parameter and verifies if a check sum satisfies given criteria.
It is a typical task for a developer working on an ERP system to implement verification such as the Luhn algorithm that is widely used to validate identification numbers, such as a credit card number.
How to do it...
- In the Object Designer window, create a new codeunit. Assign a number and name (for example,
50000
,Luhn Verification
). - Click View, then C/AL Globals; in the Globals window open the Functions tab.
- In the first line of the table enter the function name,
SplitNumber
.The verification function receives a BigInteger number as an input parameter, but the algorithm works with separate digits. Therefore, before starting the validation we need to convert the number into an array of digits.
- Position into the
Split
function, the number you just declared, and click View, then C/AL Locals. First tab in the Locals window is Parameters. Enter the first parameter of the function:Name
: DigitsDataType
: ByteVar
: Set the checkmark in this field
- Still in the C/AL Locals window, click View, Properties to open the variable properties and set Dimensions = 11.
- Close the variable properties window and add the second function parameter AccountNumber with type BigInteger.
The Parameters window with the list of properties for the variable Digits is shown in the following screenshot:
- Next, navigate to the Variables tab. Insert a variable i of Integer type.
- Close the local declarations window to return to the code editor and type the function code:
FOR i := 11 DOWNTO 1 DO BEGIN Digits[i] := AccountNumber MOD 10; ccountNumber := AccountNumber DIV 10; END;
- Open the C/AL Globals window again and insert the second function
VerifyCheckSum
. This is the main function that implements the verification algorithm. - In the C/AL Locals window, insert a single parameter of this function
AccountNumber
of typeBigInteger
. - Navigate to the Return Value tab and fill in the Return Type field. In this case, the type should be Boolean.
- In the C/AL Locals window, declare three local variables as follows:
Name
Data Type
Digits
Byte
CheckSum
Integer
i
Integer
- Select the Digits variable, open its properties, and set Dimensions to 11.
- Type the following function code:
SplitNumber(Digits,AccountNumber); FOR i := 1 TO 10 DO BEGIN IF i MOD 2 = 1 THEN CheckSum += (Digits[i] * 2) DIV 10 + (Digits[i] * 2) MOD 10; END; CheckSum := 10 - (CheckSum * 9) MOD 10; EXIT(CheckSum = Digits[11]);
- In the
OnRun
trigger, place the code that will call the verification function:IF VerifyCheckSum(79927398712) THEN MESSAGE(CorrectCheckSumMsg) ELSE MESSAGE(WrongCheckSumMsg);
- To present the execution result to the user,
OnRun
uses two text constants that we have not declared yet. To do it, open the C/AL Globals window in the View menu. In the Text Constants tab, enter the values as in the following table:Name
Value
CorrectCheckSumMsg
Account number has correct checksum
WrongCheckSumMsg
Account number has wrong checksum
How it works...
The SplitNumber
function, described in Step 1 through Step 8, uses a FOR...DOWNTO
loop with a loop control variable to iterate on all digits in the BigInteger
number, starting from the last digit. In each step the number is divided by 10 using the integer division function DIV
. The modulus division function MOD
returns the remainder of this division that is placed in the corresponding element of an array.
The Dimensions
property of the parameter Digits
tells that this variable is an array consisting of 11 elements (value of Dimensions
is the number of elements. A variable with undefined dimensions is a scalar).
When a function is called, it can receive arguments either by value or by reference. Var
checkmark in the parameter declaration means that the argument will be passed to the function by reference, and all changes made to the Digits
array in the function SplitNumber
will be reflected in the function VerifyCheckSum
that calls SplitNumber
. Arrays cannot be function return values in C/AL, so passing an array variable by reference is the only way to send arrays between functions.
The VerifyCheckSum
function defined in Step 9 to Step 13 calls the helper function SplitNumber
and then uses the same loop type, but iterates from the first digit to the last (FOR 1 TO 10
). This loop computes the checksum, which is compared to the last digit of the account number. If the two values match, the checksum is correct. Finally, the function returns the Boolean value conveying the verification result, TRUE
or FALSE
.
Based on this result, the OnRun
function in the codeunit will display one of the two text constants in a message. In the given example, the checksum is incorrect, so the message will look like this:
To see the message for the correct result, replace the last digit in the account number with 3. The correct number is 79927398713.
Messages shown in the dialog box are declared as text constants in Step 16. The same text can be written within C/AL code without declaring constants, but in general, it is recommended to use named constants, because they allow to store text values in different languages and easily switch to any available language layer. Hardcoded text values in the C/AL code cannot provide such flexibility.