crosstab — u_pbt_crosstab #
← Riferimento dei componenti · Sommario della guida
Tabella crosstab completa: aree righe / colonne / valori alimentate da un DataStore, aggregazioni, filtri, formattazione condizionale, raggruppamento di date, misure calcolate ed esportazioni CSV / Excel.
▶ Vederlo dal vivo — Applicazione dimostrativa, riquadro Crosstab: l'anteprima, il codice che lo produce e questa pagina, affiancati.
In breve #
| Userobject | u_pbt_crosstab |
| Classe degli item | — (i campi si collocano tramite metodi) |
| Serve per | Offrire ai suoi utenti un'analisi incrociata dei suoi dati, che riorganizzano da soli, senza scrivere SQL né passare da Excel |
| Limite in modalità demo | 500 righe di origine elaborate; esportazioni CSV ed Excel e copia (Ctrl+C) disattivate — vedere la modalità demo |
Il principio #
Lei fornisce al componente un insieme di dati piatto — un DataStore, quindi qualsiasi query già scritta nella sua applicazione. Al resto pensa il crosstab: ne deduce l'elenco dei campi e Lei li distribuisce in quattro aree.
| Area | Che cosa contiene | Effetto |
|---|---|---|
| Righe | Campi di raggruppamento | Un livello di righe per campo, comprimibile |
| Colonne | Campi di raggruppamento | Un livello di intestazioni di colonna per campo |
| Valori | Campi numerici e la loro aggregazione | Ciò che viene calcolato nelle celle |
| Filtri | Campi di selezione | Un filtro sopra la tabella, applicato a tutto |
Tutto il calcolo avviene nel componente: una volta trasmessi i dati, riorganizzare la tabella non provoca alcun viaggio di andata e ritorno verso il database né verso PowerBuilder.
Avvio rapido #
// event open della finestra
datastore lds
lds = create datastore
lds.dataobject = "d_sales"
lds.SetTransObject(SQLCA)
lds.Retrieve()
// 1. Trasmettere i dati: i campi sono dedotti dalle colonne
uo_crosstab.of_from_datastore(/*data*/ lds)
// 2. Distribuire i campi nelle aree
uo_crosstab.of_add_row_field(/*field*/ "region")
uo_crosstab.of_add_col_field(/*field*/ "year")
uo_crosstab.of_add_value_field(/*field*/ "amount", /*agg*/ uo_crosstab.AGG_SUM)
// 3. Presentare: formato degli importi e totali generali
uo_crosstab.of_set_value_format(/*field*/ "amount", /*decimals*/ 0, /*thousands*/ "locale", /*suffix*/ "$", /*symbol_before*/ true)
uo_crosstab.ib_row_grand_total = true
uo_crosstab.ib_col_grand_total = true
// event ue_cell_double_clicked di uo_crosstab: (string as_row_tuple_json, string as_col_tuple_json, integer ai_measure, double ad_value)
// L'utente vuole il dettaglio dietro una cifra: aprire l'elenco corrispondente.
of_open_detail(as_row_tuple_json, as_col_tuple_json)
Costanti #
| Costante | Valore | Per |
|---|---|---|
TOTALS_BOTTOM · TOTALS_TOP | "bottom" "top" | is_totals_position |
VALUES_COLS · VALUES_ROWS | "cols" "rows" | is_values_axis |
AGG_SUM · AGG_COUNT · AGG_DISTINCT_COUNT | "sum" "count" "dcount" | of_add_value_field |
AGG_AVG · AGG_MIN · AGG_MAX | "avg" "min" "max" | of_add_value_field |
LABEL_GT · LABEL_LT · LABEL_BETWEEN | "gt" "lt" "between" | of_set_label_filter |
LABEL_CONTAINS · LABEL_BEGINS · LABEL_ENDS | "contains" "begins" "ends" | of_set_label_filter |
Le costanti di aggregazione si leggono sul componente: uo_crosstab.AGG_SUM. Quelle di un campo (SHOW_*, CF_*) si leggono sull'handle del campo.
Proprietà #
| Proprietà | Tipo | Predefinito | Ruolo |
|---|---|---|---|
is_totals_position | string | "bottom" | Dove si colloca la riga del totale generale: TOTALS_BOTTOM (in fondo, predefinito) o TOTALS_TOP (in cima, subito sotto le intestazioni). Si sposta solo il totale generale: il subtotale di un gruppo resta sulla riga del gruppo |
is_values_axis | string | "cols" | Orientamento delle misure quando ce n'è più di una: VALUES_COLS (affiancate in colonne, predefinito) o VALUES_ROWS (impilate in righe) |
is_currency_symbol | string | "" | La valuta che il menu Formato numero di un chip di valore propone, accanto a « Nessun simbolo » e « % ». Vuoto = quella della lingua di visualizzazione ($ in inglese, € altrove) |
is_thousands | string | "locale" | Separatore delle migliaia delle misure che non ne impostano uno (of_set_value_format con separatore vuoto) — la stessa impostazione del menu Opzioni della griglia: THOUSANDS_LOCALE (quello della lingua di visualizzazione, predefinito), THOUSANDS_SPACE, THOUSANDS_NONE, o il separatore stesso (",", ".", " ") |
ib_field_list | boolean | true | Mostra il pannello dei campi, dove l'utente riorganizza la tabella con il mouse |
ib_row_subtotals | boolean | true | Mostra il subtotale di ogni gruppo di righe, scritto sulla riga del gruppo stesso, sopra i suoi membri; disattivato, quella riga conserva l'etichetta senza cifra |
ib_col_subtotals | boolean | true | Mostra un subtotale per ogni gruppo di colonne |
ib_row_grand_total | boolean | true | Mostra la riga del totale generale sotto la tabella (la gemella di ib_col_grand_total) |
ib_col_grand_total | boolean | true | Mostra la colonna del totale generale dopo la tabella (la gemella di ib_row_grand_total) |
ib_copy_headers | boolean | true | Ctrl+C copia le intestazioni con le celle selezionate: i nomi delle colonne su una prima riga (la misura vi è nominata solo se la tabella la mostra: più valori, o nessun campo in Colonne) e il membro di ogni riga — il suo percorso intero, « Nord / Lille » — in una prima colonna, il cui angolo porta i nomi dei campi in righe (« region / ville »). Un incolla in un foglio di calcolo dice così che cosa sono le cifre. false copia le sole cifre. Letta in diretta, riportata a true da of_reset |
ib_enabled | boolean | true | In grigio: la griglia mostra ancora le sue cifre — un crosstab vuoto non è la stessa cosa di uno spento dall'applicazione — ma smette di rispondere al puntatore |
is_theme_style | string | "" | Stile visivo del componente (costanti THEME_STYLE_*); vuoto = quello dell'applicazione, seguito a ogni cambio |
is_theme_mode | string | "" | Variante chiara o scura (costanti THEME_MODE_*); vuoto = quella dell'applicazione, seguita a ogni cambio |
il_theme_accent | long | -1 | Colore d'accento di questo componente (-1 = accento dell'applicazione, o quello del tema) |
is_tooltip | string | "" | Tooltip semplice mostrato al passaggio del mouse sul componente |
is_super_tooltip_title | string | "" | Titolo del tooltip avanzato (prevale su is_tooltip) |
is_super_tooltip_text | string | "" | Testo del tooltip avanzato (markup avanzato accettato) |
is_super_tooltip_image | string | "" | Immagine del tooltip avanzato |
Proprietà di un campo #
of_field (string as_field) restituisce l'handle di un campo: lo recupera una volta, poi pilota il campo attraverso le sue proprietà. L'handle viene creato alla prima chiamata e riutilizzato in seguito.
| Proprietà | Tipo | Predefinito | Ruolo |
|---|---|---|---|
is_label | string | intestazione del DataWindow | Etichetta leggibile del campo ("amount" → "Fatturato"). Per impostazione predefinita il testo di intestazione della colonna nel DataWindow, altrimenti il suo nome; una stringa vuota lo ripristina. Posta dal suo codice, sopravvive a of_from_datastore |
is_show | string | "normal" | Ciò che la cella visualizza: "normal", "pctGrand" (% del totale generale), "pctRow" (% della riga), "pctCol" (% della colonna), "running" (totale progressivo), "diff" (scarto rispetto al precedente) |
is_conditional_formatting | string | "none" | Formattazione condizionale: CF_NONE, CF_SCALE (scala di colori), CF_BARS (barre nella cella) o CF_ICONS (una freccia per terzo: su, stabile, giù) |
I valori di is_show e is_conditional_formatting sono disponibili anche come costanti sull'handle (SHOW_PCT_COL, CF_SCALE…). Posti prima che il campo sia in Valori, vengono conservati, riletti così come posti e applicati al suo arrivo.
// Local variables
n_pbt_crosstab_field lnv_field
// Il campo importo : la sua etichetta e una scala di colori
lnv_field = uo_crosstab.of_field(/*field*/ "amount")
lnv_field.is_label = "Fatturato"
lnv_field.is_conditional_formatting = lnv_field.CF_SCALE
⚠️ Modifica non retrocompatibile. Questa proprietà si chiamava
is_cf: l'abbreviazione non diceva nulla nel punto di chiamata. Il vecchio nome non esiste più: un codice che lo utilizza non compila. La sostituzione è meccanica:is_cf→is_conditional_formatting, senza alcun cambiamento di valori né di comportamento.
Metodi #
Alimentare e denominare #
| Metodo | Ruolo |
|---|---|
of_from_datastore (datastore ads_data) | Trasmette l'insieme di dati: i campi sono dedotti dalle colonne del DataStore, la loro etichetta dal testo di intestazione. Un testo che contiene una tabulazione o un a capo resta nella sua riga; un valore vuoto (NULL, testo vuoto) è un solo membro (vuoto), messo per ultimo; le etichette poste con is_label sopravvivono al ricaricamento. Restituisce 0 una volta caricati i dati, -5 se il DataStore non è valido o non ha alcuna colonna, -2 se il componente non è creato |
of_field (string as_field) | Restituisce l'handle di un campo, per etichettarlo o formattarlo (vedere Proprietà di un campo) |
Costruire la tabella #
| Metodo | Ruolo |
|---|---|
of_clear_layout ( ) | Svuota le quattro aree: la tabella torna vuota, i dati restano caricati. Restituisce 0 una volta applicato, -2 se il componente non è creato |
of_add_row_field (string as_field) | Aggiunge un campo nell'area Righe (l'ordine delle chiamate determina l'ordine dei livelli). Un campo già in Valori vi resta: può stare in entrambi (un conteggio distinto per membro). Restituisce 0 una volta applicato, -5 per un campo che i dati non contengono o per una misura calcolata (va solo in Valori), -2 se il componente non è creato |
of_add_col_field (string as_field) | Aggiunge un campo nell'area Colonne. Un campo già in Valori vi resta: può stare in entrambi (un conteggio distinto per membro). Restituisce 0 una volta applicato, -5 per un campo che i dati non contengono o per una misura calcolata (va solo in Valori), -2 se il componente non è creato |
of_add_value_field (string as_field, string as_agg) | Aggiunge una misura nell'area Valori, con la sua aggregazione (AGG_*, vuoto = AGG_SUM). Il campo conserva il suo posto in Righe, Colonne o Filtri. Restituisce 0 una volta applicato, -5 per un campo che i dati non contengono o un'altra aggregazione, -2 se il componente non è creato |
of_add_filter_field (string as_field) | Aggiunge un campo nell'area Filtri, sopra la tabella. Restituisce 0 una volta applicato, -5 per un campo che i dati non contengono o per una misura calcolata (va solo in Valori), -2 se il componente non è creato |
of_remove_field (string as_field) | Toglie un campo dalla tabella: da tutte le aree in cui si trova (Righe, Colonne, Filtri, e ciascuno dei suoi valori), con i suoi filtri — come « Rimuovi » dall'elenco dei campi. Il resto della disposizione resta com'è, e ue_layout_changed segnala quella nuova. Restituisce 0 una volta applicato, -4 quando il campo non è in nessuna area, -5 per un campo che i dati non contengono |
Le aggregazioni accettate da of_add_value_field sono esposte dal componente come costanti: AGG_SUM (predefinito), AGG_COUNT, AGG_DISTINCT_COUNT (conteggio di valori distinti, celle vuote ignorate come in Excel), AGG_AVG, AGG_MIN, AGG_MAX.
Totali e subtotali #
I totali si impostano tramite proprietà, descritte sopra: ib_row_grand_total e ib_col_grand_total per i totali generali, ib_row_subtotals e ib_col_subtotals per i subtotali, is_totals_position per la posizione della riga del totale generale.
Filtrare #
| Metodo | Ruolo |
|---|---|
of_set_member_filter (string as_field, string as_values_tab) | Mantiene solo i valori elencati di un campo. I valori sono separati da tabulazioni (~t); un elenco vuoto rimuove il filtro, come of_set_member_order. Restituisce 0 una volta applicato, -5 per un campo che i dati non contengono, -2 se il componente non è creato |
of_clear_member_filter (string as_field) | Rimuove questo filtro. Restituisce 0 una volta applicato, -5 per un campo che i dati non contengono, -2 se il componente non è creato |
of_set_value_filter (string as_field, string as_type, double ad_a, double ad_b, integer ai_measure_index) | Filtra sul totale della misura n. ai_measure_index (la prima = 1): VALUEFILTER_TOP o VALUEFILTER_BOTTOM (i primi o gli ultimi ad_a), VALUEFILTER_GT, VALUEFILTER_LT (sopra, sotto ad_a), VALUEFILTER_BETWEEN (tra ad_a e ad_b). Restituisce 0 una volta applicato, -5 per un campo che i dati non contengono, un altro tipo o una posizione senza misura in Valori, -2 se il componente non è creato |
of_clear_value_filter (string as_field) | Rimuove questo filtro. Restituisce 0 una volta applicato, -5 per un campo che i dati non contengono, -2 se il componente non è creato |
of_set_label_filter (string as_field, string as_type, double ad_a, double ad_b) | Filtro numerico sul valore del campo stesso: LABEL_GT, LABEL_LT, LABEL_BETWEEN. Restituisce 0 una volta applicato, -5 per un campo che i dati non contengono o un altro tipo, -2 se il componente non è creato |
of_set_label_filter (string as_field, string as_type, string as_a, string as_b) | Filtro testo sul valore del campo: LABEL_CONTAINS, LABEL_BEGINS, LABEL_ENDS (as_a, senza distinguere maiuscole e minuscole; as_b non serve). Restituisce 0 una volta applicato, -5 per un campo che i dati non contengono, un altro tipo o un testo vuoto, -2 se il componente non è creato |
of_clear_label_filter (string as_field) | Rimuove questo filtro. Restituisce 0 una volta applicato, -5 per un campo che i dati non contengono, -2 se il componente non è creato |
Formattare #
| Metodo | Ruolo |
|---|---|
of_set_value_format (string as_field, integer ai_decimals, string as_thousands, string as_suffix { , boolean ab_symbol_before }) | Formato di una misura: numero di decimali (da 0 a 6), separatore delle migliaia (",", ".", " ": il separatore stesso, "," con un punto decimale e "." con una virgola decimale; "space" spazio sottile, "none", "locale" quello della lingua di visualizzazione; "" lascia la misura su is_thousands, il predefinito del menu Opzioni), simbolo — dopo il numero per impostazione predefinita (1 234 EUR), PRIMA quando ab_symbol_before è true ($1,234). Le tre impostazioni appartengono a QUESTA misura; poste prima che il campo sia in Valori, vengono conservate e applicate al suo arrivo. Restituisce 0 una volta applicato, -5 per un campo che i dati non contengono, -2 se il componente non è creato |
of_clear_value_format (string as_field) | Ritorno al formato predefinito. Restituisce 0 una volta applicato, -5 per un campo che i dati non contengono, -2 se il componente non è creato |
of_set_member_order (string as_field, string as_values_tab) | Ordine di visualizzazione imposto ai valori di un campo (separati da ~t); una stringa vuota ripristina l'ordine naturale. Restituisce 0 una volta applicato, -5 per un campo che i dati non contengono, -2 se il componente non è creato |
Date e campi calcolati #
| Metodo | Ruolo |
|---|---|
of_group_date_field (string as_field, string as_part) | Crea un campo derivato da una colonna date, datetime o timestamp (un'ora sola non ha data da raggruppare): DATE_YEAR, DATE_QUARTER o DATE_MONTH, chiamato <colonna>__<parte>. Entra nell'elenco dei campi e si usa come gli altri. Restituisce 0 una volta applicato, -5 per un campo che i dati non contengono o un'altra parte, -2 se il componente non è creato |
of_add_calc_field (string as_name, string as_label, string as_formula) | Campo calcolato riga per riga ("[amount] * 0.8" = il netto di ogni vendita, poi sommato come qualsiasi colonna), utilizzabile in qualsiasi area. Non per un rapporto di totali (prezzo medio): serve of_add_calc_measure. Restituisce 0 una volta applicato, -5 con un argomento non valido, -2 se il componente non è creato |
of_remove_calc_field (string as_name) | Rimuove un campo calcolato. Restituisce 0 una volta applicato, -5 se nessun campo calcolato ha questo nome, -2 se il componente non è creato |
of_add_calc_measure (string as_name, string as_label, string as_formula) | Misura calcolata cella per cella, sui totali ("[marge] / [ca]" = tasso di margine globale). Si colloca esclusivamente nell'area Valori. La sua formula cita solo campi di dati: un'altra misura calcolata è rifiutata (ue_calc_field_error). Restituisce 0 una volta applicato, -5 con un argomento non valido, -2 se il componente non è creato |
of_remove_calc_measure (string as_name) | Rimuove una misura calcolata. Restituisce 0 una volta applicato, -5 se nessuna misura calcolata ha questo nome, -2 se il componente non è creato |
Una formula accetta gli operatori + - * / ( ), numeri e campi tra parentesi quadre. Una formula non valida attiva ue_calc_field_error — nulla va in crash.
Espandere, memorizzare, esportare #
| Metodo | Ruolo |
|---|---|
of_expand_all ( ) · of_collapse_all ( ) | Espande o comprime tutti i gruppi, di righe E di colonne. Restituisce 0 una volta applicato, -2 se il componente non è creato |
of_expand_to_level (integer ai_level) | Espande fino a un livello dato (1 = solo il primo livello). Restituisce 0 una volta applicato, -2 se il componente non è creato |
of_get_layout ( ) → string | Restituisce lo stato completo della tabella — da conservare così com'è, poi da riprodurre con of_set_layout |
of_set_layout (string as_state_json) | Ripristina uno stato ottenuto in precedenza. Restituisce 0 una volta applicato, -5 per un testo vuoto o che non è JSON, -2 se il componente non è creato |
of_get_cell_value (string as_row_tuple_json, string as_col_tuple_json, integer ai_measure, ref double ad_value) | Legge il valore di una cella, quello che la tabella mostra (0,8 sotto 80,0 %, il progressivo sotto un progressivo). La sua riga e la sua colonna sono i tuple forniti da ue_cell_double_clicked — {"region":"Nord","city":"Lille"}, un membro vuoto null, {} (o una stringa vuota) per il totale — e ai_measure è la posizione del valore nell'area Valori, a partire da 1. Un tuple nomina i campi della sua area a partire dal primo: {"region":"Nord"} è il subtotale di Nord. La risposta non dipende dalla visualizzazione: un ramo compresso o subtotali nascosti si leggono comunque. Restituisce 0 con il valore in ad_value (NULL per una cella senza valore), -4 quando la tabella non ha quella cella (un membro o un campo che non mostra lì), -5 per un tuple malformato o una posizione senza misura, -2 se il componente non è creato |
of_export_csv (string as_path) | Scrive un file CSV della vista corrente (UTF-8 con BOM, punto e virgola); ue_csv_saved conferma. I numeri prendono il separatore decimale della lingua di visualizzazione (la virgola in francese, tedesco, italiano, spagnolo, portoghese); un'etichetta che verrebbe letta come una formula (= + - @) è scritta preceduta da un apostrofo. Il gemello di of_export_xlsx. Restituisce 0 una volta applicato, -5 con un argomento non valido, -2 se il componente non è creato |
of_export_xlsx (string as_path) | Scrive un file Excel della tabella così come è visualizzata, formattazione compresa (negativi in rosso inclusi); ue_xlsx_saved conferma — o rifiuta con il motivo oltre 16 384 colonne o 1 048 576 righe, i limiti di un foglio Excel. Restituisce 0 una volta applicato, -5 con un argomento non valido, -2 se il componente non è creato |
Comuni #
| Metodo | Ruolo |
|---|---|
of_reset ( ) | Riporta il componente al suo stato iniziale. Restituisce 0 una volta applicato, -2 se il componente non è creato |
of_set_redraw (boolean) | Raggruppa una raffica di modifiche in un solo rendering. Restituisce 0 una volta applicato, -2 se il componente non è creato |
of_save_as_png (string) · of_save_as_jpg (string) | Esporta il rendering come immagine. Restituisce 0, -2 se il componente non è creato, -4 se la cattura non riesce, -5 con un percorso vuoto |
Event #
| Event | Attivato quando |
|---|---|
ue_layout_changed (string as_layout_json) | L'utente ha riorganizzato la tabella (spostato un campo, cambiato un'aggregazione, ordinato una colonna, compresso un gruppo…): tutto ciò che of_get_layout salva |
ue_cell_double_clicked (string as_row_tuple_json, string as_col_tuple_json, integer ai_measure, double ad_value) | Doppio clic su una cella: i primi due argomenti descrivono l'incrocio ({"region":"Nord","city":"Lille"}, un membro vuoto vi vale null, {} per il totale), ai_measure la posizione del valore cliccato nell'area Valori, a partire da 1, e ad_value il valore che la cella mostra — 0.8 sotto « 80,0 % », il progressivo sotto un progressivo — oppure NULL per una cella vuota. I due tuple e ai_measure formano l'indirizzo che of_get_cell_value rilegge. È il punto di ingresso di un dettaglio |
ue_csv_saved (string as_path, boolean ab_ok, string as_error) | Il file CSV è stato scritto — oppure no, e as_error dice perché |
ue_xlsx_saved (string as_path, boolean ab_ok, string as_error) | Il file Excel è stato scritto — oppure no, e as_error dice perché |
ue_calc_field_error (string as_field, string as_message) | La formula di un campo o di una misura calcolata non è valida |
ue_copy (string as_tsv) | L'utente ha copiato una selezione di celle (Ctrl+C): spetta a Lei metterla negli appunti. as_tsv è un testo separato da tabulazioni che porta per impostazione predefinita le intestazioni — i nomi delle colonne su una prima riga, il membro di ogni riga (il suo percorso intero, « Nord / Lille ») in una prima colonna — oppure le sole cifre con ib_copy_headers = false. In modalità demo la copia è un'esportazione: rifiutata, e la griglia lo dice |
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) |
Che cosa può fare l'utente senza una riga di codice #
La tabella è viva: è tutto l'interesse del componente. Con il pannello dei campi visualizzato (ib_field_list = true), l'utente può:
- trascinare un campo da un'area all'altra e riorganizzare l'incrocio a piacimento;
- cambiare l'aggregazione di una misura (somma, media, conteggio…);
- filtrare i valori di un campo tramite un elenco con caselle di spunta;
- comprimere o espandere un gruppo di righe o di colonne;
- ordinare da un'intestazione;
- selezionare e poi copiare un blocco di celle, con le sue intestazioni perché un incolla in un foglio di calcolo dica che cosa sono le cifre (
ib_copy_headers).
Ognuna di queste manipolazioni viene segnalata in ue_layout_changed: unita a of_get_layout / of_set_layout, permette di offrire ai suoi utenti delle « viste salvate ».
Da tastiera. Ognuno di questi gesti è raggiungibile senza mouse: Tab porta su un campo, su un triangolo di chiusura o su un'intestazione ordinabile, Invio o Spazio lo attiva. Su un campo si apre il suo menu — quello che porta Aggiungi alle righe / alle colonne / ai valori / ai filtri e Rimuovi: tutta la costruzione della tabella passa di lì. Maiusc+F10 o il tasto Menu aprono anche questo menu, e il focus segue il campo appena spostato, anche in un'altra zona.
Esempi #
Un rapporto vendite completo #
// Righe: regione, poi citta all'interno di ogni regione
uo_crosstab.of_clear_layout()
uo_crosstab.of_add_row_field(/*field*/ "region")
uo_crosstab.of_add_row_field(/*field*/ "city")
// Colonne: una per anno
uo_crosstab.of_add_col_field(/*field*/ "year")
// Celle: l'importo totale
uo_crosstab.of_add_value_field(/*field*/ "amount", /*agg*/ uo_crosstab.AGG_SUM)
// Presentazione: importi leggibili, subtotali e totali generali
uo_crosstab.of_set_value_format(/*field*/ "amount", /*decimals*/ 0, /*thousands*/ "locale", /*suffix*/ "$", /*symbol_before*/ true)
uo_crosstab.ib_row_subtotals = true
uo_crosstab.ib_row_grand_total = true
uo_crosstab.ib_col_grand_total = true
// Colorare le celle per individuare i grandi importi a colpo d'occhio
uo_crosstab.of_field(/*field*/ "amount").is_conditional_formatting = n_pbt_crosstab_field.CF_SCALE
Etichette leggibili #
Le sue colonne si chiamano spesso mt_ht o cd_reg. Le rinomini una volta per tutte, subito dopo of_from_datastore.
// Prima i dati : i campi prendono il nome delle colonne
uo_crosstab.of_from_datastore(/*data*/ lds)
// Poi un'etichetta leggibile per ogni campo
uo_crosstab.of_field(/*field*/ "region").is_label = "Regione"
uo_crosstab.of_field(/*field*/ "city").is_label = "Città"
uo_crosstab.of_field(/*field*/ "category").is_label = "Categoria"
uo_crosstab.of_field(/*field*/ "year").is_label = "Anno"
uo_crosstab.of_field(/*field*/ "amount").is_label = "Fatturato"
uo_crosstab.of_field(/*field*/ "quantity").is_label = "Quantità"
Analizzare quote anziché importi #
// Local variables
n_pbt_crosstab_field lnv_amount
// Ripartire da aree vuote, poi collocare i campi
uo_crosstab.of_clear_layout()
uo_crosstab.of_add_row_field(/*field*/ "category")
uo_crosstab.of_add_col_field(/*field*/ "year")
uo_crosstab.of_add_value_field(/*field*/ "amount", /*agg*/ uo_crosstab.AGG_SUM)
// Tenere solo due categorie sullo schermo (valori separati da una tabulazione)
uo_crosstab.of_set_member_filter(/*field*/ "category", /*values_tab*/ "Informatique~tMobilier")
// Il campo importo, per regolarne la visualizzazione
lnv_amount = uo_crosstab.of_field(/*field*/ "amount")
// Mostrare la quota di ogni cella nel totale della sua colonna
lnv_amount.is_show = lnv_amount.SHOW_PCT_COL
// Una piccola barra in ogni cella per confrontare le quote a colpo d'occhio
lnv_amount.is_conditional_formatting = lnv_amount.CF_BARS
Una misura tutta sua: il prezzo medio #
Una misura calcolata si valuta sui totali di ogni cella, non riga per riga: è ciò che rende corretto un rapporto.
// Ripartire da aree vuote, poi collocare i campi
uo_crosstab.of_clear_layout()
uo_crosstab.of_add_row_field(/*field*/ "region")
// I due totali che serviranno da base al calcolo
uo_crosstab.of_add_value_field(/*field*/ "amount", /*agg*/ uo_crosstab.AGG_SUM)
uo_crosstab.of_add_value_field(/*field*/ "quantity", /*agg*/ uo_crosstab.AGG_SUM)
// Prezzo medio = importo totale diviso per la quantita totale
uo_crosstab.of_add_calc_measure(/*name*/ "avg_price", /*label*/ "Prezzo medio", /*formula*/ "[amount] / [quantity]")
uo_crosstab.of_set_value_format(/*field*/ "avg_price", /*decimals*/ 2, /*thousands*/ "locale", /*suffix*/ "$", /*symbol_before*/ true)
// Poi metterla tra i valori come qualsiasi campo (l'aggregato non conta: una misura si calcola)
uo_crosstab.of_add_value_field(/*field*/ "avg_price", /*agg*/ uo_crosstab.AGG_SUM)
// event ue_calc_field_error di uo_crosstab: (string as_field, string as_message)
// Formula non valida: avvisare senza rompere nulla, la tabella resta visualizzata.
uo_status.of_panel(/*key*/ "main").is_text = "Formula " + as_field + " : " + as_message
Analizzare per mese, trimestre o anno #
Una colonna data non si incrocia così com'è — ogni giorno formerebbe una riga a sé. Derivi prima il livello desiderato.
// Creare tre campi derivati dalla colonna sale_date
uo_crosstab.of_group_date_field(/*field*/ "sale_date", /*part*/ "year")
uo_crosstab.of_group_date_field(/*field*/ "sale_date", /*part*/ "quarter")
uo_crosstab.of_group_date_field(/*field*/ "sale_date", /*part*/ "month")
// Poi incrociarli come qualsiasi altro campo: anno in colonne, trimestre sotto
uo_crosstab.of_add_col_field(/*field*/ "sale_date__year")
uo_crosstab.of_add_col_field(/*field*/ "sale_date__quarter")
La classifica delle dieci migliori regioni #
// Tenere solo le 10 regioni con il totale piu alto sulla prima misura
uo_crosstab.of_set_value_filter(/*field*/ "region", /*type*/ "top", /*a*/ 10, /*b*/ 0, /*measure_index*/ 1)
Esportare #
L'esportazione riprende esattamente la vista corrente: stessi filtri, stessi totali, stessa formattazione.
// Verso Excel: il file viene scritto direttamente nel percorso indicato
uo_crosstab.of_export_xlsx(/*path*/ "C:\temp\ventes.xlsx")
// event ue_xlsx_saved di uo_crosstab: (string as_path, boolean ab_ok, string as_error)
// inv_notif = un n_pbt_toaster dichiarato come variabile d'istanza della finestra
if ab_ok then
inv_notif.is_title = "Esportazione completata"
inv_notif.is_text = as_path
inv_notif.is_kind = inv_notif.KIND_SUCCESS
else
inv_notif.is_title = "Esportazione impossibile"
inv_notif.is_text = as_error
inv_notif.is_kind = inv_notif.KIND_ERROR
end if
inv_notif.of_show()
// Verso CSV: un file, come per Excel; ue_csv_saved conferma
uo_crosstab.of_export_csv(/*path*/ "C:\exports\ventes.csv")
Offrire viste salvate #
// Local variables
string ls_view
// Salvare la vista corrente : of_get_layout risponde subito
ls_view = uo_crosstab.of_get_layout()
// Conservare il contenuto COSI COM E : si riproduce senza trasformazioni.
of_save_view(is_current_view, ls_view)
// Piu tardi: riprodurre una vista salvata
uo_crosstab.of_set_layout(/*state_json*/ of_read_view("Ventes par region"))
Scendere al dettaglio dietro una cifra #
// event ue_cell_double_clicked di uo_crosstab: (string as_row_tuple_json, string as_col_tuple_json, integer ai_measure, double ad_value)
// I primi due argomenti descrivono l'incrocio (quali valori di righe,
// quali valori di colonne): quanto basta per ricostruire una query di dettaglio.
w_sales_detail lw_detail
// Aprire la finestra di dettaglio con l'incrocio come parametro
OpenWithParm(lw_detail, as_row_tuple_json + "|" + as_col_tuple_json)
I due tuple e ai_measure formano l'indirizzo della cella: of_get_cell_value lo rilegge più tardi, così come la tabella lo mostra in quel momento.
// ue_cell_double_clicked event of uo_crosstab : the address of the cell, read again later
// Local variables
double ld_value
// Read the cell again from its address : 0 when it exists
if uo_crosstab.of_get_cell_value(/*row_tuple_json*/ as_row_tuple_json, /*col_tuple_json*/ as_col_tuple_json, /*measure*/ ai_measure, /*value*/ ld_value) = 0 then
// ld_value is what the cell shows ; NULL for an empty cell
end if
Una cella si legge anche senza clic, attraverso i suoi membri: un tuple parziale designa un subtotale. E of_remove_field toglie un campo da tutte le sue aree in un colpo solo, filtri compresi.
// The sales of Nord in 2025, first measure of Values
// Local variables
double ld_north
// A partial address : the region and the year, no other member
uo_crosstab.of_get_cell_value(/*row_tuple_json*/ '{"region":"Nord"}', /*col_tuple_json*/ '{"year":"2025"}', /*measure*/ 1, /*value*/ ld_north)
// Take the year out of the table, filters included
uo_crosstab.of_remove_field(/*field*/ "year")
Buone pratiche #
- Chiami
of_from_datastoreuna sola volta per insieme di dati: riorganizzare la tabella in seguito non costa nulla, ritrasmettere i dati costa caro. - Imposti le etichette (
of_field("...").is_label) subito dopoof_from_datastore: seguono il campo dappertutto, anche nel pannello dei campi e nelle esportazioni. - Filtri lato SQL ciò che non è destinato a essere analizzato: il crosstab è rapido, ma un DataStore due volte più piccolo si apre due volte più in fretta.
of_clear_layout()svuota le aree senza ritrasmettere i dati: è la chiamata giusta per proporre più analisi sulla stessa origine.- Un campo data si incrocia sempre tramite
of_group_date_field, mai direttamente. - Lasci il pannello dei campi visibile sulle schermate di analisi, lo nasconda sui cruscotti fissi.
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.
| Membri | Ruolo | Descritto in |
|---|---|---|
of_count · of_keys_at · of_has | Percorrere ciò che il componente contiene | 3.2 Gli item |
of_reset | Riportare il componente a zero | 3.6 Riportare un componente a zero: of_reset() |
of_set_property · of_get_property · of_component_name | Pilotare una proprietà per nome | 3.1 Il motore delle proprietà |
of_register_shortcut · of_clear_shortcuts | Scorciatoie da tastiera del componente | 3.5 Le scorciatoie da tastiera |
of_is_created · of_is_ready · of_get_last_error | Se è nato, se è pronto, cosa è fallito | 3.7 Diagnostica |
of_save_as_png · of_save_as_jpg | Esportare il rendering in immagine | 3.8 Esportare il rendering come immagine |
of_set_redraw | Raggruppare le modifiche in un solo ridisegno | 3.10 Buone pratiche |
of_preload_icons | Icone mostrate senza ritardo | Visualizzazione istantanea: of_icon |
of_set_translation | Tradurre una dicitura del componente | 5.2 Adattare un'etichetta: of_set_translation |
of_focus_webview | Dare il focus al componente | 6.4 Tastiera e focus |
of_print · of_print_to_pdf | Stampare, o scrivere un PDF | 6.9 Stampare |
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.