DataGridView: paginated grids
DataGridView shows a list of rows from a table on a Screen, with native pagination (Page Up/Down) over a DDS subfile. There can only be one per Screen.
1. Full example
@Properties {
Type : Screen
Name : SGRIDDEMO
}
@References {
Tables = ["tables/TLGRIDDEMO.warp"]
}
@Variables {
global {
VCustCode char(6)
VName char(20)
VCity char(15)
VTotal number(5)
VLast char(6)
}
}
@Layout {
DataGridView("GridDemo", 2, 2, 5)
[
Column("Code", &VCustCode)
Column("Name", &VName)
Column("City", &VCity)
]
}
@Source {
Event Load
For Each In GRIDDEMO Index GRIDDMNOM
&VCustCode = CustCode
&VName = Name
&VCity = City
LoadRow()
EndFor
EndEvent
Event Enter
&VTotal = 0
For Each Row
&VTotal = &VTotal + 1
&VLast = &VCustCode
EndFor
Message("Rows: " + String(&VTotal, 5) + " Last: " + &VLast, Info)
EndEvent
}
Between two contiguous visible columns there is always at least one free position (the separator, if declared; otherwise a space). This counts toward the E00353 width calculation: see Available width and error E00353.
2. Loading the grid: Event Load + LoadRow()
LoadRow() takes the current values of the variables bound to each Column and appends a row to the grid. It is valid anywhere in the body of any Event of a Screen — directly, inside If, Case, While, For or For Each — so it can also load the grid with data that does not come from a table. A For Each that loads the grid must declare Index (E00201). There can be several loads in the same event: all of them append rows to the same grid. In Event Load the grid is reset only once, when the event starts; in any other Event or Procedure the rows are appended to the ones already there. It loads the entire result set in a single pass — Page Up/Down are native terminal scrolling over what’s already loaded; Load never runs again.
LoadRow() can also be used inside any Procedure of the Screen, regardless of where it is invoked from (with Do). A Function cannot use LoadRow(), and it cannot be used outside an Event or Procedure either (E00198).
Event Load
Do Carga()
EndEvent
Procedure Carga()
For &Indice = 1 To 5
&VCod = &Indice
&VNombre = "Item " + String(&Indice, 3)
LoadRow()
EndFor
EndProc
A Procedure with LoadRow() can also be called from another event. Here Enter appends rows to the ones Load already loaded (and F5/Refresh runs Load again, which resets the grid):
Event Enter
Do AddRows()
EndEvent
Procedure AddRows()
&VCod = 99
&VNombre = "Added row"
LoadRow()
EndProc
Or directly in the event, with no procedure and no table:
Event Load
&VCod = 1
&VNombre = "First"
LoadRow()
&VCod = 2
&VNombre = "Second"
LoadRow()
EndEvent
Related rule: a local variable with the same name as a Column variable shadows the global one (LoadRow() would copy the local value), error E00356. See Diagnostics.
3. Reading the selection: RefreshSelectRow() and CurrentInput()
When the cursor lands inside the grid’s rectangle (header, attention row, or any data row), CurrentInput() returns the grid’s name. RefreshSelectRow() re-reads the row under the cursor and writes each column (including Hidden ones) back into its bound variable — it’s the reverse of LoadRow(). This is how to recover the value of a Hidden column: those columns travel in the subfile record as hidden fields (usage H in the DDS), with no line or position on the screen:
Event Enter
&Control = CurrentInput()
If &Control = "GridDemo"
RefreshSelectRow()
Message("You selected: " + &VCustCode, Info)
EndIf
EndEvent
4. Iterating over all loaded rows: For Each Row
For Each Row ... EndFor iterates over all rows already loaded into the subfile (not the database table), writing each Column into its bound variable before every iteration — same direction as RefreshSelectRow(). It doesn’t support Index/Where/When None because there’s no table being iterated:
Event Enter
&VTotal = 0
For Each Row
&VTotal = &VTotal + 1
EndFor
EndEvent
5. Hidden columns
Column("Internal ID", &VInternalId, Hidden)
A Hidden column loads its data (participates in LoadRow()/RefreshSelectRow()/For Each Row) but doesn’t show its cell or header title — useful for carrying an internal key without taking up screen space.
6. Editable columns (Input)
Column("Quantity", &VQuantity, Input)
Lets the user edit the value directly in the grid.
Reloading the grid: Refresh and Refresh Keep
To run Event Load again (for example, after changing a filter) use Refresh (goes back to the first row) or Refresh Keep (keeps the row where the user was). The reload happens when the current event ends. F5, if declared in @FunctionKeys, runs Event Refresh and then reloads the grid. See Refresh and Refresh Keep.
7. Rules to keep in mind
- The name (
"GridDemo") is required and must be unique amongInput/DataGridViewcontrols on the same screen. - Only one
DataGridViewperScreen. - Only valid inside a
Screen’s@Layout, never aProgram’s.