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

DataGridView: grillas paginadas

DataGridView muestra una lista de filas de una tabla en un Screen, con paginación nativa (Page Up/Down) sobre un subfile DDS. Sólo puede haber uno por Screen.

1. Ejemplo completo

@Properties {
    Type : Screen
    Name : SGRIDDEMO
}
@References {
    Tables = ["tables/TLGRIDDEMO.warp"]
}
@Variables {
    global {
        VCodCli  char(6)
        VNombre  char(20)
        VCiudad  char(15)
        VTotal   number(5)
        VUltimo  char(6)
    }
}
@Layout {
    DataGridView("GridDemo", 2, 2, 5)
    [
        Column("Codigo", &VCodCli)
        Column("Nombre", &VNombre)
        Column("Ciudad", &VCiudad)
    ]
}
@Source {
    Event Load
        For Each In GRIDDEMO Index GRIDDMNOM
            &VCodCli = CodCli
            &VNombre = Nombre
            &VCiudad = Ciudad
            LoadRow()
        EndFor
    EndEvent

    Event Enter
        &VTotal = 0
        For Each Row
            &VTotal = &VTotal + 1
            &VUltimo = &VCodCli
        EndFor
        Message("Filas: " + String(&VTotal, 5) + " Ultimo: " + &VUltimo, Info)
    EndEvent
}

Entre dos columnas visibles contiguas siempre queda al menos una posición libre (el separador, si se declara; si no, un espacio). Esto cuenta para el cálculo de ancho de E00353: ver Ancho disponible y error E00353.

2. Cargar la grilla: Event Load + LoadRow()

LoadRow() toma los valores actuales de las variables atadas a cada Column y agrega una fila a la grilla. Es válido en cualquier lugar del cuerpo de cualquier Event de un Screen —directo, dentro de If, Case, While, For o For Each—, de modo que también sirve para cargar la grilla con datos que no vienen de una tabla. Un For Each que cargue la grilla debe declarar Index (E00201). Puede haber varias cargas en el mismo evento: todas agregan filas a la misma grilla. En Event Load la grilla se reinicia una sola vez, al entrar al evento; en cualquier otro Event o Procedure las filas se agregan a las que ya hay. Carga todo el resultado en una sola pasada — Page Up/Down son scroll nativo del terminal sobre lo ya cargado; Load nunca vuelve a correr.

LoadRow() también se puede usar dentro de cualquier Procedure del Screen, sin importar desde dónde se invoque (con Do). Una Function no puede usar LoadRow(), ni tampoco puede usarse fuera de un Event o Procedure (E00198).

Event Load
    Do Carga()
EndEvent

Procedure Carga()
    For &Indice = 1 To 5
        &VCod    = &Indice
        &VNombre = "Item " + String(&Indice, 3)
        LoadRow()
    EndFor
EndProc

Una Procedure con LoadRow() también puede llamarse desde otro evento. Aquí Enter agrega filas a las que Load ya cargó (y F5/Refresh vuelve a correr Load, que reinicia la grilla):

Event Enter
    Do AgregaFilas()
EndEvent

Procedure AgregaFilas()
    &VCod    = 99
    &VNombre = "Fila agregada"
    LoadRow()
EndProc

Y directo en el evento, sin procedimiento ni tabla:

Event Load
    &VCod    = 1
    &VNombre = "Primero"
    LoadRow()
    &VCod    = 2
    &VNombre = "Segundo"
    LoadRow()
EndEvent

Regla relacionada: una variable local con el mismo nombre que la variable de una Column tapa a la global (LoadRow() copiaría el valor local), error E00356. Ver Diagnósticos.

3. Leer la selección: RefreshSelectRow() y CurrentInput()

Cuando el cursor cae dentro del rectángulo de la grilla (encabezado, fila de atención o cualquier fila de datos), CurrentInput() devuelve el nombre de la grilla. RefreshSelectRow() relee la fila bajo el cursor y escribe cada columna (incluidas las Hidden) de vuelta en su variable atada — es la inversa de LoadRow(). Es la forma de recuperar el valor de una columna Hidden: esas columnas viajan en el registro del subfile como campos ocultos (uso H en el DDS), sin línea ni posición en pantalla:

Event Enter
    &Control = CurrentInput()
    If &Control = "GridDemo"
        RefreshSelectRow()
        Message("Seleccionaste: " + &VCodCli, Info)
    EndIf
EndEvent

4. Recorrer todas las filas cargadas: For Each Row

For Each Row ... EndFor recorre todas las filas ya cargadas en el subfile (no la tabla de base de datos), escribiendo cada Column en su variable atada antes de cada iteración — misma dirección que RefreshSelectRow(). No admite Index/Where/When None porque no hay tabla que recorrer:

Event Enter
    &VTotal = 0
    For Each Row
        &VTotal = &VTotal + 1
    EndFor
EndEvent

5. Columnas ocultas (Hidden)

Column("ID Interno", &VIdInterno, Hidden)

Una columna Hidden carga su dato (participa en LoadRow()/RefreshSelectRow()/For Each Row) pero no muestra la celda ni el título de su encabezado — útil para llevar una clave interna sin ocupar espacio en pantalla.

6. Columnas editables (Input)

Column("Cantidad", &VCantidad, Input)

Permite que el usuario edite el valor directamente en la grilla.

Recargar la grilla: Refresh y Refresh Keep

Para volver a ejecutar Event Load (por ejemplo, tras cambiar un filtro) usa Refresh (vuelve a la primera fila) o Refresh Keep (conserva la fila donde estaba el usuario). La recarga ocurre al terminar el evento actual. F5, si está declarada en @FunctionKeys, ejecuta Event Refresh y luego recarga la grilla. Ver Refresh y Refresh Keep.

7. Reglas a tener en cuenta

  • El nombre ("GridDemo") es obligatorio y único entre Input/DataGridView de la misma pantalla.
  • Sólo un DataGridView por Screen.
  • Sólo válido dentro de @Layout de un Screen, nunca de un Program.