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 ]

ParameterDescription
ElementName of the variable used as loop counter.
GroupAny expression evaluating to an iterable object.
StatementsOne 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 Function

Iterating 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 Function

Iterating 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 Sub

Iterating 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 Sub

Iterating 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

SystemMinimal versionRemarks
Palm OSPalm OS 3.0-
Windows CEWindows CE 3.0-