Makros und Programme einsetzen

Das Programmiermodell von TurboPL

Top  Previous  Next

Das Programmiermodell

Bei der Programmierung mit TurboPL kann man sich den Aufbau einer Anwendung schematisch als drei Ebenen von Objekten vorstellen.

Programmiermodell

Die unterste Ebene sind die Tabellen. Sie enthalten die Daten inklusive der Indexe, Memos, Blobs und Relationsfelder. Tabellen werden als *.dat-Objekte gespeichert und bei Verzeichnisdatenbanken auch als dat-Dateien sichtbar.

In der mittleren Ebene greifen Cursor auf die Tabellen zu. Ein Cursor besitzt einen Satzzeiger, der den aktuellen Datensatz der Tabelle spezifiziert, eine Markierungsliste (die sogenannte interne Markierungsliste) und den Zugriff. Der Zugriff wiederum legt fest, ob auf die Daten in der natürlichen Reihenfolge zugegriffen wird, über einen Index oder über die interne Markierungsliste. (Außerdem gibt es noch Filter und Bereiche für den Zugriff, aber die sind ein fortgeschrittenes Thema.) Für eine Tabelle kann es keinen, einen oder mehrere Cursor geben. Das ist wichtig, damit unterschiedliche Datenfenster für die selbe Tabelle unterschiedliche Satzzeiger, Zugriffe und Markierungslisten für diese Tabelle pflegen können.

Datenfenster sind also die dritte und oberste Ebene des Programmiermodells. Sobald ein Formular geöffnet wird, erzeugt es einen Cursor für die Primärtabelle, über den es auf die Daten der Tabelle zugreift. Wenn eingebettete Tabellenansichten vorhanden sind, erzeugen auch diese jeweils einen Cursor auf ihre zugehörige Tabelle. Jedes Datenfenster – egal ob das Formular selbst oder eine eingebettete Tabellenansicht – hat genau einen solchen Cursor.

Nur wenn die eingebettete Tabellenansicht die selbe Tabelle darstellt wie das Formular und sie außerdem entsprechend gekennzeichnet ist (Eigenschaft Tabelle ist Formular), dann verwendet diese eingebettete Tabellenansicht den selben Cursor wie das Formular. Deshalb hat sie immer den selben aktuellen Datensatz, die selbe Sortierung, usw.

Zu einem Formular gehört also immer mindestens ein Cursor, es kann aber mehrere davon besitzen. Aber nicht nur Formulare haben Cursor. Auch Berichte und Datenbankjobs haben welche, sonst könnten sie nicht auf die Daten der Tabelle zugreifen.

Zusätzlich zu all diesen Cursor-Mengen für Formulare (von denen keine vorhanden ist, wenn kein Formular geöffnet wurde), gibt es immer noch eine weitere für TurboPL-Datenbank-Befehle. Diese werden für Datenbankjobs verwendet, weil die ja auch ohne Formular ausgeführt werden können aber auch für Makros, damit diese nicht das Formular durcheinander bringen.

Zusammenhang zwischen Eigenschaften der Oberfläche und im Cursor

Auf den ersten Blick könnte man denken, was im Cursor eingestellt ist, sieht man auch an der Oberfläche. Das ist im Prinzip tatsächlich richtig: Das Datenfenster zeigt den aktuellen Datensatz des Cursors, die Reihenfolge der Datensätze entspricht dem im Cursor eingestellten Zugriff usw.

Bei einigen anderen Eigenschaften ist der Zusammenhang nicht so direkt. Zum Beispiel sieht man die Markierungen des Cursors nicht direkt sondern in der Auswahl der angezeigten Datensätze. Die sichtbaren Markierungen (die aus Tradition "Sternchen" heißen, auch wenn sie in TurboDB Studio als Kreise dargestellt werden) haben dagegen mit dem Cursor überhaupt nichts zu tun. Sie sind alleine eine Eigenschaft des Datenfensters.

Wenn der Anwender also mit der Maus sichtbare Markierungen setzt und anschließend den Befehl "Nur markierte Datensätze anzeigen" auswählt, passieren zwei Dinge:

1.Werden die sichtbaren Markierungen in interne verwandelt, d.h. das Datenfenster übergibt sie dem Cursor.
2.Der Zugriff im Cursor wird auf Markierung gestellt, was bedeutet, dass nur noch die Datensätze mit Markierung angezeigt werden.

Ein anderes Beispiel für einen komplexeren Zusammenhang zwischen Datenfenster und Cursor ist der Bearbeitungsmodus. Der Cursor verwaltet einen solchen Modus für den gerade aktuellen Datensatz, dieser wird zu einem bestimmten Zeitpunkt entweder betrachtet, geändert oder neu eingegeben. Die entsprechenden Schalter Datenfenster dagegen bedeuten, dass der Anwender ändern beziehungsweise neu eingeben darf. Beispielsweise kann man mit eingeschaltetem Neueingabemodus auch schon vorhandene Datensätze betrachten.

In diesem Fall ist der Modus im Datenfenster "Neueingabe erlaubt", der Bearbeitungs-Modus im Cursor jedoch "betrachten". Umgekehrt ist es in einer Prozedur möglich, den Datensatz mit einer Datenbank-Prozedur auf "ändern" zu schalten und per Programm zu editieren, während im Formular der Schalter Datensätze bearbeiten nicht aktiviert ist.

Datenbank-Befehle und Oberflächen-Befehle

TurboPL enthält sowohl Befehle, die auf die TurboPL-Cursor wirken als auch Befehle für die Datenfenster. Erstere heißen Datenbank-Befehle - ReadRec, SetMark, Access, Replace gehören zum Beispiel dazu - letztere Oberflächen-Befehle wie ShowRec, SetSortOrder und andere. Oberflächen-Befehle können natürlich nur dann ausgeführt werden, wenn mindestens ein Formular geöffnet ist. Den Effekt einer Oberflächenprozedur sieht man deshalb immer sofort im Datenfenster. Allerdings bewirken viele Oberflächen-Prozeduren auch eine Änderung am Cursor. Die Prozedur Sortierung zum Beispiel ändert als erstes den Zugriff des Cursors und zeigt dann anschließend die Daten neu an, damit die neue Sortierung sichtbar ist. Außerdem aktualisiert sie die Anzeige der Sortierung im Kombinationsfeld in der Werkzeugleiste. Das bedeutet, dass nach der Ausführung eines Oberflächen-Befehls der Cursor und das Datenfenster entsprechend angepasst und synchronisiert sind.

Bei Datenbank-Befehlen ist das nicht so, weil sie auf den Cursor für TurboPL-Datenbefehle wirken und erst einmal nicht auf die Oberfläche. Das ist ein wichtiger Vorteil. Es würde zum Beispiel nicht gut aussehen, wenn eine Prozedur eine schnelle Schleife über viele Datensätze macht, um beispielsweise bestimmte davon zu markieren und das Datenfenster würde alle Datensätze auch tatsächlich darstellen. Abgesehen davon wäre das viel zu langsam.

Stattdessen gibt es einen expliziten Befehl, der die Cursor des Datenfensters wieder mit dem TurboPL-Cursor abgleicht, genauer gesagt, den Satzzeiger, die Markierungen und den Zugriff vom TurboPL-Cursor übernimmt. Der Befehl ist die Prozedur Attach und aktualisiert das Datenfenster inklusive etwaiger eingebetteter Tabellenansichten. Attach ruft man normalerweise als letzten Befehl in einer Prozedur auf, weil man ja vorher keine Aktualisierung im Datenfenster benötigt.

An dieser Stelle sollten wir noch einmal kurz auf den Unterschied zwischen der Prozedur Attach und der Prozedur Refresh eingehen. Refresh übernimmt weder Zugriff noch Markierung noch Satzzeiger aus dem Kursor, es zeigt einfach nur die Daten neu an um etwaige Änderungen in Datenfeldern an der Oberfläche wiederzuspiegeln. Refresh kann man jederzeit bedenkenlos aufrufen, weil es den Zustand des Datenfensters nicht ändert – ganz anders als Attach.

Was passiert aber nun, wenn man mit Datenbank-Befehlen den Zustand des Cursors ändert, ohne das Datenfenster mit Attach abzugleichen? Interessant ist das, wenn die Prozedur endet und das Datenfenster wieder die Kontrolle übernimmt oder wenn in der Prozedur eine modale Datenfenster-Funktion aufgerufen wird. Auch in diesem Fall ist das Datenfenster ja wieder aktiv und muss entscheiden welchen Zustand es anzeigt, seinen eigenen oder den des Cursors.

Im Prinzip ist die Antwort ganz einfach: Alle Änderungen auf dem Cursor werden verworfen und der ursprüngliche Zustand vor Aufruf der Prozedur wiederhergestellt. Da die Änderungen an der Tabelle aber verbleiben, gibt es hier ein paar Problemfälle.

Der Datensatz, auf dem der Satzzeiger stand wurde inzwischen gelöscht: Dann steht der nach der Prozedur entweder auf dem darauffolgenden Datensatz oder auf dem letzten Datensatz der Tabelle.
Ein Datensatz, der jetzt gelöscht ist, war markiert: Die Markierung wird entfernt