@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(¶m)
...
EndProc
Function Name(¶m) returnType
...
Return expr
EndFunc
Procedure(no return value,subis a synonym): called withDo 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
| Statement | Use |
|---|---|
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("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 toTablefor the whole program (ADDPFM+OVRDBF, before anyopen). InProgram, only at the top level of@Source; inScreen, only at the top level ofEvent Init(see @Source: Event and Screen). At most once per table.Export(Table, destination): copiesTable’s active member to an IFS stream file (CPYTOIMPF, comma-delimited). Only valid inProgram(not inScreen); no position restriction within it.
Return
Return [expr]
Exits a Function (the value is required if you want to honor the declared return type).