PBToolboxAI v4 ← Site

datagrid — u_pbt_datagrid #

← Riferimento dei componenti · Sommario della guida

La griglia moderna di un DataStore: colonne tipizzate e celle ricche, ordinamento, filtri, raggruppamento con subtotali, modifica sul posto, paginazione, sorgente a finestra ed esportazione CSV — il DataWindow resta il padrone dei suoi dati.

▶ Vederlo dal vivo — Applicazione dimostrativa, riquadro Data grid: l'anteprima, il codice che lo produce e questa pagina, affiancati.


In breve #

Userobjectu_pbt_datagrid
Classe degli itemn_pbt_datagrid_column — una colonna, raggiunta con of_column
Serve perPresentare un DataStore in una griglia moderna — ordinamento, filtri, raggruppamenti, modifica, volumi molto grandi — senza lasciare il suo DataWindow
Limite in modalità demo100 righe visualizzate; esportazioni CSV ed Excel disattivate — vedere la modalità demo

Il posizionamento #

Il datagrid non sostituisce la DataWindow: è uno strato di presentazione che si sovrappone ad essa. Lei mantiene il Suo SQL, i Suoi Retrieve(), i Suoi Update(), le Sue stampe — e guadagna una griglia moderna per la visualizzazione.

Punta a due punti ciechi della griglia DataWindow classica:

Il collegamento alla base dati e l'aggiornamento restano fuori perimetro: appartengono alla DataWindow.

Il DataStore degli esempi #

Tutti gli esempi di questa pagina — come quelli dell'applicazione dimostrativa — partono dallo stesso DataStore di conti clienti, una riga per conto: city, rep (il commerciale), status, pipeline (una percentuale), trend (sette cifre mensili scritte "3,5,2,6,7,4,8"), revenue e rating (un voto su cinque). La griglia si chiama uo_grid nella finestra, il DataStore ids. Una riga caricata da of_from_datastore ha come chiave il suo RowID nel DataStore: non cambia quando il DataStore ordina, filtra, inserisce o elimina. Un event glielo restituisce, e ids.GetRowFromRowId(Long(as_key)) è il numero della riga che designa adesso.

Un DataStore contiene solo valori semplici, e basta per le celle ricche: un numero è tutto ciò che serve a un indicatore (RENDERER_PROGRESS) e alle stelle (RENDERER_RATING), un nome dà un avatar, un testo "3,5,2,6" un mini grafico (RENDERER_SPARKLINE) come "vip, b2b" delle etichette (RENDERER_TAGS); il colore di un chip (RENDERER_CHIP) si dà per valore con is_tones.


Avvio rapido #

// open event of the window : the accounts, retrieved the way your application already does
ids = create datastore
ids.dataobject = "d_accounts"
ids.SetTransObject(SQLCA)
ids.Retrieve()

// 1. The grid reads the columns (typed) and every row of the DataStore
uo_grid.of_from_datastore(/*ads*/ ids)

// 2. The titles are the header texts of the DataWindow ; rename one if you like
uo_grid.of_column(/*key*/ "rep").is_title = "Account manager"

// 3. Rich cells : an avatar, a coloured status, a gauge, a mini chart, stars
uo_grid.of_column(/*key*/ "rep").is_renderer = n_pbt_datagrid_column.RENDERER_AVATAR
uo_grid.of_column(/*key*/ "status").is_renderer = n_pbt_datagrid_column.RENDERER_CHIP
uo_grid.of_column(/*key*/ "status").is_tones = "Active=" + n_pbt_datagrid_column.TONE_SUCCESS + "|At risk=" + n_pbt_datagrid_column.TONE_DANGER
uo_grid.of_column(/*key*/ "pipeline").is_renderer = n_pbt_datagrid_column.RENDERER_PROGRESS
uo_grid.of_column(/*key*/ "trend").is_renderer = n_pbt_datagrid_column.RENDERER_SPARKLINE
uo_grid.of_column(/*key*/ "rating").is_renderer = n_pbt_datagrid_column.RENDERER_RATING

// 4. A total, and the city stays in view
uo_grid.of_column(/*key*/ "revenue").is_summary = n_pbt_datagrid_column.SUMMARY_SUM
uo_grid.of_column(/*key*/ "city").is_pin = n_pbt_datagrid_column.PIN_START
// ue_row_clicked event of uo_grid : (string as_key)
// The key of a row loaded by of_from_datastore is its RowID : GetRowFromRowId gives
// the row it designates now, even after a sort or a delete in the DataStore.
wf_open_account(ids.GetRowFromRowId(Long(as_key)))

Proprietà #

ProprietàTipoPredefinitoRuolo
is_selection_modestringSELECT_NONEModalità di selezione: nessuna, una riga, più righe (Maiusc = intervallo, Ctrl = commuta)
is_densitystringDENSITY_COMFORTABLEAltezza di riga: comoda o compatta
is_quick_filterstring""Filtro rapido globale: mantiene solo le righe il cui testo — come visualizzato (22/09/2026, 1.234,50) o grezzo — contiene questo valore. Ciò che l'utente digita attende la fine della digitazione; nascosto con una sorgente a finestra
ib_filter_rowbooleanfalseMostra la riga di immissione del filtro sotto le intestazioni (equivalente del pulsante Filtri)
ib_context_menubooleantrueMenu contestuale integrato su una riga: Copia, Seleziona tutto, Cancella selezione, Esporta in CSV, oltre alle sue voci (of_add_row_menu_item). Attivo per impostazione predefinita. Un clic destro fuori dalla selezione la sposta sulla riga mirata, un clic destro dentro la conserva. A false per mostrare il suo menu da ue_row_rclicked
ib_veto_editsbooleanfalseChiede prima di conservare un valore immesso: solleva ue_cell_editing, che può rifiutare — la cella mantiene allora il suo vecchio valore
ib_write_backbooleanfalseScrive ogni immissione nel DataStore passato a of_from_datastore — SetItem sulla riga che la chiave designa (il suo RowID, ritrovato dov'è), tipizzato dalla colonna (date, numeri, testo, codici) — prima di ue_cell_edited. L'Update resta a Lei; una data o un numero svuotati diventano NULL, e un valore che il DataStore non può conservare (una riga eliminata nel frattempo, un valore rifiutato da SetItem, un testo che non è un'ora) non viene conservato: la cella riprende ciò che il DataStore contiene, ue_write_back_failed dice perché, e ue_cell_edited non viene sollevato. SetItem non applica la regola Validation della colonna: verifichi un valore in ue_cell_editing (ib_veto_edits)
ib_detail_on_demandbooleanfalseDettaglio su richiesta: ogni riga mostra la sua freccia, e aprirla (la freccia, o of_expand_row) solleva ue_detail_needed — vi riempia il pannello con of_fill_detail, si apre al ritorno dell'evento. Nulla di riempito: la riga resta chiusa. Il dettaglio di 5.000 righe non viene mai letto in anticipo
is_group_bystring""Raggruppa le righe per una o più colonne, in ordine, le loro chiavi unite da | ("status|city"); ogni intestazione di gruppo porta i subtotali delle colonne che hanno un totale. "" torna a un elenco piatto. Riletta dal vivo
ii_page_sizeinteger100Numero di righe per pagina, una volta attivata la paginazione
il_page_thresholdlong50000Numero di righe oltre il quale la griglia passa alle pagine. 0 = paginare sempre, qualunque sia il volume
is_theme_stylestring""Stile visivo del componente (costanti THEME_STYLE_*); vuoto = quello dell'applicazione, seguito a ogni cambio
is_theme_modestring""Variante chiara o scura (costanti THEME_MODE_*); vuoto = quella dell'applicazione, seguita a ogni cambio
il_theme_accentlong-1Colore d'accento di questo componente (-1 = accento dell'applicazione, o quello del tema)
is_tooltipstring""Tooltip semplice mostrato al passaggio del mouse sul componente
is_super_tooltip_titlestring""Titolo del tooltip avanzato (prevale su is_tooltip)
is_super_tooltip_textstring""Testo del tooltip avanzato (markup avanzato accettato)
is_super_tooltip_imagestring""Immagine del tooltip avanzato

Proprietà di colonna #

Ogni colonna è un oggetto a sé stante, ottenuto con of_column("identificatore") — l'handle viene creato al primo accesso e resta valido in seguito.

// A column is reached by its key ; used once, it fits on one line
uo_grid.of_column(/*key*/ "amount").is_summary = n_pbt_datagrid_column.SUMMARY_SUM
uo_grid.of_column(/*key*/ "city").is_pin = n_pbt_datagrid_column.PIN_START
ProprietàTipoPredefinitoRuolo
is_titlestringla chiaveTesto d'intestazione della colonna; "" rimostra la chiave. of_from_datastore lascia i nomi di colonna del DataWindow: li nomini qui per l'utente
is_tonesstring""Colore di un chip (RENDERER_CHIP) secondo il suo valore, per il testo di un DataStore: coppie valore=tono unite da | ("Active=success|At risk=danger"), toni TONE_*; un valore non elencato resta neutro
ii_widthintegerlarghezza dichiarataLarghezza della colonna, in pixel
ib_hiddenbooleanfalseNasconde o mostra di nuovo la colonna
is_pinstringPIN_NONEBlocca la colonna a sinistra o a destra: resta visibile durante lo scorrimento orizzontale
ib_editablebooleanfalseConsente l'immissione: doppio clic, digitazione, Invio conferma, Esc annulla → ue_cell_edited. Un valore che non si addice alla colonna (lettere in un numero) viene mostrato come rifiutato durante la digitazione, e Invio lascia l'editor aperto. Una colonna booleana mostra una vera casella di controllo: un clic, Spazio, Invio o F2 la inverte subito. Digitare un carattere su una cella di testo o numero apre l'editor con quel carattere; durante una modifica, Tab e Maiusc+Tab conservano il valore e aprono la cella modificabile successiva (precedente)
is_summarystringSUMMARY_NONETotale a piè di colonna; SUMMARY_NONE lo rimuove. SUMMARY_COUNT conta le celle che hanno un valore, come count() di un DataWindow
is_rendererstringRENDERER_NONECella ricca applicata a posteriori; RENDERER_NONE torna al testo. RENDERER_BOOL mostra un segno di spunta per un valore vero; RENDERER_CUSTOM legge il valore come testo ricco a tag — per una colonna che il Suo codice compone: un valore digitato da un utente deve avere le parentesi quadre protette ([[ ]])
ii_indexintegerordine di dichiarazionePosizione della colonna (prima posizione = 1); una colonna che la griglia non contiene si rilegge 0
is_filterstring""Filtro per colonna. Il testo viene cercato in ciò che la cella mostra (data formattata, numero con maschera) o nel suo valore grezzo; su una colonna numerica viene riconosciuto un operatore iniziale ("> 1000", "<= 50", "> 1,5" con il separatore decimale della lingua), su una colonna data anche ("> 22/09/2026", nell'ordine della lingua, o ISO). Stringa vuota = filtro rimosso
is_formatstring""Formato di visualizzazione, nella sintassi della DataWindow: "#,##0.00", "$#,##0;($#,##0)", "0.0%", "dd/mm/yyyy", "mmmm d, yyyy", "hh:mm", "@@@-@@@@". Come in una DataWindow, la virgola e il punto indicano i separatori della lingua. Stringa vuota = torna il formato della DataWindow; si rilegge (il formato in vigore)

Costanti #

Usi sempre le costanti anziché le stringhe letterali: l'IDE le completa e un errore di battitura diventa impossibile.

FamigliaCostantiPortate da
Tipo di colonnaTYPE_STRING, TYPE_NUMBER, TYPE_INT, TYPE_DATE, TYPE_DATETIME, TYPE_BOOLil componente (of_add_column)
Cella riccaRENDERER_AVATAR, RENDERER_CHIP, RENDERER_PROGRESS, RENDERER_SPARKLINE, RENDERER_RATING, RENDERER_TAGS, RENDERER_BUTTON, RENDERER_LINK, RENDERER_BOOL, RENDERER_CUSTOMil componente e l'handle di colonna (is_renderer)
Cella ricca: nessunaRENDERER_NONEsolo l'handle di colonna (is_renderer)
Tono del chipTONE_SUCCESS, TONE_WARN, TONE_DANGER, TONE_INFO, TONE_NEUTRALl'handle di colonna (is_tones)
Modalità di selezioneSELECT_NONE, SELECT_SINGLE, SELECT_MULTIPLEil componente (is_selection_mode)
DensitàDENSITY_COMFORTABLE, DENSITY_COMPACTil componente (is_density)
Totale a piè di paginaSUMMARY_NONE, SUMMARY_SUM, SUMMARY_AVG, SUMMARY_MIN, SUMMARY_MAX, SUMMARY_COUNTl'handle di colonna (is_summary)
Lato di bloccoPIN_NONE, PIN_START, PIN_END (logici: START = bordo d'inizio della lettura)l'handle di colonna (is_pin)

Le costanti si leggono sull'oggetto che le porta: u_pbt_datagrid.SELECT_MULTIPLE per una proprietà del componente, n_pbt_datagrid_column.PIN_START per una proprietà di colonna.


Metodi #

Alimentare la griglia #

MetodoRuolo
of_from_datastore (datastore ads)Il ponte DataStore: legge le colonne (nome + tipo PowerBuilder, tipizzazione automatica) e trasferisce tutte le righe in una sola chiamata, con ciò che il DataWindow dice di ogni colonna — il suo testo d'intestazione diventa il titolo, il suo formato di visualizzazione si applica, e una tabella dei codici (Values, DropDown DataWindow, CheckBox) mostra il valore visualizzato mentre la riga conserva il dato. Le colonne arrivano nell'ordine in cui il DataWindow le mostra (la loro X), e una colonna nascosta nel painter (Visible = 0) arriva nascosta: l'utente la rimostra dal pulsante Colonne. Un campo calcolato non è una colonna del DataStore: non arriva; una DropDown DataWindow il cui figlio non ha righe mostra i codici. La richiami dopo un Retrieve: le colonne conservano ciò che vi è stato impostato (titolo, cella ricca, blocco, larghezza, totale) e il loro posto, ciò che il DataWindow dice (intestazione, formato, tabella dei codici) viene riletto, e ogni valore arriva sotto la propria colonna, qualunque ordine l'utente abbia dato loro. La chiave di ogni riga è il suo RowID: non cambia quando il DataStore ordina, filtra, inserisce o elimina, e ids.GetRowFromRowId(Long(as_key)) è la riga che designa adesso. Restituisce 0 una volta applicato, -5 quando il DataStore non è valido o non ha colonne, -2 quando il componente non è creato
of_add_column (string as_key, string as_title, string as_type)Aggiunge una colonna a larghezza automatica, dopo le altre: quelle già presenti conservano ciò che vi è stato impostato. Per modificare una colonna in seguito, passi dal suo handle (of_column). Restituisce 0 una volta applicato, -5 quando la chiave è vuota, contiene / o `, o nomina una colonna che la griglia ha già, -2` quando il componente non è creato
of_add_column (string as_key, string as_title, string as_type, long al_width)Idem, con una larghezza in pixel (0 = automatica). Restituisce 0 una volta applicato, -5 quando la chiave è vuota, contiene / o `, o nomina una colonna che la griglia ha già, -2` quando il componente non è creato
of_add_column (string as_key, string as_title, string as_type, long al_width, string as_renderer)Idem, con una cella ricca (RENDERER_*). Restituisce 0 una volta applicato, -5 quando la chiave è vuota, contiene / o `, o nomina una colonna che la griglia ha già, -2` quando il componente non è creato
of_set_columns (string as_columns_json)Dichiara tutte le colonne in una volta, con le loro opzioni di dettaglio (formato, blocco, colonna modificabile…). Gli handle di colonna ottenuti prima (of_column) vengono rilasciati: li riprenda. Restituisce 0 una volta applicato, -5 quando il testo non è un array JSON, -2 quando il componente non è creato
of_load_rows (string as_rows_json)Sostituisce le righe visualizzate. Il DataStore di un of_from_datastore precedente viene dimenticato: ib_write_back e of_reload_row non lo raggiungono più. Restituisce 0 una volta applicato, -5 quando il testo non è un array JSON, -2 quando il componente non è creato
of_append_rows (string as_rows_json)Aggiunge righe dopo quelle già visualizzate — scorrimento infinito, arrivo in tempo reale. Restituisce 0 una volta applicato, -5 quando il testo non è un array JSON o alcune sue righe sono state scartate perché la griglia ne possiede già la chiave (le altre vengono aggiunte), -2 quando il componente non è creato
of_update_row (string as_row_json)Sostituisce una riga sul posto: quella che porta la stessa chiave _k. Restituisce 0 una volta applicato, -5 quando il testo non è un oggetto JSON o la griglia non possiede alcuna riga con quella chiave, -2 quando il componente non è creato
of_reload_row (long al_row)Rinvia una riga del DataStore passato a of_from_datastore, letta adesso: dopo che il Suo codice l'ha cambiata. al_row è il suo numero di riga oggi; la griglia ritrova la riga tramite il suo RowID, un ordinamento o un'eliminazione nel frattempo non cambiano nulla. Una riga che la griglia non contiene ancora (InsertRow, ovunque) si aggiunge dopo le altre. Restituisce 0 una volta inviata, -5 quando nessun DataStore è collegato o la riga non esiste, -2 quando il componente non è creato
of_reset_update ( )Da chiamare una volta riuscito il Suo Update: le celle modificate nella griglia non sono più segnate (un piccolo angolo nel colore d'accento). Restituisce 0 una volta inviato, -2 quando il componente non è creato
of_remove_row (string as_key)Rimuove una riga, tramite la sua chiave. Per una riga di un DataStore la chiave è il suo RowID: lo prenda prima di ids.DeleteRow(ll_row), con String(ids.GetRowIdFromRow(ll_row)). Restituisce 0 una volta applicato, -5 quando la griglia non contiene nessuna riga con questa chiave, -2 quando il componente non è creato
of_clear_columns ( )Svuota le colonne accumulate da of_add_column, prima di ricostruire una griglia. Gli handle di colonna ottenuti prima (of_column) vengono rilasciati: li riprenda. Restituisce 0 una volta applicato, -2 quando il componente non è creato

Colonne #

MetodoRuolo
of_column (string as_key)L'handle di una colonna (n_pbt_datagrid_column): larghezza, blocco, mascheramento, immissione, totale, cella ricca, posizione, filtro — vedere Proprietà di colonna

Ordinamento, filtro, presentazione #

MetodoRuolo
of_sort (string as_col, string as_dir)Ordina su una sola colonna: "asc", "desc" o "none" (ritorno all'ordine caricato). Una colonna con tabella dei codici ordina sul suo dato, come un DataWindow. Più colonne: of_sort("city A, revenue D"). Restituisce 0 una volta ordinato, -5 quando la griglia non ha questa colonna o il verso non è uno dei tre, -2 quando il componente non è creato
of_sort (string as_sort)Ordina su più colonne, nel loro ordine: la prima decide, le successive ne risolvono le parità. as_sort si scrive come lo legge il SetSort di un DataWindow — "city A, revenue D"; anche asc e desc sono letti, una colonna senza verso è crescente, "" toglie l'ordinamento (ordine caricato). Restituisce 0 una volta ordinato, -5 per una colonna che la griglia non ha, un altro verso o una colonna nominata due volte, -2 quando il componente non è creato
of_get_layout ( )Ciò che l'utente ha disposto, in JSON: le colonne nel loro ordine con larghezza, blocco e visibilità, l'ordinamento (un array ordinato: "sort":[{"col":"city","dir":"asc"},{"col":"revenue","dir":"desc"}]), i filtri così come digitati, la ricerca rapida, il raggruppamento e la riga dei filtri. Da conservare (file, registro, tabella) e restituire a of_set_layout. Titoli, celle ricche e formati sono Suoi: non vi figurano
of_set_layout (string as_layout_json)Ripristina una disposizione letta da of_get_layout o ricevuta tramite ue_layout_changed. Una colonna che non conosce (aggiunta nel frattempo) mantiene il suo posto dopo quelle che ordina; una colonna che nomina e che non esiste più viene ignorata; viene sollevato ue_layout_changed, come per ogni cambiamento della disposizione. Un ordinamento scritto come oggetto singolo ("sort":{"col":"city","dir":"asc"}) viene letto anch'esso. Restituisce 0 una volta applicata, -5 quando il testo è vuoto o non è un oggetto JSON (un file troncato: non viene inviato nulla), -2 quando il componente non è creato
of_clear_filters ( )Cancella il filtro rapido e tutti i filtri per colonna. Restituisce 0 una volta applicato, -2 quando il componente non è creato

Selezione, dettaglio, esportazione #

MetodoRuolo
of_select_rows (string as_keys_json)Imposta la selezione dal Suo codice, tramite elenco di chiavi ('["1","4"]'); un array vuoto deseleziona tutto, una chiave che la griglia non possiede viene scartata. Come un clic, solleva ue_selection_changed (nulla se restano selezionate le stesse righe). Restituisce 0 una volta applicato, -5 quando il testo non è un array JSON, -2 quando il componente non è creato
of_selected_keys ( )Restituisce le chiavi selezionate, come array JSON ('["1","4"]'), lette dalla griglia al momento della chiamata: una selezione impostata da of_select_rows, o una riga rimossa nel frattempo, è già presa in conto
of_fill_detail (string as_key, string as_markup)Pannello di dettaglio di una riga, in testo formattato. Restituisce 0 una volta applicato, -5 quando la griglia non contiene nessuna riga con questa chiave, -2 quando il componente non è creato
of_expand_row (string as_key) · of_collapse_row (string as_key)Espande / richiude il pannello di dettaglio di una riga; come il suo chevron, solleva ue_row_expanded / ue_row_collapsed (nulla se il pannello è già in quello stato). Restituisce 0 una volta applicato, -5 quando la griglia non contiene nessuna riga con questa chiave, -2 quando il componente non è creato
of_expand_node (string as_key) · of_collapse_node (string as_key)Modalità ad albero: espande / richiude un nodo (le righe figlie portano _parent). Restituisce 0 una volta applicato, -5 quando la griglia non contiene nessuna riga con questa chiave, -2 quando il componente non è creato
of_export_csv (string as_path)Scrive ciò che la griglia mostra (filtri, ordinamento, colonne visibili) in un file CSV: UTF-8 con BOM, separatore punto e virgola — il gemello dell'esportazione del crosstab. La DLL scrive il file, ue_csv_saved conferma. Rifiutato senza licenza. Restituisce 0 una volta richiesto, -5 quando il percorso è vuoto, -2 quando il componente non è creato
of_export_xlsx (string as_path)Scrive ciò che la griglia mostra (filtri, ordinamento, colonne visibili) in una cartella di lavoro Excel (.xlsx): i numeri restano numeri, con il formato della loro colonna, la riga di intestazione in grassetto. La DLL scrive il file, ue_xlsx_saved conferma; un percorso relativo viene scritto nella cartella in cui l'applicazione è partita. Rifiutato senza licenza e con una sorgente a finestra. Restituisce 0 una volta richiesto, -5 quando il percorso è vuoto, -2 quando il componente non è creato
of_add_row_menu_item (string as_key, string as_label)Aggiunge una delle sue voci al menu contestuale di riga, sotto quelle integrate; la scelta torna in ue_row_menu_clicked con questa chiave, un'etichetta vuota mostra la chiave. Restituisce 0 una volta aggiunta, -5 quando la chiave è vuota, contiene / o ``, o è già una delle Sue voci
of_add_row_menu_separator ( )Un separatore tra due gruppi delle sue voci. Restituisce 0
of_clear_row_menu ( )Toglie le sue voci: il menu di riga torna alle sole voci integrate. Restituisce 0 una volta applicato, -2 quando il componente non è creato

Volumi molto grandi #

MetodoRuolo
of_open_source (long al_total)Dichiara una sorgente di al_total righe senza costruirle: la griglia richiede solo quelle che deve visualizzare, tramite ue_rows_needed. Le chiavi sono allora posizioni nella Sua sorgente; il DataStore di un of_from_datastore precedente viene dimenticato. La ricerca rapida e la riga dei filtri sono nascoste (la griglia tiene solo le righe sullo schermo); un ordinamento scelto dall'utente Le arriva tramite ue_sort_changed: ordini la Sua sorgente, la griglia richiede di nuovo le sue righe. Restituisce 0 una volta applicato, -2 quando il componente non è creato
of_supply_rows (long al_from, string as_rows_json)Risposta a ue_rows_needed: il lotto di righe è posto a partire dalla riga al_from, contata da 1 come quelle di un DataStore. Restituisce 0 una volta applicato, -5 quando il testo non è un array JSON, -2 quando il componente non è creato
of_clear_source ( )Esce dalla modalità a finestra e torna alle righe caricate in memoria. Restituisce 0 una volta applicato, -2 quando il componente non è creato
of_go_to_page (long al_page)Visualizza una pagina data (la prima = 1). Senza effetto finché la paginazione non è attivata. Restituisce 0 una volta applicato, -2 quando il componente non è creato
of_supply_grand_totals (string as_values_json)Imposta il totale generale, che calcola Lei: '{"ca":128400000,"quantity":51230}'. Una stringa vuota lo rimuove. Restituisce 0 una volta applicato, -5 quando il testo non è un oggetto JSON, -2 quando il componente non è creato

Comuni #

MetodoRuolo
of_reset ( )Svuota colonne e righe e riporta il componente al suo stato iniziale. Restituisce 0 una volta applicato, -2 quando il componente non è creato
of_set_redraw (boolean)Raggruppa una raffica di modifiche in un solo rendering. Restituisce 0
of_save_as_png (string) · of_save_as_jpg (string)Esporta il rendering come immagine. Restituisce 0 una volta scritta l'immagine, -2 non creato, -4 cattura fallita, -5 percorso vuoto

Event #

EventAttivato quando
ue_row_clicked (string as_key)Si fa clic su una riga
ue_row_dblclicked (string as_key, string as_col)Si fa doppio clic su una riga: il gesto che apre una scheda. as_col è la colonna sotto il puntatore. Su una cella modificabile il doppio clic apre l'editor e non solleva questo event
ue_cell_clicked (string as_key, string as_col)Si fa clic su una cella
ue_selection_changed (string as_keys_json)La selezione cambia: un clic seleziona solo quella riga, Ctrl+clic ne aggiunge o ne toglie una, Maiusc+clic prende un intervallo, e of_select_rows fa lo stesso dal vostro codice; as_keys_json è l'array JSON delle chiavi selezionate ('["1","4"]'). Anche una selezione che il Suo codice svuota (un ricaricamento, SELECT_NONE) viene segnalata
ue_sort_changed (string as_col, string as_dir, string as_sort)L'ordinamento è cambiato: un clic su un'intestazione (Maiusc+clic aggiunge una colonna all'ordinamento), il menu di una colonna, o of_sort — un ordine dal codice solleva l'event come un gesto; nulla quando l'ordinamento resta lo stesso. as_col / as_dir: la colonna in questione e il suo verso ora ("none" una volta uscita dall'ordinamento); as_sort: l'ordinamento intero, le colonne nel loro ordine, scritto come lo legge SetSort ("city A, revenue D", "" per nessuno). Con una sorgente a finestra (of_open_source), ordini il Suo DataStore con esso — ids.SetSort(as_sort) poi ids.Sort(): la griglia richiede poi di nuovo le sue righe nel nuovo ordine
ue_action_clicked (string as_key, string as_col, string as_action)Si fa clic su un pulsante collocato in una cella (RENDERER_BUTTON)
ue_row_expanded (string as_key)Una riga master-dettaglio viene espansa, dal suo chevron o da of_expand_row — il momento giusto per alimentarne il dettaglio al volo
ue_row_collapsed (string as_key)Una riga master-dettaglio viene compressa, dal suo chevron o da of_collapse_row
ue_detail_needed (string as_key)Con ib_detail_on_demand: una riga che non ha ancora un dettaglio viene aperta (la sua freccia, o of_expand_row). La riempia qui con of_fill_detail(as_key, …): il pannello si apre al ritorno dell'evento; nulla di riempito, la riga resta chiusa
ue_filter_changed (string as_filters_json)L'utente ha immesso un filtro, nella ricerca rapida o nella riga di filtro per colonna (la ricerca: una volta finita la digitazione). as_filters_json dice ogni filtro così come digitato e la ricerca — {"filters":{"revenue":"> 1000"},"quick":"bos"}: i testi che is_filter e is_quick_filter riprendono così come sono
ue_cell_edited (string as_key, string as_col, string as_value)Una cella modificabile viene confermata con un nuovo valore; as_value è quel valore in formato testo. Con ib_veto_edits, solo dopo che ue_cell_editing lo ha accettato. Con ib_write_back, un valore che il DataStore rifiuta non viene conservato: la cella torna indietro, ue_write_back_failed dice perché, e questo evento non viene sollevato
ue_cell_editing (string as_key, string as_col, string as_value)Prima che un valore immesso venga conservato, solo se ib_veto_edits è vero. Restituisca false per lasciare il vecchio valore nella cella (ue_cell_edited non viene allora sollevato); true per impostazione predefinita
ue_write_back_failed (string as_key, string as_col, string as_value, string as_reason)Con ib_write_back: il DataStore non ha potuto conservare un valore digitato (la sua riga eliminata dopo il caricamento, un valore rifiutato da SetItem, un testo che non è un'ora). La cella ha ripreso ciò che il DataStore contiene e ue_cell_edited non è stato sollevato; as_reason dice perché — da comunicare all'utente, o ricaricare la riga
ue_layout_changed (string as_layout_json)La disposizione è cambiata, che sia stato l'utente o il Suo codice: una colonna ridimensionata, spostata, bloccata o nascosta, l'ordinamento, i filtri, la ricerca rapida, il raggruppamento, la riga dei filtri — of_set_layout compreso. Nulla viene sollevato quando nulla cambia. as_layout_json è l'intera disposizione, come la restituisce of_get_layout: da conservare, poi da restituire a of_set_layout
ue_rows_needed (long al_from, long al_to)Modalità a finestra: la griglia richiede le righe da al_from a al_to, incluse, contate da 1 — i numeri di riga di un DataStore. Risponda con of_supply_rows
ue_page_changed (long al_page, long al_pages)La pagina visualizzata cambia, tramite i pulsanti di paginazione o tramite of_go_to_page. al_page è la pagina corrente (la prima = 1), al_pages il numero totale di pagine. Informa soltanto: con una sorgente a finestra le righe della nuova pagina sono richieste da ue_rows_needed — risponda a quello, non a entrambi
ue_csv_saved (string as_path, boolean ab_ok, string as_error)Il CSV chiesto da of_export_csv — o dalla voce Esporta in CSV del menu di riga, che chiede il file all'utente — è stato scritto, oppure no: ab_ok, e as_error dice perché
ue_xlsx_saved (string as_path, boolean ab_ok, string as_error)La cartella di lavoro richiesta da of_export_xlsx è stata scritta — o no: ab_ok, e as_error dice perché. as_path è il file scritto, un percorso relativo risolto
ue_copy (string as_tsv)L'utente ha premuto Ctrl+C. as_tsv contiene le righe selezionate con la loro riga di intestazione, oppure la sola cella con il fuoco se non c'è nulla di selezionato
ue_row_rclicked (string as_key, string as_col, long al_x, long al_y)Una riga ha ricevuto un clic destro (o il tasto Menu / Maiusc+F10 premuto su di essa). Sollevato che il menu integrato sia attivo o meno. al_x / al_y sono pixel schermo, non unità PowerBuilder: per posare il suo menu dove l'utente ha mirato, usi PopMenu(PointerX(), PointerY()) sulla sua finestra
ue_row_menu_clicked (string as_menu_key, string as_row_key, string as_keys_json)Una delle sue voci (of_add_row_menu_item) è stata scelta: as_menu_key è la sua chiave, as_row_key la riga su cui il menu è stato aperto; as_keys_json è l'intera selezione, su cui deve lavorare un'azione di lotto
ue_ready ( )Il componente ha terminato il caricamento; tutto ciò che è stato inviato prima è stato riprodotto
ue_runtime_missing ( )Il runtime WebView2 è assente: il componente resta vuoto
ue_bg_color (long al_color)Il componente ha calcolato il colore di sfondo del proprio tema; l'userobject lo ha già adottato (backcolor)

Ciò che l'utente può fare senza una riga di codice #

La griglia integra la propria barra degli strumenti e i propri menu d'intestazione. Nulla di tutto questo richiede codice da parte Sua:

Ogni modifica della disposizione ritorna in ue_layout_changed: larghezze, ordine, colonne bloccate o nascoste. La conservi, e la restituisca con una sola chiamata a of_set_layout alla prossima apertura; of_get_layout la rilegge in qualsiasi momento.

Da tastiera — la griglia è un unico punto di tabulazione. Una volta raggiunta, la si percorre interamente da tastiera:

TastoEffetto
FrecceSpostano la cella con il fuoco, cella per cella
Inizio / FinePrima / ultima colonna della riga
Ctrl+Inizio / Ctrl+FinePrima / ultima cella della griglia
Pag su / Pag giùSi spostano di una schermata, seguendo l'altezza reale della vista
Maiusc + frecceEstendono la selezione dall'ancora (modalità SELECT_MULTIPLE)
SpazioSeleziona o deseleziona la riga con il fuoco e vi posa l'ancora; su una casella di controllo modificabile, la inverte
Invio o F2Mette la cella in modifica se la sua colonna è modificabile; una casella di controllo si inverte subito
Un carattereSu una cella di testo o numero modificabile, apre l'editor con quel carattere, come un foglio di calcolo
Tab / Maiusc+Tab (in modifica)Conserva il valore e apre la cella modificabile successiva (precedente), la riga seguente alla fine di una riga
Ctrl+CCopia la selezione — vedere ue_copy

La cella con il fuoco è contornata dal colore d'accento e annunciata ai lettori di schermo tramite aria-activedescendant. Il fuoco sopravvive allo scorrimento: essendo la griglia virtualizzata, viene tenuto in memoria e riposato dopo ogni rendering. Scompare invece se la sua riga esce dalla vista per un ordinamento o un filtro.

⚠️ Gli appunti del browser possono essere rifiutati in una WebView ospitata. È per questo che ue_copy vi restituisce il testo: mettetelo voi stessi con ClipBoard(as_tsv) per essere certi del risultato.


Esempi #

Conti clienti in poche righe #

// ids : the accounts DataStore (see above). One repaint for the whole setup.
uo_grid.of_set_redraw(/*on*/ false)

// 1. The grid reads the columns (typed) and every row of the DataStore
uo_grid.of_from_datastore(/*ads*/ ids)

// 2. The titles are the header texts of the DataWindow ; rename one if you like
uo_grid.of_column(/*key*/ "rep").is_title = "Account manager"

// 3. Rich cells : an avatar, a coloured status, a gauge, a mini chart, stars
uo_grid.of_column(/*key*/ "rep").is_renderer = n_pbt_datagrid_column.RENDERER_AVATAR
uo_grid.of_column(/*key*/ "status").is_renderer = n_pbt_datagrid_column.RENDERER_CHIP
uo_grid.of_column(/*key*/ "status").is_tones = "Active=" + n_pbt_datagrid_column.TONE_SUCCESS + "|At risk=" + n_pbt_datagrid_column.TONE_DANGER
uo_grid.of_column(/*key*/ "pipeline").is_renderer = n_pbt_datagrid_column.RENDERER_PROGRESS
uo_grid.of_column(/*key*/ "trend").is_renderer = n_pbt_datagrid_column.RENDERER_SPARKLINE
uo_grid.of_column(/*key*/ "rating").is_renderer = n_pbt_datagrid_column.RENDERER_RATING

// A total, a column that stays in view, several rows selectable
uo_grid.of_column(/*key*/ "revenue").is_summary = n_pbt_datagrid_column.SUMMARY_SUM
uo_grid.of_column(/*key*/ "city").is_pin = n_pbt_datagrid_column.PIN_START
uo_grid.is_selection_mode = u_pbt_datagrid.SELECT_MULTIPLE
uo_grid.of_set_redraw(/*on*/ true)

Raggruppare per stato, poi per città #

// The subtotal every group header shows
uo_grid.of_column(/*key*/ "revenue").is_summary = n_pbt_datagrid_column.SUMMARY_SUM

// Two levels : the status, then the city inside it ; "" goes back to a flat list
uo_grid.is_group_by = "status|city"

// The rating stays in view on the right
uo_grid.of_column(/*key*/ "rating").is_pin = n_pbt_datagrid_column.PIN_END

Filtrare dal suo codice #

// The filter row under the headers : the user types in it
uo_grid.ib_filter_row = true

// Only the accounts in Paris, and only those above one million
uo_grid.is_quick_filter = "Paris"
uo_grid.of_column(/*key*/ "revenue").is_filter = "> 1000000"

Ordinare su più colonne #

L'ordinamento si scrive come quello di un DataWindow: la prima colonna decide, le successive risolvono le parità. L'utente fa lo stesso con il mouse con Maiusc+clic sulle intestazioni; un clic semplice riparte da una sola colonna.

// City first, then the largest revenue in each city
uo_grid.of_sort(/*sort*/ "city A, revenue D")

Ciò che la griglia legge nella DataWindow #

of_from_datastore non prende solo i dati: il testo d'intestazione di ogni colonna (<colonna>_t) diventa il suo titolo, il suo formato di visualizzazione (Format, o la maschera di un EditMask) si applica, e una tabella di codici — i Values di un Edit, di una DDLB o di pulsanti radio, una DropDown DataWindow, una CheckBox — mostra il valore visualizzato (Active) mentre la riga conserva il dato (A). Si ordina e si cerca su ciò che si vede; una colonna con tabella di codici si modifica tramite un elenco, e torna il dato.

// The grid reads titles, formats and code tables in the DataWindow
uo_grid.of_from_datastore(/*ads*/ ids)

// A format of your own on one column, in the DataWindow's syntax
uo_grid.of_column(/*key*/ "revenue").is_format = "$#,##0.00;($#,##0.00)"

// The rating is picked in its code table (Poor to Excellent) ; the number goes into the DataStore
uo_grid.of_column(/*key*/ "rating").ib_editable = true
uo_grid.ib_write_back = true

// Your code changed a row of the DataStore : show it again
ids.SetItem(12, "rating", 5)
uo_grid.of_reload_row(/*row*/ 12)

Modificare sul posto, salvare nel DataStore #

La griglia modifica, il DataStore custodisce la verità: con ib_write_back, ogni immissione vi è scritta sulla riga che la chiave designa (il suo RowID, ritrovato dov'è), tipizzata dalla colonna, prima di ue_cell_edited — e l'indicatore segue. Una cella modificata conserva un piccolo angolo nel colore d'accento fino a of_reset_update.

// The pipelines can be edited : double-click, type a percentage, Enter
uo_grid.of_column(/*key*/ "pipeline").ib_editable = true

// Every edit goes into the DataStore itself, on the row the key designates
uo_grid.ib_write_back = true

Una colonna booleana resa modificabile (TYPE_BOOL, o una colonna CheckBox di un DataWindow letta da of_from_datastore) mostra una vera casella di controllo in ogni cella: un clic, Spazio, Invio o F2 la inverte subito — nessun editor di testo, e un doppio clic non la inverte due volte. La cella riceve il valore dell'altro stato — true/false, o i valori ON/OFF della CheckBox del DataWindow — per la stessa via di un'immissione: veto ib_veto_edits / ue_cell_editing, poi ue_cell_edited, marca «modificata» e ib_write_back. In sola lettura, una colonna booleana conserva il suo segno ✓.

// A yes/no column the user ticks : a check box in every cell
uo_grid.of_add_column(/*key*/ "vip", /*title*/ "VIP", /*type*/ u_pbt_datagrid.TYPE_BOOL)
uo_grid.of_column(/*key*/ "vip").ib_editable = true
// Saving stays with the DataStore : when the user confirms
if ids.Update() = 1 then
	COMMIT USING SQLCA;

	// the edited cells are no longer marked as modified
	uo_grid.of_reset_update()
else
	ROLLBACK USING SQLCA;
end if

Una riga espandibile, scritta dal DataStore #

// Local variables
long ll_row

// A detail panel for the first 20 accounts, written from their DataStore row
for ll_row = 1 to 20
    uo_grid.of_fill_detail(/*key*/ String(ll_row), /*markup*/ "[b]" + ids.GetItemString(ll_row, "rep") + "[/b] follows the " + ids.GetItemString(ll_row, "city") + " account")
next

// The first one is open right away ; the chevron opens the others
uo_grid.of_expand_row(/*key*/ "1")

Pagine invece di uno scorrimento, e il totale di tutto #

Una volta paginata, la griglia contiene una sola pagina: il suo piede totalizza la pagina. Il totale di tutti i conti ce l'ha il DataStore.

// Local variables
n_pbt_json lnv_totals
double ld_revenue
long ll_row

// Pages of 25 rows past 100 rows ; the footer totals the page
uo_grid.ii_page_size = 25
uo_grid.il_page_threshold = 100
uo_grid.of_column(/*key*/ "revenue").is_summary = n_pbt_datagrid_column.SUMMARY_SUM

// The grand total of ALL the accounts, from the DataStore
for ll_row = 1 to ids.RowCount()
    ld_revenue = ld_revenue + ids.GetItemDecimal(ll_row, "revenue")
next
lnv_totals.of_set_number(/*path*/ "revenue", /*value*/ ld_revenue)
uo_grid.of_supply_grand_totals(/*values_json*/ lnv_totals.of_text())

Una sorgente che la griglia non tiene mai per intero #

Per centinaia di migliaia di righe, la griglia ne conosce solo il numero e richiede quelle che mostra. È qui che la sua applicazione legge dalla base la porzione richiesta; i numeri di riga partono da 1, come quelli del DataStore.

// The grid only learns HOW MANY rows exist ; it asks for the ones on screen
uo_grid.of_open_source(/*total*/ ids.RowCount())
// ue_rows_needed event of uo_grid : (long al_from, long al_to)
// Rows al_from to al_to, both included, counted from 1 like the DataStore
n_pbt_json lnv_row
string ls_rows
long ll_row

// One JSON row per DataStore row asked for, its key being the row number
ls_rows = "["
for ll_row = al_from to Min(al_to, ids.RowCount())
    lnv_row.of_clear()
    lnv_row.of_set_string(/*path*/ "_k", /*value*/ String(ll_row))
    lnv_row.of_set_string(/*path*/ "city", /*value*/ ids.GetItemString(ll_row, "city"))
    lnv_row.of_set_string(/*path*/ "rep", /*value*/ ids.GetItemString(ll_row, "rep"))
    lnv_row.of_set_string(/*path*/ "trend", /*value*/ ids.GetItemString(ll_row, "trend"))
    lnv_row.of_set_number(/*path*/ "revenue", /*value*/ Double(ids.GetItemDecimal(ll_row, "revenue")))
    if ll_row > al_from then ls_rows = ls_rows + ","
    ls_rows = ls_rows + lnv_row.of_text()
next
uo_grid.of_supply_rows(/*from*/ al_from, /*rows_json*/ ls_rows + "]")
// ue_sort_changed event of uo_grid : (string as_col, string as_dir, string as_sort)
// as_sort is the whole sort, written as SetSort reads it ("" for none) :
// sort the source with it, the grid then asks for its rows again
ids.SetSort(as_sort)
ids.Sort()

Esportare ciò che è mostrato #

// What is shown - filters, sort, visible columns - to a CSV file
uo_grid.of_export_csv(/*path*/ "C:\exports\accounts.csv")
// ue_csv_saved event of uo_grid : (string as_path, boolean ab_ok, string as_error)
if ab_ok then
    st_status.Text = "Written : " + as_path
else
    st_status.Text = as_error
end if

Le sue voci nel menu di riga #

// The row menu, entry by entry
uo_grid.of_add_row_menu_item(/*key*/ "open", /*label*/ "Open the account")
uo_grid.of_add_row_menu_separator()
uo_grid.of_add_row_menu_item(/*key*/ "call", /*label*/ "Call the sales rep")
// ue_row_menu_clicked event of uo_grid : (string as_menu_key, string as_row_key, string as_keys_json)
choose case as_menu_key
    case "open"
        wf_open_account(Long(as_row_key))
    case "call"
        wf_call(ids.GetItemString(Long(as_row_key), "rep"))
end choose

Reagire alla selezione #

// ue_selection_changed event of uo_grid : (string as_keys_json)
// '["3","7"]' : the RowIDs of the selected accounts (ids.GetRowFromRowId gives their rows)
cb_delete.Enabled = (Pos(as_keys_json, "[]") = 0)

Ricordare la disposizione dell'utente #

// ue_layout_changed event of uo_grid : (string as_layout_json)
// Order, widths, pins, hidden columns, sort, filters, grouping : keep it
SetProfileString(gs_ini, "grids", "accounts", as_layout_json)
// open event of the window, once the grid is filled : the layout of last time
uo_grid.of_set_layout(/*layout_json*/ ProfileString(gs_ini, "grids", "accounts", ""))

Buone pratiche #

Ereditato dalla base comune #

Questi membri esistono su tutti i componenti visivi — non sono propri di questo. Sono descritti una sola volta, nei capitoli trasversali; questa tabella dice solo dove leggerli.

MembriRuoloDescritto in
of_count · of_keys_at · of_hasPercorrere ciò che il componente contiene3.2 Gli item
of_resetRiportare il componente a zero3.6 Riportare un componente a zero: of_reset()
of_register_shortcut · of_clear_shortcutsScorciatoie da tastiera del componente3.5 Le scorciatoie da tastiera
of_is_created · of_is_ready · of_get_last_errorSe è nato, se è pronto, cosa è fallito3.7 Diagnostica
of_save_as_png · of_save_as_jpgEsportare il rendering in immagine3.8 Esportare il rendering come immagine
of_set_redrawRaggruppare le modifiche in un solo ridisegno3.10 Buone pratiche
of_preload_iconsIcone mostrate senza ritardoVisualizzazione istantanea: of_icon
of_set_translationTradurre una dicitura del componente5.2 Adattare un'etichetta: of_set_translation
of_focus_webviewDare il focus al componente6.4 Tastiera e focus
of_print · of_print_to_pdfStampare, o scrivere un PDF6.9 Stampare
of_set_property · of_get_property · of_component_namePilotare una proprietà per nome3.1 Il motore delle proprietà

Due aiuti non sono ereditati: of_icon e of_escape_markup vivono su n_pbt_utils. Ne dichiari uno — n_pbt_utils lnv_utils, niente da creare — e li chiami su di esso.

← Riferimento dei componenti · Sommario della guida