PBToolboxAI v4 ← Site

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 #

Userobjectu_pbt_crosstab
Item-Klasse— (Felder werden über Methoden platziert)
WofürIhren Benutzern eine Kreuzauswertung Ihrer Daten bieten, die sie selbst umstellen, ohne SQL zu schreiben oder nach Excel auszuweichen
Grenze im Demomodus500 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.

BereichWas er enthältWirkung
ZeilenGruppierungsfelderEine Zeilenebene je Feld, einklappbar
SpaltenGruppierungsfelderEine Ebene von Spaltenkopfzeilen je Feld
WerteNumerische Felder und ihr AggregatWas in den Zellen berechnet wird
FilterAuswahlfelderEin 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 #

KonstanteWertFü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 #

EigenschaftTypStandardZweck
is_totals_positionstring"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_axisstring"cols"Ausrichtung der Kennzahlen, wenn es mehrere gibt: VALUES_COLS (nebeneinander in Spalten, Standard) oder VALUES_ROWS (untereinander in Zeilen)
is_currency_symbolstring""Die Währung, die das Menü Zahlenformat eines Wert-Chips anbietet, neben „Kein Symbol“ und „%“. Leer = die der Anzeigesprache ($ auf Englisch, € sonst)
is_thousandsstring"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_listbooleantrueZeigt das Feldpanel an, in dem der Benutzer die Tabelle mit der Maus umstellt
ib_row_subtotalsbooleantrueZeigt 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_subtotalsbooleantrueZeigt eine Zwischensumme je Spaltengruppe an
ib_row_grand_totalbooleantrueZeigt die Gesamtsummenzeile unter der Tabelle an (das Gegenstück zu ib_col_grand_total)
ib_col_grand_totalbooleantrueZeigt die Gesamtsummenspalte nach der Tabelle an (das Gegenstück zu ib_row_grand_total)
ib_copy_headersbooleantrueStrg+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_enabledbooleantrueAusgegraut: 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_stylestring""Visueller Stil der Komponente (Konstanten THEME_STYLE_*); leer = der der Anwendung, bei jeder Änderung übernommen
is_theme_modestring""Helle oder dunkle Variante (Konstanten THEME_MODE_*); leer = die der Anwendung, bei jeder Änderung übernommen
il_theme_accentlong-1Akzentfarbe dieser Komponente (-1 = Akzent der Anwendung, sonst der des Designs)
is_tooltipstring""Einfacher Tooltip beim Überfahren der Komponente
is_super_tooltip_titlestring""Titel des erweiterten Tooltips (hat Vorrang vor is_tooltip)
is_super_tooltip_textstring""Text des erweiterten Tooltips (Rich-Markup zulässig)
is_super_tooltip_imagestring""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.

EigenschaftTypStandardZweck
is_labelstringKopfzeile des DataWindowLesbare 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_showstring"normal"Was die Zelle anzeigt: "normal", "pctGrand" (% der Gesamtsumme), "pctRow" (% der Zeile), "pctCol" (% der Spalte), "running" (laufende Summe), "diff" (Abweichung zum Vorherigen)
is_conditional_formattingstring"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 #

MethodeZweck
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 #

MethodeZweck
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 #

MethodeZweck
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 #

MethodeZweck
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 #

MethodeZweck
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 #

MethodeZweck
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 ( ) → stringGibt 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 #

MethodeZweck
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 #

EventAusgelö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:

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 #

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.

MitgliederRolleBeschrieben in
of_count · of_keys_at · of_hasDurchlaufen, was die Komponente enthält3.2 Die Items
of_resetDie Komponente zurücksetzen3.6 Eine Komponente zurücksetzen: of_reset()
of_set_property · of_get_property · of_component_nameEine Eigenschaft über ihren Namen steuern3.1 Die Eigenschaften-Engine
of_register_shortcut · of_clear_shortcutsTastenkürzel der Komponente3.5 Tastenkombinationen
of_is_created · of_is_ready · of_get_last_errorOb sie entstanden ist, ob sie bereit ist, was fehlschlug3.7 Diagnose
of_save_as_png · of_save_as_jpgDie Darstellung als Bild exportieren3.8 Die Darstellung als Bild exportieren
of_set_redrawÄnderungen zu einem einzigen Neuzeichnen bündeln3.10 Best Practices
of_preload_iconsSymbole ohne VerzögerungSofortige Anzeige: of_icon
of_set_translationEine Beschriftung der Komponente übersetzen5.2 Eine Beschriftung anpassen: of_set_translation
of_focus_webviewDer Komponente den Fokus geben6.4 Tastatur und Fokus
of_print · of_print_to_pdfDrucken oder ein PDF schreiben6.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.


← Komponentenreferenz · Inhalt des Handbuchs