ForAll loops for lists and arrays

The iterative block statement ForAll executes a block of statements repeatedly, once for each element of an array or a list.

The syntax is:

ForAll refVar In container

statements

End ForAll

container names an existing array or list.

After the statements in the body of the ForAll statement are executed for the last element in container, execution continues with the next statement following the ForAll statement. However, execution may continue elsewhere if control passes out of the body of the ForAll statement during execution, via a GoTo, GoSub, Exit, or End statement.

On successive iterations of statements, the reference variable refVar refers in turn to each element in container. The name refVar is declared by its appearance in the ForAll statement. It is not a synonym for the container name itself but an alias for each individual element of the container in turn. On each successive iteration, its data type is the data type of the element of the container.

For example:

Dim persStats List As String     ' Declare list of type String.
persStats("Name") = "Ian"        ' Assign list elements.
persStats("Age") = "36"
persStats("Home state") = "MD"
ForAll idAttrib In persStats    
   Print ListTag(idAttrib)": " idAttrib 
    ' For each item in persStats, print its tag and value.
End ForAll
' Output:
' Name: Ian
' Age: 36
' Home state: MD

This example shows a ForAll statement where the container is an array instead of a list.

Dim numberId(2) As Integer      
For i% = 0 To 2
   numberId(i%) = i% + 1
Next
ForAll p2 In numberId
   Print TypeName(p2) p2 * p2
     ' Print the type and the square of the number
     ' in each element.
End ForAll
' Output:
' INTEGER 1
' INTEGER 4
' INTEGER 9

If an array or a list has no elements, then a ForAll statement with that array or list for a container variable has no effect.

For example:

Dim testNone() As Integer
Print "Before ";
ForAll iTest In testNone
   Print iTest, "In ForAll ";
End ForAll
Print "After"
' Output:
' Before After

Scope of the reference variable

You cannot refer to the reference variable outside the ForAll statement.

For example:

ForAll p2 In numberId
   Print p2 * p2 ;
End ForAll
Print
Print TypeName(p2)
' Output:
' 1  4  9
' Error 115: Illegal reference to FORALL alias variable: P2

You cannot declare a reference variable outside a ForAll statement.

For example:

Dim p2 As Integer
ForAll p2 In numberId
   Print p2 * p2 ;
End ForAll
' Output:
' Error 164: FORALL alias variable was previously declared: P2

You can, however, reuse a reference variable from one ForAll statement as the reference variable in another ForAll statement. The container variable in the second ForAll statement must have the same data type as the container variable in the first ForAll statement. The LotusScript® compiler generates an error if the data types are different. (The container can be an array or a list.)

For example:

ForAll p2 In numberId
   Print p2 * p2 ;
End ForAll
Print
Dim numShiftV(3) As Variant
ForAll p2 In numShiftV
   p2 = 1
End ForAll
' Output:
' 1  4  9
' Error 114: FORALL alias variable is not of same data type: P2

In the example, p2 was implicitly declared as an Integer variable by the statement:

ForAll p2 In numberId

Therefore it cannot be redeclared as a Variant variable, as this statement tries to do:

ForAll p2 in numShiftV

Changing the declared data type of numShiftV to Integer would make the second use of p2 legal.

Modifying container variable elements

This example shows how a ForAll statement references the current value of each element in the container array or list. Statements within the ForAll statement change the current values of the two elements in the container array iHold. The new values are used by subsequent statements in the first iteration of the ForAll statements, and also when the ForAll statements are executed for the next element in iHold.

Dim iHold(1) As Integer
iHold(0) = 50
iHold(1) = 100
ForAll iElem In iHold
   ' Print the values of iElem and iHold(1)
   ' upon each entry into ForAll.
   Print
   Print "iElem and iHold(1) IN:" iElem iHold(1)
   ' Add 2 to the current element. The current element is
   ' iHold(0) the first time through ForAll, and iHold(1)
   ' the second time through.
   iElem = iElem + 2
   ' Increment the value of iHold(1) by 5 (both trips through).
   iHold(1) = iHold(1) + 5
   ' Print the current values of iElem and iHold(1)
   ' upon each exit from ForAll.
   Print "iElem and iHold(1) OUT:" iElem iHold(1)
End ForAll
' Output:
' iElem and iHold(1) IN:  50  100
' iElem and iHold(1) OUT: 52  105
' iElem and iHold(1) IN: 105  105
' iElem and iHold(1) OUT:112  112

To compare how a With statement can perform a similar task, see the description of With in "User-Defined Data Types and Classes."

In this example, the value of an element of the container array cHold is a reference to an object of the class refClass. Initially the two elements of cHold contain different object references. On the first iteration of the ForAll statement, the value of the first element is reset to the value of the second; thereafter, the elements refer to the same object.

Option Base 1
Class refClass
   Public cVar As Integer
End Class
Dim cHold(2) As refClass
Set cHold(1) = New refClass
Set cHold(2) = New refClass
' The output from the following Print statement
' shows that cHold(1) and cHold(2) hold different 
' objects references.
If cHold(1) Is cHold(2) _
   Then Print "Same object" Else Print "Different objects"
cHold(1).cVar% = 100
cHold(2).cVar% = 200
ForAll cElem In cHold
   Print
   Print cElem.cVar%
   Set cHold(1) = cHold(2)
   ' Now cHold(1) holds the same reference as cHold(2), so 
   ' cElem refers to that object in the following statements
   ' (on both trips through ForAll).
   Print cElem.cVar%
   If cHold(1) Is cHold(2) _
      Then Print "Same object" Else Print "Different objects"
End ForAll
' Output:
' Different objects
'
' 100
' 200
' Same object
'
' 200
' 200
' Same object

The two preceding examples change the contents of the container array for the ForAll statement, but not the structure. Although you can use the Erase statement on the container or its elements; or use the ReDim statement on an array, it is not recommended, as the results are unpredictable.

Similarly, it is possible to transfer control from outside a ForAll statement to a labeled statement inside. This is also not recommended, since by doing so you bypass the built-in initialization of the ForAll reference variable that occurs when the ForAll statement begins execution for a particular element.

Element access order

As shown in the first example, a ForAll statement for a list container accesses the list elements in the same order as they are maintained in the list. A ForAll statement for an array accesses the array elements in the order in which LotusScript® stores them. For a one-dimensional array arrA, this is arrA(0), arrA(1), arrA(2), ... (if 0 is the lowest subscript for arrA). LotusScript® stores an array with more dimensions in first-fastestorder (the first subscript in the array subscript list varies fastest). A ForAll statement accesses the array elements in the same order.

For example:

Option Base 1g5
Dim eyeJay(2,3) As String
' Access the elements of eyeJay in "last fastest" order
' for assignment and printing.
For i% = 1 To 2
   For j% = 1 To 3
      ' In eyeJay(i,j), store the string "(i,j)".
      eyeJay(i%, j%) = "(" & Str(i%) & "," & Str(j%) & ")"
      ' Print the element value.
      Print eyeJay(i%, j%),
Next j%, i%
Print
' Now print the elements of eyeJay one at a time in the 
' same order as the ForAll statement accesses them.
' This order is first fastest, the storage order for any array.
Print
ForAll elem In eyeJay
   Print elem,
End ForAll
' Output:  
' ( 1, 1)  ( 1, 2)   ( 1, 3)   ( 2, 1)   ( 2, 2)   ( 2, 3)
' ( 1, 1)  ( 2, 1)   ( 1, 2)   ( 2, 2)   ( 1, 3)   ( 2, 3)