A repetitive statement is also known as a loop. The following table shows the looping mechanisms in C/AL.
Looping mechanism | Description |
---|---|
FOR | Repeats the inner statement until a counter variable equals the maximum or minimum value specified. |
FOREACH | Repeats the inner statement for each element in a .NET Framework collection. |
WHILE | Repeats the inner statement as long as the specified condition is TRUE. The statement in a loop of this kind is repeated 0 or more times. |
REPEAT | Repeats the inner statements until the specified conditions evaluate to TRUE. The statements in a loop of this kind are always executed at least one time. |
FOR-TO and FOR-DOWNTO Control Structure
The following syntax shows the FOR-TO and FOR-DOWNTO statement.
Copy Code | |
---|---|
FOR <Control Variable> := <Start Number> TO <End Number> DO <Statement> |
Copy Code | |
---|---|
FOR <Control Variable> := <Start Number> DOWNTO <End Number> DO <Statement> |
The data type of <Control Variable>, <Start Number>, and <End Number> must be Boolean, number, time, or date.
Use FOR-TO and FOR-DOWNTO statements when you want to execute code a specific number of times. The <Control Variable> controls the number of times that the code of the inner statement is executed according to the following:
-
In a FOR-TO loop statement, the <Control Variable> value is increased by one after each iteration. The inner <Statement> is executed repeatedly until the <Start Number> value is greater than the <End Number> value.
-
In a FOR-DOWNTO loop statement, the <Control Variable> value is decreased by one after each iteration. The inner <Statement> is executed repeatedly until the <Start Number> value is less than the <End Number> value.
Note |
---|
When the FOR statement is executed, <Start Number> and <End Number> are converted to the same data type as <Control Variable> if it is required. This type conversion can cause a run-time error. |
Note |
---|
If the value of the <Control Variable> is changed inside the FOR loop, then the behavior is not predictable. Furthermore, the value of the <Control Variable> is undefined outside the scope of the FOR loop. |
Example 1
Create the following variable.
Variable | Data type |
---|---|
Count | Integer |
The following code initiates a FOR loop that uses the integer control variable named Count.
Copy Code | |
---|---|
FOR Count := 1000 TO 100000000000000 DO |
When this statement is executed, a run-time error occurs because the start and end values are converted to the same data type as the Count control variable. Count has been declared as an integer variable. The end number 100000000000000 is outside the valid range for integers, and an error occurs.
Example 2
The following example shows how to nest FOR statements.
Create the following variables.
Variable | Data type |
---|---|
I | Integer |
J | Integer |
Set the Dimensions property of variable A to 5;7.
The following FOR statements could be used to initialize every element in a 5x7 array with the value 23.
Copy Code | |
---|---|
FOR I := 1 TO 5 DO FOR J := 1 TO 7 DO A[I,J] := 23; |
FOREACH Control Structure
You can use the FOREACH statement to iterate through a .NET Framework collection or array object.
The FOREACH statement has the following syntax.
Copy Code | |
---|---|
FOREACH <Element> IN <List> DO <Statement> |
The <List> variable must be a DotNet data type that is set to .NET Framework collection or array type.
Note |
---|
The FOREACH statement is not limited to collections and arrays. You can use it with any .NET Framework object that implements the GetEnumerator method, the MoveNext method, and the Current property. |
The <Element> variable must be a data type that is compatible with elements in the .NET Framework collection or array that is specified by the <List>.
Example 1
The following code example iterates through a .NET Framework collection that contains a generic list of elements and returns each element as text in a message.
Create the following local variables in a Microsoft Dynamics NAV object, such as a codeunit.
Variable | DataType | Subtype |
---|---|---|
mylist | DotNet | System.Collections.Generic.List`1.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' |
element | DotNet | System.Object.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' |
Add the following C/AL code (for example, on the OnRun trigger of the codeunit).
Copy Code | |
---|---|
// Instantiate the .NET Framework collection object mylist := mylist.List(); // Populate the collection mylist.Add('Item 1'); mylist.Add('Item 2'); mylist.Add('Item 3'); mylist.Add('Item 4'); // Iterate through the collection FOREACH element IN mylist DO BEGIN MESSAGE(FORMAT(element)); END; |
Compile and run the codeunit.
Example 2
The following code example is similar to example 1, except this example iterates on the text string of each element in the .NET Framework collection.
Create the following local variables in a Microsoft Dynamics NAV object, such as a codeunit.
Variable | DataType | Subtype |
---|---|---|
mylist | DotNet | System.Collections.Generic.List`1.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' |
txt | Text |
Add the following C/AL code to objects (for example, on the OnRun trigger of the codeunit).
Copy Code | |
---|---|
// Instantiate the .NET Framework collection object mylist := mylist.List(); // Populate the collection mylist.Add('Item 1'); mylist.Add('Item 2'); mylist.Add('Item 3'); mylist.Add('Item 4'); // Iterate through the collection FOREACH txt IN mylist DO BEGIN MESSAGE(txt); END; |
Compile and run the Microsoft Dynamics NAV object.
Example 3
The following code example iterates through a .NET Framework collection for a dictionary of keys and values and returns each key/value pair as text in a message.
Create the following local variables in a Microsoft Dynamics NAV object, such as a codeunit.
Variable | DataType | Subtype |
---|---|---|
mydictionary | DotNet | System.Collections.Generic.Dictionary`2.'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' |
element | DotNet | System.Object.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' |
Add the following C/AL code (for example, on the OnRun trigger of the codeunit).
Copy Code | |
---|---|
// Instantiate the .NET Framework collection object mydictionary := mydictionary.Dictionary(); // Populate the collection mydictionary.Add(10, '1'); mydictionary.Add(20, '22'); mydictionary.Add(30, '333'); mydictionary.Add(40, '4444'); mydictionary.Add(50, '55555'); // Iterate through the collection FOREACH element IN mydictionary DO BEGIN MESSAGE(FORMAT(element)); END; |
Compile and run the Microsoft Dynamics NAV object.
Example 4
The following code example iterates through a .NET Framework array that contains a list of file names from a local directory and returns each file name in a message.
Create the following local variables in a Microsoft Dynamics NAV object, such as a codeunit.
Variable | DataType | Subtype |
---|---|---|
strarray | DotNet | System.Array.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' |
txt | Text |
Add the following C/AL code (for example, on the OnRun trigger of the codeunit).
Copy Code | |
---|---|
strarray := Dir.GetFileSystemEntries('C:\\myfiles\'); FOREACH txt IN strarray DO BEGIN MESSAGE(txt); END; |
Compile and run the Microsoft Dynamics NAV object.
WHILE-DO Control Structure
The following syntax shows the WHILE-DO statement.
Copy Code | |
---|---|
WHILE <Condition> DO <Statement> |
If <Condition> is TRUE, then <Statement> is executed repeatedly until <Condition> becomes FALSE. If <Condition> is FALSE from the start, then <Statement> is never executed.
The WHILE DO statement can be used when some code should be repeated as long as an expression is TRUE.
Programming Conventions
When there is only one condition, put WHILE and DO on the same line. Put the statements on separate lines and indented by two spaces.
When there are multiple conditions, put the conditions on separate lines and indented by two spaces and put DO on a separate line that is aligned with WHILE.
Example
Copy Code | |
---|---|
WHILE <expr> DO <Statement>; |
Example
Copy Code | |
---|---|
WHILE <expr> DO BEGIN <Statement>; <Statement>; END; |
Example
Copy Code | |
---|---|
WHILE <expr> AND <expr> AND <expr> DO BEGIN <Statement>; <Statement>; END; |
Example
Create the following variable.
Variable | Data type |
---|---|
I | Integer |
The following C/AL code increases the variable I until it equals 1000 and displays a message when it is finished.
Copy Code | |
---|---|
WHILE I < 1000 DO I := I + 1; Message(format(I)); |
REPEAT-UNTIL Control Structure
The following syntax shows the REPEAT-UNTIL statement.
Copy Code | |
---|---|
REPEAT <Statements> UNTIL <Condition> |
<Statements> is executed repeatedly until <Condition> is TRUE.
The REPEAT UNTIL control structure resembles the WHILE control structure. The difference is that because the REPEAT UNTIL statement is executed from left to right, the <Statements> is always executed at least one time, regardless of what the <Condition> is evaluated to. This contrasts with the WHILE control structure, which performs the evaluation before the <Statement> is executed. In the WHILE control structure, if the first evaluation of <Condition> returns FALSE, then no statements are executed.
Programming Conventions
Always put REPEAT on a separate line.
Example
Copy Code | |
---|---|
IF x < y THEN BEGIN REPEAT x := x + 1; a := a - 1; UNTIL x = y; b := x; END; |
Example
Create the following variables.
Variable | Data type | Subtype |
---|---|---|
Count | Integer |
|
Customer | Record | Customer |
Copy Code | |
---|---|
Count := 0; IF Customer.FIND('-') THEN REPEAT Count := Count + 1; UNTIL Customer.NEXT <= 0; Message(’The Customer table contains %1 records.’,Count); |
This code uses a REPEAT-UNTIL loop to count the number of entries in the Customer table. The FIND function finds the first entry in the table. Each time NEXT is called, it steps one record forward. When NEXT equals 0, there are no more entries in the table. The loop is exited, and a message displays how many entries were found.
EXIT Statement
The EXIT statement is used to control the flow of the execution. The following syntax shows an EXIT statement.
Copy Code | |
---|---|
EXIT([<Value>]) |
An EXIT statement is used to interrupt the execution of a C/AL trigger. The interruption occurs even when the code is executed inside a loop or a similar structure. The EXIT statement is also used when a local function should return a value.
Using EXIT without a parameter in a local function corresponds to using the parameter value 0. The C/AL function will return the value 0 or '' (empty string).
A compile-time error occurs if EXIT is called by using a return parameter from either of the following:
-
System-defined triggers.
-
Local functions that do not return a value.
Example
The following example shows the use of the EXIT statement in a local function. Assume that the IF statement is used to detect an error. If the error condition is met, then execution is stopped and the local function returns the error code 1.
Copy Code | |
---|---|
FOR I := 1 TO 1000 DO BEGIN IF Amount[I] < Total[I] THEN EXIT(1); A[I] := Amount[I] + Total[I]; END; |