Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

@Source: control statements

The imperative body of a Program/Screen: assignments, control flow, table access, Procedure/Function declarations, calls and reports.

For Each In: iterating over a table

For Each In Table [Index IndexName]
[Where Field = expr]...
    // body, runs for each row found
[When None
    // runs if no row was found
]
EndFor
  • Index: optional, picks the access path (defaults to the sequential-access one).
  • Where: zero or more, filters by equality.
  • When None: optional, runs if the loop found no rows.

Delete(): deleting the current row

For Each In Table
    If &Expired
        Delete()
    EndIf
EndFor

No arguments — deletes the row the iteration currently has loaded. Only valid inside a For Each In (not inside a For Each Row, which iterates a DataGridView’s subfile, not a table); valid in both Program and Screen. A deleted row isn’t also updated, even if the body assigned one of its fields earlier in the same iteration.

For Each Row: iterating over a DataGridView

For Each Row
    // body — runs once per row already loaded into the subfile
EndFor

No Index/Where/When None (there’s no table being iterated). Only valid inside any Event of a Screen with a DataGridView. Before each iteration it writes each Column (including Hidden ones) into its bound variable — see DataGridView.

Classic For: counter

For &Variable = start To end [Step increment]
    // body
EndFor

Counts from start to end, incrementing &Variable by increment each time around. Step is optional (default 1); with a negative Step, start must be greater than end to count downward.

Iterating over a List

There’s no For Each over an in-memory list (For Each In is exclusive to database tables, see below). It’s traversed with a classic For, using Count() as the limit and indexing (&Variable[&i]):

For &i = 1 To &List.Count()
    // ... &List[&i] ...
EndFor

See Data types: List for the full syntax of Add/Clear/Remove/Count.

New: inserting a row

New In Table
    Field = expr
    ...
[When Duplicate
    // runs if the insert collides with an existing unique key
]
EndNew

If / While

If condition
    ...
Else
    ...
EndIf

While condition
    ...
EndWhile

condition combines comparisons with And/Or (e.g. &a = 1 And &b = 2 Or &c = 3). And binds tighter than Or (a And b Or c reads as (a And b) Or c).

Procedure / Function

Procedure Name(&param)
    ...
EndProc

Function Name(&param) returnType
    ...
    Return expr
EndFunc
  • Procedure (no return value, sub is a synonym): called with Do Name(expr, ...).
  • Function (with a return value, type required right after the parameter list — same syntax as @Fields/@Variables): called as an expression, &variable = Name(expr, ...), type-checked against &variable.
  • A parameter/return value can be struct(Template) — see Data types: Struct. The argument passed must always be a variable declared with that exact same template (never an expression nor a different template, even if it has the same members).

Call vs Do

StatementUse
Call(Name, expr, ...)Calls an external program or screen (one of @References/Programs or @References/Screens), resolved at compile time.
Call("Name", expr, ...)Calls an external program by name, resolved at runtime.
Do Name(expr, ...)Calls a Procedure from this same file (always an unquoted name).

A Screen referenced in @References/Screens is called with Call(Name, ...) exactly like a Program — typically to show it as a pop-up window (see @Properties). The called Screen can declare @Parameters just like a Program.

Print

Print("BlockName")

Prints an instance of a Block from @Layout — see @Layout. Writes 132-character lines to the QPRINT spool (OVRPRTF + open at the start, close at the end); with Print Mode: Screen the spool is also shown (DSPSPLF) and deleted (DLTSPLF) when the program finishes.

Member / Export: reports with data members

Member(Table, expr)
Export(Table, destination)

See the full guide: Reports with Member()/Export().

  • Member(Table, expr): attaches a data member to Table for the whole program (ADDPFM + OVRDBF, before any open). In Program, only at the top level of @Source; in Screen, only at the top level of Event Init (see @Source: Event and Screen). At most once per table.
  • Export(Table, destination): copies Table’s active member to an IFS stream file (CPYTOIMPF, comma-delimited). Only valid in Program (not in Screen); no position restriction within it.

Return

Return [expr]

Exits a Function (the value is required if you want to honor the declared return type).