Bei der Überblicksdarstellung von Listen und Datensammlungen ist man häufig auf Tabellen angewiesen. Sei es, dass man die Inhalte einer Datenbankabfrage anzeigen möchte oder dass man wie auch immer generierte oder eingelesene Listen benötigt, die angeschaut oder sortiert werden sollen, in denen Änderungen gemacht werden sollen oder einzelne Elemente ausgewählt und im Detail betrachtet werden sollen. LiveCode stellt uns hierfür eine sehr leistungsfähige Komponente zur Verfügung: DataGrid kann wirklich fast alles, was man jemals braucht, ist aber im Vergleich zu vielen anderen LiveCode-Objekten erst einmal nicht ganz so intuitiv zu konfigurieren und zu verwenden.

Das liegt natürlich auch an seiner Komplexität. Eine DataGrid-Komponente ist bei LiveCode eine Objektgruppe (group), die eine Menge eigener Properties, Methoden und Funktionen enthält. Man kann fast alles darin indivduell konfigurieren: Anzahl der Zeilen und Spalten, Zeilenhöhen, Spaltenbreiten, Schriftarten, Hintergrundfarben, abwechselnd gefärbte Zeilen, Überschriften, automatische Sortierung, Auswahlmöglichkeiten, Bearbeitung usw.

Wenn man möchte, kann man sogar das Template für die Tabelle nach eigenen Vorstellungen bearbeiten und damit zusätzliche Objekte in die Tabelle eingliedern: So kann man Buttons, Grafiken, Checkboxen in die Tabelle einfügen sowie ein komplett eigenes Verhalten für jede Zelle definieren. Aber soweit wollen wir hier noch nicht gehen. Auch mit den enthaltenen Grundfunktionen kann man schon eine Menge machen, wenn man nur weiß, wie es geht.

Beginnen wir also ganz simpel. Starte einen neuen LiveCode-Stack, mache ihn schön groß und ziehe eine DataGrid-Komponente hinein.

Im Property Inspector kannst Du nun zahlreiche Grundeinstellungen für die Tabelle setzen. Zum Beispiel die Hintergrundfarbe, den Rahmen, ob die Tabelle abwechselnde Hintergrundfarben für die Zeilen hat und welche Farben das sein sollen, ob man die Inhalte der Tabelle per Doppelklick ändern können soll, die Höhe der Tabellenzeilen, ob mehrere Zeilen gleichzeitig selektierbar sein sollen, ob die vertikale und horizontale Scrollleiste angezeigt werden soll. Ein paar Eigenschaften fehlen im Inspector jedoch - die werden bei Bedarf per Skript gesetzt. Dazu komme ich später.

Erst einmal stellt sich die Frage: Wie bekommst Du nun überhaupt Daten in diese Tabelle?

Nun ja, wir haben dafür zwei Möglichkeiten. Die erste wäre es, die Daten über den Property Inspector manuell hineinzuschreiben. Nehmen wir an, wir möchten eine Liste mit Namen, E-Mail und Telefon von Personen erstellen.

Was wir zunächst wissen müssen: Im DataGrid gibt es die Property dgText  - das steht für "DataGrid Text" und darin befindet sich der gesamte Text für den Datenbereich der Tabelle, nicht aber die Spaltenüberschriften. Die werden über separate Properties verwaltet.

Schreiben wir mal drei Datenzeilen separat in unser DataGrid: Also Doppelklick auf die Tabelle, die wir gleich mal mit "tabelle" benennen können. Dann gehen wir auf den Contents-Reiter und schreiben den dgtext, hier im Beispiel die drei Zeilen hinein:

Wichtig dabei ist: Die einzelnen Spalteninhalte werden im internen DataGrid-Format durch Tabulatorzeichen (tab) voneinander getrennt, die Zeilen werden durch RETURN getrennt.

So sieht das dann in der Tabelle aus (die mittlere Spalte habe ich mit der Maus etwas verbreitert).


Daten per Skript einfügen

Wenn wir diese Daten stattdessen per Skript einfügen wollen (was ja normalerweise der Fall ist) geht das prinzipiell genauso. Wir müssen das Property dgtext der Tabelle auf eine Zeichenkette mit unseren Daten setzen - und diese Daten müssen die Inhalte der Zeilen und Spalten im selben Format wie oben beschrieben  (TAB für Spalten und RETURN für Zeilen) enthalten.

put "Hauke Fehr"&tab&"fehr@fehr-media.de"&tab&"0123-4567890"&return into meineDaten
put "Erwin Mayer"&tab&"erwinmayer@web.de"&tab&"0173-47367463"&return after meineDaten
put "Otto Müller"&tab&"otto@muellerweb.de"&tab&"0800-3243434" after meineDaten
set the dgtext of group "tabelle" to meineDaten

So würde man zum Beispiel die obigen Daten per Skript in den Text der Tabelle einfügen. Das würde einwandfrei funktionieren, aber in der Regel werden die Daten, die man anzeigen möchte, natürlich zuvor berechnet oder aus einer Datenbank, einer Datei oder einer Liste ausgelesen und dann von LiveCode entsprechend aufbereitet, bevor sie dem dgtext der Tabelle zugewiesen werden. Ein Beispiel, wie man eine Datenbank ausliest, so dass der Ergebnistext ohne weitere Aufbereitung direkt in den dgText eines DataGrid übernommen werden kann, gibt es im Beitrag Keine Angst vor Datenbanken in diesem Blog.

Du könntest aber auch zum Beispiel eine externe CSV-Datei in eine Variable einlesen und sie dann sehr einfach für unser DataGrid aufbereiten. Eine CSV-Liste trennt die Datensätze ja per Komma und nicht durch Tabulator. Also musst Du die Kommas durch tab-Zeichen ersetzen und kannst die Liste dann direkt zuweisen:

replace comma with tab in meineCSVListe
set the dgtext of group "tabelle" to meineCSVListe

Hier noch eine Ergänzung von Klaus:

Durch den Zusatz dgtext[TRUE] kann man dem Datagrid Daten zuweisen, die eine andere Reihenfolge der Spalten aufweisen als bereits im Datagrid erstellt, sofern die erste Zeile die korrekten (also im DataGrid angelegten) Namen der Spalten enthält..

Als Beispiel nehmen wir ein Datagrid mit zwei Spalten namens "name" (Spalte 1) und "id" (Spalte 2)
Daten werden nun so zugewiesen:
...
put "Klaus" & TAB & "0815" into tData
set the dgtext of group "datagrid" to tData
...

Nun haben oder bekommen wir eine CSV Datei, die so aussieht:
id TAB name
0815 TAB Klaus
4711 TAB Kölle Alaaf
...
Also definitiv eine andere Reihenfolge als bereits in unseren Datagrid eingestellt.

Wir brauchen nun weder die CSV Datei noch das Datagrid selber zu ändern, sondern können nun Folgendes skripten:
...
put url("file:" & pfad_zur_csv_datei_mit_anderer_reihenfolge) into tData
set the dgtext[TRUE] of grp "datagrid" to tData
...
Und das Behaviour der Datagrid Library korrigiert die andere Reihenfolge automatisch.


Spaltenüberschriften setzen

Du kannst die Überschriften ebenso manuell setzen wie die Inhalte. Das ist oft sinnvoll, wenn Du zum Beispiel die Inhalte einer Datenbank in die Tabelle einlesen willst. Dabei stehen ja die Überschriften der Spalten fest, nur der Inhalt ändert sich je nach Datenbankanfrage.

Doppelklicke die Tabelle und gehe auf den Reiter Columns (das ist der vierte von links).

Hier kannst Du jeder Spalte einen Namen (mit dem Du dann später per Property auf sie zugreifen kannst) und ein Label (das ist das, was sichtbar in der Kopfzeile der Tabelle steht) zuweisen.

Du kannst gleichzeitig hier auch eine feste Größe für jede Spalte einstellen, die Textausrichting für jede Spalte lässt sich zuweisen, und es lassen sich auch Spalten durch Abwählen der Checkbox "Visible" unsichtbar machen - das heißt, sie existieren zwar, und es ist auch Text in ihnen vorhanden, sie werden aber ausgeblendet, wenn die Tabelle angezeigt wird. Das ist zum Beispiel sinnvoll für eine interne ID, die zu einer Zeile gehört, die man aber nicht sehen soll.


Wie befüllen wir nun die Kopfzeile mit den Überschriften per Skript?

Dies geschieht durch Setzen der entsprechenden Gruppen-Property des DataGrid. Und zwar sieht es für die Überschriften folgendermaßen aus:

set the dgProps["column labels"] of group "tabelle" to "Name" & return & "E-Mail" & return & "Telefon"

Das heißt, auch die Namen aller Überschriften (column labels) kann man als Zeichenkette der Tabelle übergeben, allerdings sind die Spaltennamen der Tabelle hier nicht durch Tabulatorzeichen, sondern durch neue Zeilen (RETURN) voneinander abgegrenzt (so wie es auch im Property Inspector dargestellt ist). Jede Spaltenüberschrift hat also eine eigene Zeile.

Mit dem Befehl set the dgProps["propertyName"] können wir noch viel mehr Eigenschaften der Tabelle verändern, und zwar nicht nur solche, die wir auch im Property Inspector setzen können, sondern auch zahlreiche, die dort nicht aufgeführt sind. So kannst Du damit den Zeichensatz (text font) für den Datenbereich oder die Kopfzeile setzen, ebenso wie die Zeichengröße oder den Stil.

set the dgProps["text font"] of group "tabelle" to "Calibri"
set the dgProps["text size"] of group "tabelle" to 24
set the dgProps["header text font"] of group "tabelle" to "Arial"
set the dgProps["header text size"] of group "tabelle" to 30

Auch die Größe und der Farben der Kopfzeile lassen sich so anpassen. header background color, header background hilite color, header height, header margins usw... Auf die Weise kannst Du praktisch jedes Detail des Aussehens der Tabelle regeln (inaktive/aktive Farbe der Auswahl usw...). Auch das Verhalten lässt sich vielfach regeln, zum Beispiel ob die Zellen bearbeitbar sein sollen, ob Klick auf die Kopfzeile automatisch sortiert und vieles andere mehr. Eine Auflistung aller Properties der DataGrid-Komponente gibt es hier:

http://lessons.livecode.com/m/datagrid/l/7343-data-grid-properties

Nachdem wir uns jetzt eingehend mit dem Thema des Befüllens und dem Layout der Tabelle beschäftigt haben, steht noch eine wichtige Frage aus:


Wie lese ich am besten gewählte Daten aus der Tabelle aus?

Es ist mit Hilfe des dgData-Properties möglich, Daten gezielt aus einzelnen Tabellenzeilen zu lesen oder in sie zu schreiben.Wer will, kann dies im unten aufgeführten LiveCode-Tutorial nachvollziehen. Ich will für Einsteiger jetzt nur die einfachste Methode nennen, um Standardaufgaben, die man mit DataGrid-Tabellen immer wieder hat, in den Griff zu bekommen.

Die typische Anwendung ist nämlich diese: Wir haben eine Tabelle mit Spalten und Zeilen, die mit Daten befüllt ist, zum Beispiel unsere oben erstellte Namenliste mit E-Mails und Telefonnummern. Der Benutzer unseres Programms kann durch diese Liste blättern, kann sie möglicherweise sortieren und filtern und wählt dann per Mausklick oder Touch eine Zeile aus der Liste aus, um über diesen Datensatz mehr Details abzurufen oder Änderungen daran vorzunehmen. Wie kommen wir jetzt an die gewählte Zeile, um diesen Datensatz weiter zu verarbeiten?


Ermitteln der angewählten Tabellenzeile

Das folgende Skript (der DataGrid-group zugeordnet)  zeigt, wie man etwa die Daten der gewählten Zeile bei Mausklick auf die Tabelle auslesen könnte.

on mouseUp
  put the dgHilitedLines of me into zeile
  put line zeile of the dgText of me into zeilentext
  set the itemDelimiter to tab
  put item 1 of zeilentext into username
  put item 2 of zeilentext into email
  put item 3 of zeilentext into telefon
  put item 4 of zeilentext into user_id
end mouseUp

Mit der Property dgHilitedLines erhalten wir eine Zahl, die besagt, die wievielte Zeile der dargestellten Tabelle gewählt ist. Mit dieser Zahl können wir dann den eigentlichen Text dieser Zeile  aus der Property dgText ermitteln. Indem wir das Trennzeichen auf tab setzen, können wir dann jedes einzelne Datenfeld als item auslesen und einer Variablen zuweisen. Vielleicht brauchen wir gar nicht alle, sondern wir benötigen nur die id, mit deren Hilfe wir dann eine Datenbankabfrage machen, um die Details zum gewählten Datensatz aus der Datenbank abzurufen.

Wenn wir zum Beispiel neue Daten an das Ende der Tabelle anfügen wollen, dann empfiehlt es sich ebenso, dies über den dgText zu machen. Beispielsweise so:

put the dgText of group "tabelle" into tabtext
put return&"Neuer Name"&tab&"Neue E-Mail"&tab&"Neue Telnr."&tab&"neueId" after tabtext
set the dgText of group "tabelle" to tabtext

Wollen wir also den Dateninhalt der Tabelle ändern, dann ist es oft am einfachsten und übersichtlichsten, den gesamten Dateninhalt dgText in eine eigene Variable zu stecken, diese zu bearbeiten (dafür bietet LiveCode immerhin eine Menge bequeme Funktionen) und die Variable dann hinterher wieder dem dgText der Tabelle zuzuweisen. Wenn die Tabelle hingegen als Anzeiger einer Datenbank fungiert, sollten die Änderungen natürlich immer in der Datenbank selber vorgenommen werden und die Tabelle anschließend wieder durch Datenbankabfrage neu befüllt werden.

Diese kleine Einführung hat noch längst nicht alle Möglichkeiten der DataGrid-Komponente behandelt. Die Informationen sollten aber ausreichen, um damit in Gang zu kommen und die typischen Aufgaben damit erledigen zu können. Das englischsprachige Tutorial von LiveCode selber zeigt noch ein paar Möglichkeiten mehr auf und ist auf jeden Fall lesenswert:

http://lessons.livecode.com/m/datagrid

WIe immer ist Feedback in jeder Form willkommen, direkt hier oder im Forum.
Viel Spaß beim Entwickeln eigener Anwendungen mit dem LiveCode DataGrid!