Syntax
FOREACH variable IN <iterator> [ FROM | BACK | EVERY ] [ POLYMORPHIC ] [ SERIAL ] [ SECURE | KEYONLY ] [ MULTI expression ] [ GS status ] <iterator> := <object> | <profile> | extract_file | array | <list attribute> <object> := object_name( argument [ ,...n ] ) <profile> := object_name.profile_name( argument [ ,...n ] )
Parameters
The ForEach logic command is followed by a sequence of logic statements to execute for each iteration. This sequence is terminated by an End, EndExit, or EndNoPrint logic statement.
variable
The instance variable into which each record will be loaded.
IN <iterator>
The set, array, or list attribute to read. This can be a profile, a persistent class, an extract file, an Array, or a list attribute. If a persistent class is specified, records are read using the class's default profile. You can also use an external class with persistent members to read an external data source.
,…n
The key values to read. The following rules apply for key values.
Only Strings are allowed as values for keys defined as strings.
Dates and numeric can be used interchangeably for keys defined as numeric or date.
Only Boolean values are allowed as values for keys defined as Boolean.
Only NationalString values are allowed for keys defined as NationalString (except for Glb.Spaces, Glb.High, LB.HIGH, and Glb.Low that are allowed as values for NationalString keys).
There should be no space between the second qualifier and the brackets containing the parameters.
FROM
Reads records in the profile order, starting from the specified key values.
Note: When an action qualifier is not specified for the ForEach command, From is used as the default action qualifier.
BACK
Reads records in reverse profile order, starting back from the specified key values.
EVERY
Reads records that match the specified key values.
POLYMORPHIC
The Polymorphic option only has an effect in a persistent inheritance hierarchy. If the Polymorphic option is specified, then records are returned which are of the same type or class as first qualifier or any of its sub-classes. If Polymorphic is not specified then only records which are the same type or class as first qualifier is returned.
SERIAL
Increases efficiency by retaining pointers. Refer to Serial for more information.
SECURE
Facilitates record locking of the database in applications that do not force integrity. Refer to Secure for more information.
KEYONLY
The KeyOnly command option is not supported on applications that are deployed to Windows.
For MCP-based systems, refer to KeyOnly.
MULTI records
The Multi command option is not supported on applications that are deployed to Windows or MCP.
GS status
Indicates if there are no records retrieved, using the specified qualifier.
Note: The Polymorphic, Serial, Secure, KeyOnly, and Multi expression parameters are not applicable for external classes with persistent members.
Description
The ForEach logic command iterates through the members of a set. This set can be an array, a set of database records specified by a profile, persistent class, an extract file, or a list attribute.
The ForEach looping construct allows selection of data and iteration over any collection, such as Database records, Extract file records, Array elements, and List attributes. ForEach statement has sufficient flexibility to replace current uses of DETERMINE and the looping (multi-retrieval) forms of LOOK.UP, the DETERMINE and LOOKUP commands
Note: ForEach command does not support MULTI and Group UNTIL option.
Failure behavior
If no records are retrieved (no record satisfies the set criteria), the Glb.Status built-in segment attribute is set to "*****". Use the GS logic command option to direct the Glb.Status built-in segment attribute value to a variable. This is useful in instances where many logic statements might set the Glb.Status built-in segment attribute (for example, within nested ForEach logic statement).
Examples
Example 1
In this example, the ForEach command reads records from the product table, retrieving the records based on the Product ID. The ProductID and ProductName are moved from each retrieved record into a ProductDetail frame and printed.
ForEach Product in Product ProductDetail.ProductID := Product.ProductID ProductDetail.ProductName := Product.ProductName ProductDetail.Print() End If (GLB.STATUS = "*****") Message Attention "No Product records found" End
For this example, output from the report is as follows, in product ID order:
Product ID | Product Name |
---|---|
1 |
Outfit for Dogs |
2 |
Chips for cats |
3 |
Gimborn R-7 |
4 |
KittenCaps |
5 |
Toys for Cats |
6 |
DogBelt |
7 |
CatBathSoap |
8 |
PetOutfit |
9 |
Leather Belt |
10 | ToyPet |
Example 2
This example illustrates the use of the ForEach command to read records from the product table by using a profile called P_ProductName, retrieving the records based on the product name. The ProductID and ProductName are moved from each retrieved record into a ProductDetail frame and printed.
ForEach Product in Product.P_ProductName ProductDetail.ProductID := Product.ProductID ProductDetail.ProductName := Product.ProductName ProductDetail.Print() End If (GLB.STATUS = "*****") Message Attention "No Product records found" End
For this example, output from the report is as follows, in product name order:
Product ID | Product Name |
---|---|
7 |
CatBathSoap |
2 |
Chips for cats |
6 |
DogBelt |
3 |
Gimborn R-7 |
4 |
KittenCaps |
9 |
Leather Belt |
1 |
Outfit for Dogs |
8 |
PetOutfit |
5 |
Toys for Cats |
10 | ToyPet |
Example 3
Using this form of the ForEach command, records containing information about new products are read from a text file. The retrieved data is then used to write new records into the product table.
ProductWriteFile.Open(“New_Products.txt”,ProductWriteFile.ReadMode) ForEach ProductWriteFile.Details in ProductWriteFile Product.ProductID := ProductWriteFile.Details.ProductID Product.ProductName := ProductWriteFile.Details.ProductName Product.UnitPrice := ProductWriteFile.Details.UnitPrice Product.Store() End
Example 4
Using ForEach, the following logic retrieves items from a list and accumulates a total.
ForEach ProductItem in Products Add ProductItem.Stockbal TotalStock End