4D v13.4

For...End for

Home

 
4D v13.4
For...End for

For...End for  


 

 

The formal syntax of the For...End for control flow structure is:

 For(Counter_Variable;Start_Expression;End_Expression{;Increment_Expression})
    statement(s)
 End for

The For...End for loop is a loop controlled by a counter variable:

  • The counter variable Counter_Variable is a numeric variable (Real, Integer, or Long Integer) that the For...End for loop initializes to the value specified by Start_Expression.
  • Each time the loop is executed, the counter variable is incremented by the value specified in the optional value Increment_Expression. If you do not specify Increment_Expression, the counter variable is incremented by one (1), which is the default.
  • When the counter variable passes the End_Expression value, the loop stops.

Important: The numeric expressions Start_Expression, End_Expression and Increment_Expression are evaluated once at the beginning of the loop. If these expressions are variables, changing one of these variables within the loop will not affect the loop.

Tip: However, for special purposes, you can change the value of the counter variable Counter_Variable within the loop; this will affect the loop.

  • Usually Start_Expression is less than End_Expression.
  • If Start_Expression and End_Expression are equal, the loop will execute only once.
  • If Start_Expression is greater than End_Expression, the loop will not execute at all unless you specify a negative Increment_Expression. See the examples.

1. The following example executes 100 iterations:

 For(vCounter;1;100)
  ` Do something
 End for

2. The following example goes through all elements of the array anArray:

 For($vlElem;1;Size of array(anArray))
  ` Do something with the element
    anArray{$vlElem}:=...
 End for

3. The following example goes through all the characters of the text vtSomeText:

 For($vlChar;1;Length(vtSomeText))
  ` Do something with the character if it is a TAB
    If(Character code(vtSomeText$vlChar≥)=Tab)
  ` ...
    End if
 End for

4. The following example goes through the selected records for the table [aTable]:

 FIRST RECORD([aTable])
 For($vlRecord;1;Records in selection([aTable]))
  ` Do something with the record
    SEND RECORD([aTable])
  ` ...
  ` Go to the next record
    NEXT RECORD([aTable])
 End for

Most of the For...End for loops you will write in your databases will look like the ones listed in these examples.

In some cases, you may want to have a loop whose counter variable is decreasing rather than increasing. To do so, you must specify Start_Expression greater than End_Expression and a negative Increment_Expression. The following examples do the same thing as the previous examples, but in reverse order:

5. The following example executes 100 iterations:

 For(vCounter;100;1;-1)
  ` Do something
 End for

6. The following example goes through all elements of the array anArray:

 For($vlElem;Size of array(anArray);1;-1)
  ` Do something with the element
    anArray{$vlElem}:=...
 End for

7. The following example goes through all the characters of the text vtSomeText:

 For($vlChar;Length(vtSomeText);1;-1)
  ` Do something with the character if it is a TAB
    If(Character code(vtSomeText$vlChar≥)=Tab)
  ` ...
    End if
 End for

8. The following example goes through the selected records for the table [aTable]:

 LAST RECORD([aTable])
 For($vlRecord;Records in selection([aTable]);1;-1)
  ` Do something with the record
    SEND RECORD([aTable])
  ` ...
  ` Go to the previous record
    PREVIOUS RECORD([aTable])
 End for

If you need to, you can use an Increment_Expression (positive or negative) whose absolute value is greater than one.

9. The following loop addresses only the even elements of the array anArray:

 For($vlElem;2;Size of array(anArray);2)
  ` Do something with the element #2,#4...#2n
    anArray{$vlElem}:=...
 End for

In some cases, you may want to execute a loop for a specific number of iterations, but then get out of the loop when another condition becomes TRUE. To do so, you can test this condition within the loop and if it becomes TRUE, explicitly set the counter variable to a value that exceeds the end expression.

10. In the following example, a selection of the records is browsed until this is actually done or until the interprocess variable <>vbWeStop, intially set to FALSE, becomes TRUE. This variable is handled by an ON EVENT CALL project method that allows you to interrupt the operation:

 <>vbWeStop:=False
 ON EVENT CALL("HANDLE STOP")
  ` HANDLE STOP sets <>vbWeStop to True if Ctrl-period (Windows) or Cmd-Period (Macintosh) is pressed
 $vlNbRecords:=Records in selection([aTable])
 FIRST RECORD([aTable])
 For($vlRecord;1;$vlNbRecords)
  ` Do something with the record
    SEND RECORD([aTable])
  ` ...
  ` Go to the next record
    If(<>vbWeStop)
       $vlRecord:=$vlNbRecords+1 ` Force the counter variable to get out of the loop
    Else
       NEXT RECORD([aTable])
    End if
 End for
 ON EVENT CALL("")
 If(<>vbWeStop)
    ALERT("The operation has been interrupted.")
 Else
    ALERT("The operation has been successfully completed.")
 End if

Let's go back to the first For...End for example:

The following example executes 100 iterations:

 For(vCounter;1;100)
  ` Do something
 End for

It is interesting to see how the While...End while loop and Repeat...Until loop would perform the same action.

Here is the equivalent While...End while loop:

 $i :=1 ` Initialize the counter
 While($i<=100) ` Loop 100 times
  ` Do something
    $i :=$i +1 ` Need to increment the counter
 End while

Here is the equivalent Repeat...Until loop:

 $i :=1 ` Initialize the counter
 Repeat
  ` Do something
    $i :=$i +1 ` Need to increment the counter
 Until($i=100) ` Loop 100 times

Tip: The For...End for loop is usually faster than the While...End while and Repeat...Until loops, because 4D tests the condition internally for each cycle of the loop and increments the counter. Therefore, use the For...End for loop whenever possible.

You can use Real, Integer, and Long Integer variables as well as interprocess, process, and local variable counters. For lengthy repetitive loops, especially in compiled mode, use local Long Integer variables.

11. Here is an example:

 C_LONGINT($vlCounter` use local Long Integer variables
 For($vlCounter;1;10000)
  ` Do something
 End for

You can nest as many control structures as you (reasonably) need. This includes nesting For...End for loops. To avoid mistakes, make sure to use different counter variables for each looping structure.

Here are two examples:

12. The following example goes through all the elements of a two-dimensional array:

 For($vlElem;1;Size of array(anArray))
  ` ...
  ` Do something with the row
  ` ...
    For($vlSubElem;1;Size of array(anArray{$vlElem}))
  ` Do something with the element
       anArray{$vlElem}{$vlSubElem}:=...
    End for
 End for

13. The following example builds an array of pointers to all the date fields present in the database:

 ARRAY POINTER($apDateFields;0)
 $vlElem:=0
 For($vlTable;1;Get last table number)
    If(Is table number valid($vlTable))
       For($vlField;1;Get last field number($vlTable))
          If(Is field number valid($vlTable;$vlField))
             $vpField:=Field($vlTable;$vlField)
             If(Type($vpField->)=Is Date)
                $vlElem:=$vlElem+1
                INSERT IN ARRAY($apDateFields;$vlElem)
                $apDateFields{$vlElem}:=$vpField
             End if
          End for
       End for

 
PROPERTIES 

Product: 4D
Theme: Language definition

 
SEE ALSO 

Case of...Else...End case
Control Flow
If...Else...End if
Repeat...Until
While...End while