crosstab — u_pbt_crosstab #
← Komponentenreferenz · Inhalt des Handbuchs
Vollständige Crosstab-Tabelle: Bereiche für Zeilen / Spalten / Werte, gespeist aus einem DataStore, Aggregate, Filter, bedingte Formatierung, Datumsgruppierung, berechnete Kennzahlen und Exporte nach CSV / Excel.
▶ Live ansehen — Demoanwendung, Kachel Crosstab: die Vorschau, der zugehörige Code und diese Seite, nebeneinander.
Auf einen Blick #
| Userobject | u_pbt_crosstab |
| Item-Klasse | — (Felder werden über Methoden platziert) |
| Wofür | Ihren Benutzern eine Kreuzauswertung Ihrer Daten bieten, die sie selbst umstellen, ohne SQL zu schreiben oder nach Excel auszuweichen |
| Grenze im Demomodus | 500 verarbeitete Quellzeilen; CSV- und Excel-Exporte sowie Kopieren (Strg+C) deaktiviert — siehe Der Demomodus |
Das Prinzip #
Sie übergeben der Komponente einen flachen Datenbestand — einen DataStore, also jede beliebige Abfrage, die in Ihrer Anwendung bereits geschrieben ist. Um den Rest kümmert sich das Crosstab: Es leitet daraus die Feldliste ab, und Sie verteilen die Felder auf vier Bereiche.
| Bereich | Was er enthält | Wirkung |
|---|---|---|
| Zeilen | Gruppierungsfelder | Eine Zeilenebene je Feld, einklappbar |
| Spalten | Gruppierungsfelder | Eine Ebene von Spaltenkopfzeilen je Feld |
| Werte | Numerische Felder und ihr Aggregat | Was in den Zellen berechnet wird |
| Filter | Auswahlfelder | Ein Filter oberhalb der Tabelle, der auf alles angewendet wird |
Die gesamte Berechnung findet in der Komponente statt: Sind die Daten einmal übergeben, löst das Umstellen der Tabelle keinen einzigen Rückweg zur Datenbank oder zu PowerBuilder aus.
Schnellstart #
// Event open des Fensters
datastore lds
lds = create datastore
lds.dataobject = "d_sales"
lds.SetTransObject(SQLCA)
lds.Retrieve()
// 1. Daten uebergeben: die Felder werden aus den Spalten abgeleitet
uo_crosstab.of_from_datastore(/*data*/ lds)
// 2. Die Felder auf die Bereiche verteilen
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. Darstellen: Format der Betraege und Gesamtsummen
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 von uo_crosstab: (string as_row_tuple_json, string as_col_tuple_json, integer ai_measure, double ad_value)
// Der Benutzer moechte das Detail hinter einer Zahl: die passende Liste oeffnen.
of_open_detail(as_row_tuple_json, as_col_tuple_json)
Konstanten #
| Konstante | Wert | Für |
|---|---|---|
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 |
Die Aggregat-Konstanten werden auf der Komponente gelesen: uo_crosstab.AGG_SUM. Die eines Feldes (SHOW_*, CF_*) werden auf dem Handle des Feldes gelesen.
Eigenschaften #
| Eigenschaft | Typ | Standard | Zweck |
|---|---|---|---|
is_totals_position | string | "bottom" | Wo die Zeile der Gesamtsumme steht: TOTALS_BOTTOM (am Fuß, Standard) oder TOTALS_TOP (oben, direkt unter den Kopfzeilen). Nur die Gesamtsumme wandert: die Zwischensumme einer Gruppe bleibt auf der Zeile der Gruppe |
is_values_axis | string | "cols" | Ausrichtung der Kennzahlen, wenn es mehrere gibt: VALUES_COLS (nebeneinander in Spalten, Standard) oder VALUES_ROWS (untereinander in Zeilen) |
is_currency_symbol | string | "" | Die Währung, die das Menü Zahlenformat eines Wert-Chips anbietet, neben „Kein Symbol“ und „%“. Leer = die der Anzeigesprache ($ auf Englisch, € sonst) |
is_thousands | string | "locale" | Tausendertrennzeichen der Kennzahlen, die keines setzen (of_set_value_format mit leerem Trennzeichen) — dieselbe Einstellung wie das Menü Optionen des Rasters: THOUSANDS_LOCALE (das der Anzeigesprache, Standard), THOUSANDS_SPACE, THOUSANDS_NONE oder das Trennzeichen selbst (",", ".", " ") |
ib_field_list | boolean | true | Zeigt das Feldpanel an, in dem der Benutzer die Tabelle mit der Maus umstellt |
ib_row_subtotals | boolean | true | Zeigt die Zwischensumme jeder Zeilengruppe an, auf der Zeile der Gruppe selbst, über ihren Elementen; ausgeschaltet behält diese Zeile ihre Beschriftung ohne Zahl |
ib_col_subtotals | boolean | true | Zeigt eine Zwischensumme je Spaltengruppe an |
ib_row_grand_total | boolean | true | Zeigt die Gesamtsummenzeile unter der Tabelle an (das Gegenstück zu ib_col_grand_total) |
ib_col_grand_total | boolean | true | Zeigt die Gesamtsummenspalte nach der Tabelle an (das Gegenstück zu ib_row_grand_total) |
ib_copy_headers | boolean | true | Strg+C kopiert die Kopfzeilen mit den ausgewählten Zellen: die Spaltennamen in einer ersten Zeile (die Kennzahl wird dort nur genannt, wenn die Tabelle sie zeigt: mehrere Werte oder kein Feld in Spalten) und das Element jeder Zeile — sein vollständiger Pfad, „Nord / Lille“ — in einer ersten Spalte, deren Ecke die Namen der Zeilenfelder trägt („region / ville“). Ein Einfügen in eine Tabellenkalkulation sagt so, was die Zahlen sind. false kopiert nur die Zahlen. Live gelesen, von of_reset auf true zurückgesetzt |
ib_enabled | boolean | true | Ausgegraut: das Raster zeigt weiterhin seine Zahlen — eine leere Crosstab-Tabelle ist etwas anderes als eine von der Anwendung abgeschaltete — reagiert aber nicht mehr auf den Zeiger |
is_theme_style | string | "" | Visueller Stil der Komponente (Konstanten THEME_STYLE_*); leer = der der Anwendung, bei jeder Änderung übernommen |
is_theme_mode | string | "" | Helle oder dunkle Variante (Konstanten THEME_MODE_*); leer = die der Anwendung, bei jeder Änderung übernommen |
il_theme_accent | long | -1 | Akzentfarbe dieser Komponente (-1 = Akzent der Anwendung, sonst der des Designs) |
is_tooltip | string | "" | Einfacher Tooltip beim Überfahren der Komponente |
is_super_tooltip_title | string | "" | Titel des erweiterten Tooltips (hat Vorrang vor is_tooltip) |
is_super_tooltip_text | string | "" | Text des erweiterten Tooltips (Rich-Markup zulässig) |
is_super_tooltip_image | string | "" | Bild des erweiterten Tooltips |
Eigenschaften eines Feldes #
of_field (string as_field) liefert das Handle eines Feldes: Sie holen es einmal und steuern das Feld anschließend über seine Eigenschaften. Das Handle wird beim ersten Aufruf erzeugt und danach wiederverwendet.
| Eigenschaft | Typ | Standard | Zweck |
|---|---|---|---|
is_label | string | Kopfzeile des DataWindow | Lesbare Bezeichnung des Feldes ("amount" → "Umsatz"). Standardmäßig der Kopfzeilentext der Spalte im DataWindow, sonst ihr Name; eine leere Zeichenkette stellt ihn wieder her. Von Ihrem Code gesetzt, übersteht sie of_from_datastore |
is_show | string | "normal" | Was die Zelle anzeigt: "normal", "pctGrand" (% der Gesamtsumme), "pctRow" (% der Zeile), "pctCol" (% der Spalte), "running" (laufende Summe), "diff" (Abweichung zum Vorherigen) |
is_conditional_formatting | string | "none" | Bedingte Formatierung: CF_NONE, CF_SCALE (Farbskala), CF_BARS (Balken in der Zelle) oder CF_ICONS (ein Pfeil je Drittel: aufwärts, gleich, abwärts) |
Die Werte von is_show und is_conditional_formatting stehen auch als Konstanten auf dem Handle zur Verfügung (SHOW_PCT_COL, CF_SCALE…). Vor dem Einfügen des Feldes in Werte gesetzt, werden sie aufbewahrt, so zurückgelesen und bei seinem Eintreffen angewendet.
// Local variables
n_pbt_crosstab_field lnv_field
// Das Betragsfeld : seine Bezeichnung und eine Farbskala
lnv_field = uo_crosstab.of_field(/*field*/ "amount")
lnv_field.is_label = "Umsatz"
lnv_field.is_conditional_formatting = lnv_field.CF_SCALE
⚠️ Inkompatible Änderung. Diese Eigenschaft hieß
is_cf: Die Abkürzung sagte an der Aufrufstelle nichts aus. Der alte Name existiert nicht mehr — Code, der ihn verwendet, lässt sich nicht kompilieren. Die Ersetzung ist mechanisch:is_cf→is_conditional_formatting, ohne Änderung der Werte oder des Verhaltens.
Methoden #
Speisen und benennen #
| Methode | Zweck |
|---|---|
of_from_datastore (datastore ads_data) | Übergibt den Datenbestand: Die Felder werden aus den Spalten des DataStore abgeleitet, ihre Bezeichnung aus dem Text der Kopfzeile. Ein Text mit Tabulator oder Zeilenumbruch bleibt in seiner Zeile; ein leerer Wert (NULL, leerer Text) ist ein einziges Element (leer), zuletzt einsortiert; die mit is_label gesetzten Bezeichnungen überstehen ein Neuladen. Gibt 0 zurück, sobald die Daten geladen sind, -5, wenn der DataStore ungültig ist oder keine Spalte besitzt, -2, wenn die Komponente nicht erstellt ist |
of_field (string as_field) | Liefert das Handle eines Feldes, um es zu bezeichnen oder zu formatieren (siehe Eigenschaften eines Feldes) |
Die Tabelle aufbauen #
| Methode | Zweck |
|---|---|
of_clear_layout ( ) | Leert alle vier Bereiche: Die Tabelle wird wieder leer, die Daten bleiben geladen. Gibt 0 zurück, sobald angewendet, -2, wenn die Komponente nicht erstellt ist |
of_add_row_field (string as_field) | Fügt ein Feld im Bereich Zeilen hinzu (die Reihenfolge der Aufrufe bestimmt die Reihenfolge der Ebenen). Ein Feld, das bereits in Werte steht, bleibt dort: es kann in beiden stehen (eine eindeutige Zählung je Element). Gibt 0 zurück, sobald angewendet, -5 für ein Feld, das die Daten nicht enthalten, oder für eine berechnete Kennzahl (sie gehört nur in Werte), -2, wenn die Komponente nicht erstellt ist |
of_add_col_field (string as_field) | Fügt ein Feld im Bereich Spalten hinzu. Ein Feld, das bereits in Werte steht, bleibt dort: es kann in beiden stehen (eine eindeutige Zählung je Element). Gibt 0 zurück, sobald angewendet, -5 für ein Feld, das die Daten nicht enthalten, oder für eine berechnete Kennzahl (sie gehört nur in Werte), -2, wenn die Komponente nicht erstellt ist |
of_add_value_field (string as_field, string as_agg) | Fügt eine Kennzahl im Bereich Werte hinzu, samt ihrem Aggregat (AGG_*, leer = AGG_SUM). Das Feld behält seinen Platz in Zeilen, Spalten oder Filter. Gibt 0 zurück, sobald angewendet, -5 für ein Feld, das die Daten nicht enthalten, oder ein anderes Aggregat, -2, wenn die Komponente nicht erstellt ist |
of_add_filter_field (string as_field) | Fügt ein Feld im Bereich Filter oberhalb der Tabelle hinzu. Gibt 0 zurück, sobald angewendet, -5 für ein Feld, das die Daten nicht enthalten, oder für eine berechnete Kennzahl (sie gehört nur in Werte), -2, wenn die Komponente nicht erstellt ist |
of_remove_field (string as_field) | Nimmt ein Feld aus der Tabelle: aus allen Bereichen, in denen es steht (Zeilen, Spalten, Filter und jeder seiner Werte), samt seinen Filtern — wie „Entfernen“ in der Feldliste. Der Rest des Layouts bleibt, wie er ist, und ue_layout_changed meldet das neue. Gibt 0 zurück, sobald angewendet, -4, wenn das Feld in keinem Bereich steht, -5 für ein Feld, das die Daten nicht enthalten |
Die von of_add_value_field akzeptierten Aggregate werden von der Komponente als Konstanten bereitgestellt: AGG_SUM (Standard), AGG_COUNT, AGG_DISTINCT_COUNT (Zählung eindeutiger Werte, leere Zellen werden wie in Excel ignoriert), AGG_AVG, AGG_MIN, AGG_MAX.
Summen und Zwischensummen #
Summen werden über Eigenschaften eingestellt, siehe oben: ib_row_grand_total und ib_col_grand_total für die Gesamtsummen, ib_row_subtotals und ib_col_subtotals für die Zwischensummen, is_totals_position für die Lage der Gesamtsummenzeile.
Filtern #
| Methode | Zweck |
|---|---|
of_set_member_filter (string as_field, string as_values_tab) | Behält nur die aufgeführten Werte eines Feldes. Die Werte sind durch Tabulatoren getrennt (~t); eine leere Liste entfernt den Filter, wie of_set_member_order. Gibt 0 zurück, sobald angewendet, -5 für ein Feld, das die Daten nicht enthalten, -2, wenn die Komponente nicht erstellt ist |
of_clear_member_filter (string as_field) | Entfernt diesen Filter. Gibt 0 zurück, sobald angewendet, -5 für ein Feld, das die Daten nicht enthalten, -2, wenn die Komponente nicht erstellt ist |
of_set_value_filter (string as_field, string as_type, double ad_a, double ad_b, integer ai_measure_index) | Filtert auf die Summe der Kennzahl Nr. ai_measure_index (die erste = 1): VALUEFILTER_TOP oder VALUEFILTER_BOTTOM (die ersten oder letzten ad_a), VALUEFILTER_GT, VALUEFILTER_LT (über, unter ad_a), VALUEFILTER_BETWEEN (zwischen ad_a und ad_b). Gibt 0 zurück, sobald angewendet, -5 für ein Feld, das die Daten nicht enthalten, einen anderen Typ oder eine Position ohne Kennzahl in Werte, -2, wenn die Komponente nicht erstellt ist |
of_clear_value_filter (string as_field) | Entfernt diesen Filter. Gibt 0 zurück, sobald angewendet, -5 für ein Feld, das die Daten nicht enthalten, -2, wenn die Komponente nicht erstellt ist |
of_set_label_filter (string as_field, string as_type, double ad_a, double ad_b) | Numerischer Filter auf den Wert des Feldes selbst: LABEL_GT, LABEL_LT, LABEL_BETWEEN. Gibt 0 zurück, sobald angewendet, -5 für ein Feld, das die Daten nicht enthalten, oder einen anderen Typ, -2, wenn die Komponente nicht erstellt ist |
of_set_label_filter (string as_field, string as_type, string as_a, string as_b) | Textfilter auf den Wert des Feldes: LABEL_CONTAINS, LABEL_BEGINS, LABEL_ENDS (as_a, ohne Beachtung der Groß-/Kleinschreibung; as_b wird nicht verwendet). Gibt 0 zurück, sobald angewendet, -5 für ein Feld, das die Daten nicht enthalten, einen anderen Typ oder einen leeren Text, -2, wenn die Komponente nicht erstellt ist |
of_clear_label_filter (string as_field) | Entfernt diesen Filter. Gibt 0 zurück, sobald angewendet, -5 für ein Feld, das die Daten nicht enthalten, -2, wenn die Komponente nicht erstellt ist |
Formatieren #
| Methode | Zweck |
|---|---|
of_set_value_format (string as_field, integer ai_decimals, string as_thousands, string as_suffix { , boolean ab_symbol_before }) | Format einer Kennzahl: Anzahl der Dezimalstellen (0 bis 6), Tausendertrennzeichen (",", ".", " ": das Trennzeichen selbst, "," mit einem Dezimalpunkt und "." mit einem Dezimalkomma; "space" schmales Leerzeichen, "none", "locale" das der Anzeigesprache; "" lässt die Kennzahl auf is_thousands, dem Standard des Menüs Optionen), Symbol — standardmäßig hinter der Zahl (1 234 EUR), DAVOR, wenn ab_symbol_before true ist ($1,234). Die drei Einstellungen gehören zu DIESER Kennzahl; vor dem Einfügen des Feldes in Werte gesetzt, werden sie aufbewahrt und bei seinem Eintreffen angewendet. Gibt 0 zurück, sobald angewendet, -5 für ein Feld, das die Daten nicht enthalten, -2, wenn die Komponente nicht erstellt ist |
of_clear_value_format (string as_field) | Zurück zum Standardformat. Gibt 0 zurück, sobald angewendet, -5 für ein Feld, das die Daten nicht enthalten, -2, wenn die Komponente nicht erstellt ist |
of_set_member_order (string as_field, string as_values_tab) | Den Werten eines Feldes vorgegebene Anzeigereihenfolge (getrennt durch ~t); eine leere Zeichenkette stellt die natürliche Reihenfolge wieder her. Gibt 0 zurück, sobald angewendet, -5 für ein Feld, das die Daten nicht enthalten, -2, wenn die Komponente nicht erstellt ist |
Datumsangaben und berechnete Felder #
| Methode | Zweck |
|---|---|
of_group_date_field (string as_field, string as_part) | Erzeugt ein aus einer Spalte vom Typ date, datetime oder timestamp abgeleitetes Feld (eine reine Uhrzeit hat kein Datum zum Gruppieren): DATE_YEAR, DATE_QUARTER oder DATE_MONTH, benannt <Spalte>__<Teil>. Es reiht sich in die Feldliste ein und wird wie jedes andere verwendet. Gibt 0 zurück, sobald angewendet, -5 für ein Feld, das die Daten nicht enthalten, oder einen anderen Teil, -2, wenn die Komponente nicht erstellt ist |
of_add_calc_field (string as_name, string as_label, string as_formula) | Berechnetes Feld Zeile für Zeile ("[amount] * 0.8" = der Nettobetrag jedes Verkaufs, danach wie jede Spalte summiert), in jedem Bereich verwendbar. Nicht für ein Verhältnis von Summen (Durchschnittspreis): dafür of_add_calc_measure. Gibt 0 zurück, sobald angewendet, -5 bei einem ungültigen Argument, -2, wenn die Komponente nicht erstellt ist |
of_remove_calc_field (string as_name) | Entfernt ein berechnetes Feld. Gibt 0 zurück, sobald angewendet, -5, wenn kein berechnetes Feld diesen Namen trägt, -2, wenn die Komponente nicht erstellt ist |
of_add_calc_measure (string as_name, string as_label, string as_formula) | Berechnete Kennzahl Zelle für Zelle, auf den Summen ("[marge] / [ca]" = globale Margenquote). Wird ausschließlich im Bereich Werte platziert. Ihre Formel nennt nur Datenfelder: eine andere berechnete Kennzahl wird abgelehnt (ue_calc_field_error). Gibt 0 zurück, sobald angewendet, -5 bei einem ungültigen Argument, -2, wenn die Komponente nicht erstellt ist |
of_remove_calc_measure (string as_name) | Entfernt eine berechnete Kennzahl. Gibt 0 zurück, sobald angewendet, -5, wenn keine berechnete Kennzahl diesen Namen trägt, -2, wenn die Komponente nicht erstellt ist |
Eine Formel akzeptiert die Operatoren + - * / ( ), Zahlen und Felder in eckigen Klammern. Eine ungültige Formel löst ue_calc_field_error aus — nichts stürzt ab.
Aufklappen, speichern, exportieren #
| Methode | Zweck |
|---|---|
of_expand_all ( ) · of_collapse_all ( ) | Klappt alle Gruppen auf oder zu, Zeilen UND Spalten. Gibt 0 zurück, sobald angewendet, -2, wenn die Komponente nicht erstellt ist |
of_expand_to_level (integer ai_level) | Klappt bis zu einer bestimmten Ebene auf (1 = nur die erste Ebene). Gibt 0 zurück, sobald angewendet, -2, wenn die Komponente nicht erstellt ist |
of_get_layout ( ) → string | Gibt den vollständigen Zustand der Tabelle zurück — unverändert aufbewahren, dann über of_set_layout wiederherstellen |
of_set_layout (string as_state_json) | Stellt einen zuvor erhaltenen Zustand wieder her. Gibt 0 zurück, sobald angewendet, -5 für einen leeren Text oder einen, der kein JSON ist, -2, wenn die Komponente nicht erstellt ist |
of_get_cell_value (string as_row_tuple_json, string as_col_tuple_json, integer ai_measure, ref double ad_value) | Liest den Wert einer Zelle, den die Tabelle anzeigt (0,8 unter 80,0 %, die laufende Summe unter einer laufenden Summe). Ihre Zeile und ihre Spalte sind die Tupel, die ue_cell_double_clicked liefert — {"region":"Nord","city":"Lille"}, ein leeres Element null, {} (oder eine leere Zeichenkette) für die Gesamtsumme — und ai_measure ist die Position des Werts im Bereich Werte, ab 1. Ein Tupel nennt die Felder seines Bereichs vom ersten an: {"region":"Nord"} ist die Zwischensumme von Nord. Die Antwort hängt nicht von der Anzeige ab: ein eingeklappter Zweig oder ausgeblendete Zwischensummen werden trotzdem gelesen. Gibt 0 mit dem Wert in ad_value zurück (NULL für eine Zelle ohne Wert), -4, wenn die Tabelle diese Zelle nicht hat (ein Element oder ein Feld, das sie dort nicht zeigt), -5 für ein fehlerhaftes Tupel oder eine Position ohne Kennzahl, -2, wenn die Komponente nicht erstellt ist |
of_export_csv (string as_path) | Schreibt eine CSV-Datei der aktuellen Ansicht (UTF-8 mit BOM, Semikolon); ue_csv_saved bestätigt. Die Zahlen erhalten das Dezimaltrennzeichen der Anzeigesprache (ein Komma auf Französisch, Deutsch, Italienisch, Spanisch, Portugiesisch); eine Beschriftung, die als Formel gelesen würde (= + - @), wird mit einem vorangestellten Apostroph geschrieben. Das Gegenstück zu of_export_xlsx. Gibt 0 zurück, sobald angewendet, -5 bei einem ungültigen Argument, -2, wenn die Komponente nicht erstellt ist |
of_export_xlsx (string as_path) | Schreibt eine Excel-Datei der Tabelle, wie sie angezeigt wird, einschließlich Formatierung (auch rote negative Zahlen); ue_xlsx_saved bestätigt — oder lehnt mit Begründung ab über 16 384 Spalten oder 1 048 576 Zeilen, den Grenzen eines Excel-Blatts. Gibt 0 zurück, sobald angewendet, -5 bei einem ungültigen Argument, -2, wenn die Komponente nicht erstellt ist |
Gemeinsame #
| Methode | Zweck |
|---|---|
of_reset ( ) | Versetzt die Komponente in ihren Neuzustand zurück. Gibt 0 zurück, sobald angewendet, -2, wenn die Komponente nicht erstellt ist |
of_set_redraw (boolean) | Fasst eine Folge von Änderungen zu einer einzigen Darstellung zusammen. Gibt 0 zurück, sobald angewendet, -2, wenn die Komponente nicht erstellt ist |
of_save_as_png (string) · of_save_as_jpg (string) | Exportiert die Darstellung als Bild. Gibt 0 zurück, -2, wenn die Komponente nicht erstellt ist, -4, wenn die Aufnahme fehlschlägt, -5 bei leerem Pfad |
Events #
| Event | Ausgelöst wenn |
|---|---|
ue_layout_changed (string as_layout_json) | Der Benutzer hat die Tabelle umgestellt (ein Feld verschoben, ein Aggregat geändert, eine Spalte sortiert, eine Gruppe eingeklappt…): alles, was of_get_layout speichert |
ue_cell_double_clicked (string as_row_tuple_json, string as_col_tuple_json, integer ai_measure, double ad_value) | Doppelklick auf eine Zelle: Die ersten beiden Argumente beschreiben die Kreuzung ({"region":"Nord","city":"Lille"}, ein leeres Element ist dort null, {} für die Gesamtsumme), ai_measure die Position des doppelt angeklickten Werts im Bereich Werte, ab 1, und ad_value den Wert, den die Zelle anzeigt — 0.8 unter „80,0 %“, die laufende Summe unter einer laufenden Summe — oder NULL für eine leere Zelle. Die beiden Tupel und ai_measure bilden die Adresse, die of_get_cell_value wieder liest. Das ist der Einstiegspunkt für ein Detail |
ue_csv_saved (string as_path, boolean ab_ok, string as_error) | Die CSV-Datei wurde geschrieben — oder nicht, und as_error sagt warum |
ue_xlsx_saved (string as_path, boolean ab_ok, string as_error) | Die Excel-Datei wurde geschrieben — oder nicht, und as_error sagt warum |
ue_calc_field_error (string as_field, string as_message) | Die Formel eines berechneten Feldes oder einer berechneten Kennzahl ist ungültig |
ue_copy (string as_tsv) | Der Benutzer hat eine Zellauswahl kopiert (Strg+C): Es liegt an Ihnen, sie in die Zwischenablage zu legen. as_tsv ist ein tabulatorgetrennter Text, der standardmäßig die Kopfzeilen enthält — die Spaltennamen in einer ersten Zeile, das Element jeder Zeile (sein vollständiger Pfad, „Nord / Lille“) in einer ersten Spalte — oder nur die Zahlen mit ib_copy_headers = false. Im Demomodus ist Kopieren ein Export: abgelehnt, und das Raster sagt es |
ue_ready ( ) | Die Komponente ist fertig geladen; alles zuvor Gesendete wurde nachgespielt |
ue_runtime_missing ( ) | Die WebView2-Runtime fehlt: die Komponente bleibt leer |
ue_bg_color (long al_color) | Die Komponente hat ihre Design-Hintergrundfarbe berechnet; das Userobject hat sie bereits übernommen (backcolor) |
Was der Benutzer ohne eine einzige Zeile Code tun kann #
Die Tabelle ist lebendig: Genau darin liegt der Sinn der Komponente. Bei eingeblendetem Feldpanel (ib_field_list = true) kann der Benutzer:
- ein Feld von einem Bereich in einen anderen ziehen und die Kreuzauswertung beliebig umstellen;
- das Aggregat einer Kennzahl ändern (Summe, Mittelwert, Anzahl…);
- die Werte eines Feldes über eine Ankreuzliste filtern;
- eine Zeilen- oder Spaltengruppe ein- oder ausklappen;
- über eine Kopfzeile sortieren;
- einen Zellblock auswählen und kopieren, samt Kopfzeilen, damit ein Einfügen in eine Tabellenkalkulation sagt, was die Zahlen sind (
ib_copy_headers).
Jede dieser Aktionen wird in ue_layout_changed gemeldet: Zusammen mit of_get_layout / of_set_layout können Sie Ihren Benutzern damit „gespeicherte Ansichten“ anbieten.
Über die Tastatur. Jede dieser Gesten ist ohne Maus erreichbar: Tab führt auf ein Feld, ein Zuklapp-Dreieck oder eine sortierbare Kopfzeile, Eingabe oder Leertaste löst sie aus. Auf einem Feld öffnet das dessen Menü — jenes mit Zu Zeilen / Spalten / Werten / Filtern hinzufügen und Entfernen: der gesamte Aufbau der Tabelle läuft darüber. Umschalt+F10 oder die Menütaste öffnen dieses Menü ebenfalls, und der Fokus folgt dem gerade verschobenen Feld, auch in eine andere Zone.
Beispiele #
Ein vollständiger Vertriebsbericht #
// Zeilen: Region, dann Stadt innerhalb jeder Region
uo_crosstab.of_clear_layout()
uo_crosstab.of_add_row_field(/*field*/ "region")
uo_crosstab.of_add_row_field(/*field*/ "city")
// Spalten: eine je Jahr
uo_crosstab.of_add_col_field(/*field*/ "year")
// Zellen: der Gesamtbetrag
uo_crosstab.of_add_value_field(/*field*/ "amount", /*agg*/ uo_crosstab.AGG_SUM)
// Darstellung: lesbare Betraege, Zwischen- und Gesamtsummen
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
// Die Zellen einfaerben, um grosse Betraege auf einen Blick zu erkennen
uo_crosstab.of_field(/*field*/ "amount").is_conditional_formatting = n_pbt_crosstab_field.CF_SCALE
Lesbare Bezeichnungen #
Ihre Spalten heißen oft mt_ht oder cd_reg. Benennen Sie sie ein für alle Mal um, direkt nach of_from_datastore.
// Zuerst die Daten : die Felder tragen die Namen der Spalten
uo_crosstab.of_from_datastore(/*data*/ lds)
// Dann eine lesbare Bezeichnung fuer jedes Feld
uo_crosstab.of_field(/*field*/ "region").is_label = "Region"
uo_crosstab.of_field(/*field*/ "city").is_label = "Stadt"
uo_crosstab.of_field(/*field*/ "category").is_label = "Kategorie"
uo_crosstab.of_field(/*field*/ "year").is_label = "Jahr"
uo_crosstab.of_field(/*field*/ "amount").is_label = "Umsatz"
uo_crosstab.of_field(/*field*/ "quantity").is_label = "Menge"
Anteile statt Beträge auswerten #
// Local variables
n_pbt_crosstab_field lnv_amount
// Mit leeren Bereichen beginnen, dann die Felder platzieren
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)
// Nur zwei Kategorien auf dem Bildschirm behalten (Werte durch einen Tabulator getrennt)
uo_crosstab.of_set_member_filter(/*field*/ "category", /*values_tab*/ "Informatique~tMobilier")
// Das Betragsfeld, um seine Anzeige einzustellen
lnv_amount = uo_crosstab.of_field(/*field*/ "amount")
// Den Anteil jeder Zelle an der Summe ihrer Spalte anzeigen
lnv_amount.is_show = lnv_amount.SHOW_PCT_COL
// Ein kleiner Balken in jeder Zelle, um die Anteile auf einen Blick zu vergleichen
lnv_amount.is_conditional_formatting = lnv_amount.CF_BARS
Eine eigene Kennzahl: der Durchschnittspreis #
Eine berechnete Kennzahl wird auf den Summen jeder Zelle ausgewertet, nicht Zeile für Zeile: Genau das macht ein Verhältnis korrekt.
// Mit leeren Bereichen beginnen, dann die Felder platzieren
uo_crosstab.of_clear_layout()
uo_crosstab.of_add_row_field(/*field*/ "region")
// Die beiden Summen, die als Grundlage der Berechnung dienen
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)
// Durchschnittspreis = Gesamtbetrag geteilt durch Gesamtmenge
uo_crosstab.of_add_calc_measure(/*name*/ "avg_price", /*label*/ "Durchschnittspreis", /*formula*/ "[amount] / [quantity]")
uo_crosstab.of_set_value_format(/*field*/ "avg_price", /*decimals*/ 2, /*thousands*/ "locale", /*suffix*/ "$", /*symbol_before*/ true)
// Dann wie jedes Feld unter die Werte stellen (das Aggregat zaehlt nicht: eine Kennzahl wird berechnet)
uo_crosstab.of_add_value_field(/*field*/ "avg_price", /*agg*/ uo_crosstab.AGG_SUM)
// Event ue_calc_field_error von uo_crosstab: (string as_field, string as_message)
// Ungueltige Formel: warnen, ohne etwas zu zerstoeren, die Tabelle bleibt sichtbar.
uo_status.of_panel(/*key*/ "main").is_text = "Formel " + as_field + ": " + as_message
Nach Monat, Quartal oder Jahr auswerten #
Eine Datumsspalte lässt sich nicht unverändert kreuzen — jeder einzelne Tag ergäbe eine eigene Zeile. Leiten Sie zuerst die gewünschte Ebene ab.
// Drei aus der Spalte sale_date abgeleitete Felder erzeugen
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")
// Dann wie jedes andere Feld kreuzen: Jahr in den Spalten, Quartal darunter
uo_crosstab.of_add_col_field(/*field*/ "sale_date__year")
uo_crosstab.of_add_col_field(/*field*/ "sale_date__quarter")
Die Rangliste der zehn besten Regionen #
// Nur die 10 Regionen mit der hoechsten Summe der ersten Kennzahl behalten
uo_crosstab.of_set_value_filter(/*field*/ "region", /*type*/ "top", /*a*/ 10, /*b*/ 0, /*measure_index*/ 1)
Exportieren #
Der Export übernimmt exakt die aktuelle Ansicht: dieselben Filter, dieselben Summen, dieselbe Formatierung.
// Nach Excel: die Datei wird direkt unter dem angegebenen Pfad geschrieben
uo_crosstab.of_export_xlsx(/*path*/ "C:\temp\ventes.xlsx")
// Event ue_xlsx_saved von uo_crosstab: (string as_path, boolean ab_ok, string as_error)
// inv_notif = ein n_pbt_toaster, als Instanzvariable des Fensters deklariert
if ab_ok then
inv_notif.is_title = "Export abgeschlossen"
inv_notif.is_text = as_path
inv_notif.is_kind = inv_notif.KIND_SUCCESS
else
inv_notif.is_title = "Export nicht möglich"
inv_notif.is_text = as_error
inv_notif.is_kind = inv_notif.KIND_ERROR
end if
inv_notif.of_show()
// Nach CSV: eine Datei, wie bei Excel; ue_csv_saved bestaetigt
uo_crosstab.of_export_csv(/*path*/ "C:\exports\ventes.csv")
Gespeicherte Ansichten anbieten #
// Local variables
string ls_view
// Aktuelle Ansicht sichern : of_get_layout antwortet sofort
ls_view = uo_crosstab.of_get_layout()
// Den Inhalt UNVERAENDERT aufbewahren: er wird ohne Umwandlung wieder abgespielt.
of_save_view(is_current_view, ls_view)
// Spaeter: eine gespeicherte Ansicht wieder abspielen
uo_crosstab.of_set_layout(/*state_json*/ of_read_view("Ventes par region"))
Hinter einer Zahl ins Detail gehen #
// Event ue_cell_double_clicked von uo_crosstab: (string as_row_tuple_json, string as_col_tuple_json, integer ai_measure, double ad_value)
// Die ersten beiden Argumente beschreiben die Kreuzung (welche Zeilenwerte,
// welche Spaltenwerte): genug, um eine Detailabfrage neu aufzubauen.
w_sales_detail lw_detail
// Das Detailfenster mit der Kreuzung als Parameter oeffnen
OpenWithParm(lw_detail, as_row_tuple_json + "|" + as_col_tuple_json)
Die beiden Tupel und ai_measure bilden die Adresse der Zelle: of_get_cell_value liest sie später wieder, so wie die Tabelle sie in diesem Moment anzeigt.
// 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
Eine Zelle lässt sich auch ohne Klick über ihre Elemente lesen: ein unvollständiges Tupel bezeichnet eine Zwischensumme. Und of_remove_field nimmt ein Feld auf einmal aus all seinen Bereichen, Filter inbegriffen.
// 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")
Best Practices #
- Rufen Sie
of_from_datastorenur ein einziges Mal je Datenbestand auf: Die Tabelle danach umzustellen kostet nichts, die Daten erneut zu übergeben ist teuer. - Setzen Sie die Bezeichnungen (
of_field("...").is_label) direkt nachof_from_datastore: Sie folgen dem Feld überallhin, auch in das Feldpanel und in die Exporte. - Filtern Sie auf SQL-Seite weg, was nicht ausgewertet werden soll: Das Crosstab ist schnell, aber ein halb so großer DataStore öffnet sich doppelt so schnell.
of_clear_layout()leert die Bereiche, ohne die Daten erneut zu übergeben: Das ist der richtige Aufruf, um mehrere Auswertungen auf derselben Quelle anzubieten.- Ein Datumsfeld wird immer über
of_group_date_fieldgekreuzt, niemals direkt. - Lassen Sie das Feldpanel auf Auswertungsbildschirmen sichtbar und blenden Sie es auf festen Dashboards aus.
Vom gemeinsamen Sockel geerbt #
Diese Mitglieder gibt es bei jeder visuellen Komponente — sie sind nicht dieser eigen. Sie werden einmal in den übergreifenden Kapiteln beschrieben; diese Tabelle sagt nur, wo man sie liest.
| Mitglieder | Rolle | Beschrieben in |
|---|---|---|
of_count · of_keys_at · of_has | Durchlaufen, was die Komponente enthält | 3.2 Die Items |
of_reset | Die Komponente zurücksetzen | 3.6 Eine Komponente zurücksetzen: of_reset() |
of_set_property · of_get_property · of_component_name | Eine Eigenschaft über ihren Namen steuern | 3.1 Die Eigenschaften-Engine |
of_register_shortcut · of_clear_shortcuts | Tastenkürzel der Komponente | 3.5 Tastenkombinationen |
of_is_created · of_is_ready · of_get_last_error | Ob sie entstanden ist, ob sie bereit ist, was fehlschlug | 3.7 Diagnose |
of_save_as_png · of_save_as_jpg | Die Darstellung als Bild exportieren | 3.8 Die Darstellung als Bild exportieren |
of_set_redraw | Änderungen zu einem einzigen Neuzeichnen bündeln | 3.10 Best Practices |
of_preload_icons | Symbole ohne Verzögerung | Sofortige Anzeige: of_icon |
of_set_translation | Eine Beschriftung der Komponente übersetzen | 5.2 Eine Beschriftung anpassen: of_set_translation |
of_focus_webview | Der Komponente den Fokus geben | 6.4 Tastatur und Fokus |
of_print · of_print_to_pdf | Drucken oder ein PDF schreiben | 6.9 Drucken |
Zwei Helfer werden nicht geerbt: of_icon und of_escape_markup liegen auf n_pbt_utils. Deklarieren Sie eines — n_pbt_utils lnv_utils, nichts zu erzeugen — und rufen Sie sie darauf auf.