Home > Language Reference > Statements
For Each...Next Statement
Repeats a group of statements for each element in a container object, such as a Collection or an array.
Syntax
For Each Element In Group
[ Statements ]
Next [ Element ]
| Parameter | Description |
| Element | Name of the variable used as loop counter. |
| Group | Any expression evaluating to an iterable object. |
| Statements | One or more statements. |
Remarks
The Group argument is evaluated once, before the loop is entered. It must return an iterable object, which can be a string, an array, a Collection, a RecordDB, a ResourceDB, or any user defined object that provides an handler for the Iterate event. Then, the statements in the loop are executed once for each element returned by the iterator. When items are exhausted (which happens immediately if the sequence is empty), the loop terminates and control is transfered to the first statement following the Next keyword.
The Element parameter must be the name of the variable which will be used as loop counter. It cannot be a qualified name such as MyClass.MyVariable, neither it can be an element of an array such as MyArray(12). As each enumerated element will be affected in turn to this variable, its type must be compatible with all of these elements. If the iterated object contains unrelated data types, such as Boolean and Date, the Element argument must be declared as a Variant.
It is possible to exit a For Each loop using the Exit For statement. It is often placed after an evaluation of a condition (If...Then for example) ; it passes control to the instruction following the Next keyword. Several For Each...Next loops can be nested, but depending on how the object implements the enumeration logic, enumerating the content of an object that is already being enumerated may lead to unpredictable results.
The HB++ language also provides other loop statements. Refer to the For...Next and While...Wend statements for more information.
Iterating over a string
If the Group argument evaluates to a string, the For Each...Next statement enumerates each character in this string, in the order they appear. The Element argument must be numeric, such as Byte or Double, as it will be affected the ANSI code of each character. Note that this code may be greater than 255 on Far East devices, therefore you should always use at least an Integer.
The following example computes the checksum of a string:
Public Function CheckSum(ByRef sText As String) As Integer
Dim b As Integer, r As Integer
For Each b In sText
r = r + b
Next
CheckSum = r
End FunctionIterating over a string is reentrant: enumerating characters of a string that is already involved into another loop behaves as expected.
Iterating over an array
If the Group argument evaluates to an array, the For Each...Next statement enumerates each elements in this array, following the order of the array indices. The Element argument must be compatible with the type of the array. For example, you can iterate over an array of integers using a Single or a String loop variable, but not using a Boolean loop variable.
The following example computes the average value of the elements of an array:
Public Function Average(ByRef Arr() As Double) As Double
Dim e As Double, r As Double, i As Integer
For Each e In Arr
r = r+e
i = i+1
Next
Average = r/i
End FunctionIterating over an array is reentrant: enumerating elements of an array that is already involved into another loop behaves as expected.
Iterating over a Collection
If the Group argument evaluates to a Collection, the For Each...Next statement enumerates each elements in this collection, in the order they were inserted. The Element argument must be compatible with the type of all the elements in the collection.
The following example shows how to use a collection to store, and then fill a list control with the names and creator of all the applications on the handheld device:
Private Sub Button1_Click()
Dim di As New DatabaseInfo
Dim c as New Collection
Dim found as Boolean
found = di.FindFirstByTypeCreator("appl","")
While found
c.Add Clone(di)
found = di.FindNext
Wend
For Each di in c
List1.AddItem di.Name & "(" & di.Creator & ")"
Next di
End SubIterating over a collection is not reentrant: enumerating elements of a collection that is already involved into another loop leads to unpredictable results.
Iterating over a database
If the Group argument evaluates to a RecordDB or a ResourceDB object, the For Each...Next statement enumerates each record or resource of this database, in the order they appear. The Element argument must be compatible with the StreamRecord class. In other words, it can be either as a Stream, a StreamMemory, or a StreamRecord object.
The following example fills a list with the resources found in the application itself:
Private Sub Button1_Click()
Dim rec As StreamRecord
List1.Redraw=False
List1.Clear
For Each rec In App
List1.AddItem rec.ResType & " " & rec.ResID
Next
List1.Redraw=True
End SubIterating over a database is reentrant: enumerating records of a database that is already involved into another loop behaves as expected.
Iterating over user defined objects
No other HB++ predefined object is iterable, but you can make your own classes iterable, by allowing them to process the Iterate event. For more information about this mechanism, please refer to the Iterable Objects section in the Programmer's Guide.
System requirements
| System | Minimal version | Remarks |
| Palm OS | Palm OS 3.0 | - |
| Windows CE | Windows CE 3.0 | - |