[WHERE where_clause[, where_clause]] 
                            [[REVERSE_]SORTBY field_data
                            [ROW_COUNT $variable_name]

table_data is one of the table names in the database (if you have added your own tables, you could choose one of them). END_LOOP marks the end of the set of commands to be repeated once for every row pulled from the table (but only those rows that meet the specified criteria).

where_clause is of the form:

  • field_data IS text_data
  • field_data ISNOT text_data
  • field_data CONTAINS text_data
  • field_data STARTSWITH text_data
  • field_data ENDSWITH text_data
  • field_data ISLESS numeric_data (or date_data)
  • field_data ISLESSOREQUAL numeric_data (or date_data)
  • field_data ISMORE numeric_data (or date_data)
  • field_data ISMOREOREQUAL numeric_data (or date_data)
  • field_data ISMULTIPLEOF numeric_data

field_data is always a field from the new table (the one named in the LOOP command). Normal rules for field names apply (see the FIELD command for details).

text_data is either a piece of literal text (* see below) to compare against (normal rules apply, see the TEXT command for details), or a special form of a field of the form CURRENT.field_data. CURRENT and the dot are required, and indicate that the data should be compared against a field from the current row being examined (i.e., the one in progress before this LOOP command). Once again normal rules for field names apply (see the FIELD command for details). 

Thus, a typical loop might be:

LOOP FROM "Away Talks" WHERE "Brother" ISNOT "J. Samuels"


LOOP FROM "Away Talks" WHERE "Last Given" IS CURRENT."Talk Date"

Note that you can combine multiple WHERE clauses by separating with commas. All such clauses are applied to the current row to determine if it is acceptable, and if not, the next row is fetched and so on, until none are left. Note that you must be prepared for the possibility that no rows at all match the criteria for a LOOP command, and thus it will appear to have no effect.

Any WHERE clauses that cannot be understood are ignored and no attempt is made to apply them to the current row (but any other clauses on the line are still checked).

You can embed inner loops within existing loops. Each LOOP must be matched by an END_LOOP, and all commands between those two commands will be executed for each matching row. However, if an outer loop skips a row because it does not match the criteria, any inner loops will not be executed for that row. This is logical - if the row is not suitable for the outer loop, then it is not suitable for anything within that loop, including inner loops. Once a loop has ended the table it was examining is no longer 'current', and FIELD commands will revert to the outer loop (or nothing if there are no outer loops).

You can optionally sort the order in which rows are processed from this loop by adding SORTBY (increasing order) or REVERSE_SORTBY (decreasing order). 

The NODATERANGE keyword will prevent the loop from using the date range specified when creating the report (or before entering the editor, if editing the script). Note, though, that the date range only applies to Away Talks, Congregations, Home Talks, Public Talk Titles tables - it has no effect on any other table, even ones you may have added. It will be ignored for any other table.

You can optionally save the number of rows in the loop to a user defined variable by adding ROW_COUNT "$variable-name" to the end of the LOOP command. The variable needs to be already defined at the top of the script using REQUIRES. Be careful not to use this row count variable for any other part of the loop command, such as WHERE or SORTBY clauses, otherwise you won’t get the expected results.

Unlike commands such as FONT, the keywords and parameters for the LOOP command, if supplied, must be supplied in the order shown. WHERE clauses obviously can be in any order, though, within their section of the command.

text_data* The text value can also be a variable name, such as $variable. Also, it is important to use valid text if specifying literal text. Depending on the field type, you must follow this set of rules (not that you don't need to worry if you are creating the script through the editor).

Text Field

Text fields have no limitations. Virtually any value is accepted.

Numeric Field

Number fields expect to be numeric. So only use numbers (0 to 9)

Tentative Field

Tentative field is actually a YES/NO field. Use:

  • 0 for YES
  • 1 for NO

Date Field

Date fields must follow a strict pattern: #YYYY MM DD#

For example, given the date "January 4th, 1999", it would be represented with:

#1999 01 04#


(Statement split over multiple physical lines for clarity only)

LOOP FROM "Home Talks" WHERE "Chairman" IS "Chairman 1" SORTBY "Last Given"
    (commands go inside loop)

REQUIRES "Number Home Talks (internal variable)" AS $HomeTalksRowCount VALUES "0"
LOOP FROM "Home Talks" WHERE "Chairman" IS "Chairman 1" 
                       SORTBY "Last Given" ROW_COUNT "$HomeTalksRowCount"
    (commands go inside loop)
TEXT "Number of rows found: $HomeTalksRowCount"