Komfortable Ausgabeseiten für Haupt- und Detailtabellen

Die Logik von Haupt- und Detailtabellen, die über einfach erstellbare Relationen miteinander verknüpft sind, eignet sich zum Abbilden beliebig komplexer Geschäftsvorfälle. Allerdings gibt es - bei ausschließlicher Verwendung der internen Masken - einen offenkundigen Nachteil: Zwar stellt die Detailtabelle per Pulldown-Liste die wesentlichen Daten der Haupttabelle bereit. Es wäre jedoch sehr unübersichtlich, alle Spalten der Haupttabelle in den Ausdruck zu übernehmen. Bei größeren Haupttabellen müssen gewisse Spalten unsichtbar bleiben. Ferner gelingt es nicht, von einem Hauptdatensatz her alle Detaildatensätze zu sehen, die zu diesem Hauptdatensatz gehören. Man muß die Tabelle verlassen, die Detailtabelle aufrufen und dort jene Datensätze suchen, die zum Hauptdatensatz gehören.

Mit Ausgabeseiten läßt sich dies dagegen sehr einfach realisieren. Wie? Dies erfahren Sie hier.

Vorbereitung: Zwei verknüpfte Tabellen

Für das folgende Beispiel können Sie sich zwei kleine Tabellen bauen:
  • Tabelle Personen: Spalten Nachname, Vorname usw.
  • Tabelle Termine: Spalten PersonenId (Typ int), Datum, Beschreibung usw.
  • Verknüpfung:
    • Grundtabelle Personen
    • gezeigter Ausdruck:
      Nachname + ', ' + Vorname
    • Detailspalte: Termine.PersonenId
    Weitere Eigenschaften sind nicht notwendig
Die Grundtabelle kann natürlich auch, wie unter Mitgliederverwaltung skizziert, eine UID-Tabelle sein. Ferner können Sie die Relation mit der Eigenschaft 'Hauptrecht notwendig' definieren. Dies stellt sicher, daß jeder Nutzer (= Person = eine Zeile in der Personentabelle) nur zu seinem eigenen Hauptdatensatz Termine hinzufügen darf.

Wenn Sie beide Tabellen erstellt haben, können Sie sich zu jeder Tabelle einen View erzeugen, der sämtliche Spalten umfaßt. Anschließend generieren Sie zu jeder Tabelle (oder zu jedem View) eine Ausgabeseite der einfachsten Art (Code generieren, Tabelle / View auswählen, speichern).

Das Prinzip: Die ID der ausgewählten Zeile übergeben, auf der Zielseite einen passenden Filter setzen

Das Prinzip für die Lösung dieser Probleme ist sehr einfach: Beide Ausgabeseiten - eine für die Haupt-, eine für die Detailtabelle - enthalten ein sd:rs -Element, das tabellarische Daten bereitstellt. Auch wenn die Datenquelle aus einer Abfrage stammt, ist - aufgrund der Datenstruktur - bekannt, wo der Primärschlüssel zu finden ist, der auf der anderen Seite als Filter benötigt wird. Dieser Primärschlüssel wird beim Aufruf der Seite übergeben. Die Zielseite liest diesen Wert aus, cacht ihn - und verwendet ihn zum Filtern der angezeigten Datensätze: Es werden nur jene Zeilen ausgegeben, die zu diesem Hauptdatensatz gehören.

Schritt 1: Die ID der ausgewählten Zeile übergeben

Der für die Filterung benötigte Primärschlüssel kann auf der Ausgabeseite für die Haupttabelle in einer zusätzlichen Spalte mit dem folgenden Code ausgegeben werden:
<td>
  <a>
    <sd:attribute sd:attribute-name='href'>
      /zielseite.html?myParam=<sd:cell-value sd:col='primärschlüsselspalte'/>
    </sd:attribute>
    Details
  </a>
</td>
Dies generiert den folgenden Html-Code:
<td>
  <a href='/zielseite.html?myParam=5'>Details</a>
</td>
Für die Zeile mit der ID 5 wird ein Link eingefügt, der die Detailtabelle mit 'myParam=5' aufruft.

Schritt 2: Den übergebenen Wert auf der Detailtabellen-Ausgabeseite cachen

Das Cachen dieses Wertes wird mit einer einzigen Zeile erledigt, die am besten direkt nach dem öffnenden <body>-Element eingefügt wird:
<sd:param sd:name='myParam'
    sd:cache-name='my-internal-cache'/>
Dies definiert ein sd:param -Element mit dem Namen 'myParam', also dem Namen, der auch in der Url verwendet wird. Wird eine Ausgabeseite mit einem Parameter über eine solche Url aufgerufen, so wird der Name ausgelesen und steht für diesen Aufruf zur Verfügung (später nicht mehr). Verwendet das Element das sd:cache-name -Attribut, so wird der übergebene Wert zusätzlich im Laufzeitcache für diesen Benutzer gecacht - und steht für alle folgenden Aufrufe ebenfalls zur Verfügung.

Schritt 3: Den gecachten Wert als Filter verwenden

Dem sd:rs -Element, welches das Suchergebnis anzeigt, können sd:ro-value -Elemente zugewiesen werden. Das sind Elemente, die nach der Verarbeitung der zurückgesandten Formulardaten ausgewertet werden und fixierte (read-only) Werte für die Suche bereitstellen. Hier genügt ein Element, das - wie das sd:param -Element - direkt nach dem <body>-Element eingefügt wird:
<sd:ro-value sd:for='sample-output'
  sd:col='PersonenId'
  sd:std-value='$my-internal-cache'
  sd:missing-value='0'
/>
Dieses Element wird niemals im Html-Code ausgegeben. Es stellt sicher, daß für das sd:rs -Element mit dem Namen 'sample-output' die Spalte 'PersonenId' entweder mit dem gecachten Wert, also der ID des Hauptdatensatzes, belegt wird. Oder die Spalte wird mit dem Wert 0 belegt. Letzteres führt bei Relationen dazu, daß die Suche keinen Zeilen zurückgibt - da Primärschlüssel hier immer > 0 sind.

Ein Beispiel: Haupt- und Detaildatensätze

Auf der Seite

https://beispiel.server-daten.de/nutzer-infos.html

finden Sie ein Beispiel für diese Technik. Rufen Sie die Unterseite

https://beispiel.server-daten.de/nutzer-interessen.html

direkt aus, so wird nichts ausgegeben. Der Cache wird in diesem Fall explizit gelöscht, so daß der sd:missing-value-Wert genutzt wird. Nutzen Sie einen der pro Zeile ausgegebenen Links, etwa

https://beispiel.server-daten.de/nutzer-interessen.html?myParam=1,

so werden Ihnen die Detailzeilen zu diesem Hauptdatensatz ausgegeben. Das Beispiel ist als

https://beispiel.server-daten.de/nutzer-infos-login.html

über den Link 'Haupt- und Detaildatensätze' auf

https://beispiel.server-daten.de/

direkt erreichbar. Die Haupttabelle ist hier als UID-Tabelle definiert, die Relation nutzt zusätzlich 'Hauptrecht notwendig = Ja', um sicherzustellen, daß jeder Nutzer nur Detaildatensätze zu Hauptzeilen erstellen kann, die er auch editieren darf.

Berechtigungen

Sie können allen Benutzern das Recht zuordnen, gewisse dieser Ausgabeseiten aufzurufen. Zusätzlich ist es natürlich möglich, daß Sie auch die internen Verwaltungsdaten (Geldeingänge, Verlängerung der Mitgliedschaft) auf diese Weise Ihren internen Mitarbeitern einfach zugänglich machen. Für diese Ausgabeseiten erhält nur eine kleine Gruppe die Berechtigung, diese Ausgabeseiten überhaupt auszuführen. Damit steht Ihnen eine komfortable Verwaltung zur Verfügung - mit derselben Sicherheit, die auch für die internen Masken gültig ist.

Zusammenfassung

Das wars, mehr ist nicht zu tun. Für verknüpfte Tabellen genügen die folgenden drei Schritte:
  • Im sd:rs -Element, von dem ausgegangen werden soll, einen Link auf die Zielseite mit dem Namen eines sd:param -Elements und der ID dieser Zeile einfügen.
  • In der Zielseite ein sd:param -Element mit diesem Namen und einem sd:cache-name - Attribut deklarieren.
  • Ein geeignetes sd:ro-value -Element deklarieren, das dem sd:rs -Element für die gewünschte Spalte den gecachten Wert zur Verfügung stellt.
Damit können Nutzer von einer Ausgabeseite zur Grundtabelle mehrere Detailseiten aufrufen und erhalten immer die zum vorigen Element passenden Datensätze. Dasselbe kann natürlich gleichzeitig mit vertauschten Rollen durchgeführt werden: Sie rufen die Detailseite über einen Link ohne Parameter auf. Dann können Nutzer sich alle Detaildatensätze anzeigen lassen oder in diesen suchen. Fügen Sie zu jeder Zeile einen Link mit Parameternamen und dem Spaltenwert der Detailspalte hinzu. Ergänzen Sie die Hauptseite durch ein passendes sd:param -Element mit dem in der Url verwendeten Namen. Und fügen Sie ein sd:ro-value -Element ein, das die Primärschlüsselspalte mit der übergebenen ID vorbelegt. Dann können Nutzer sich zu jeder Detailzeile auch den kompletten Hauptdatensatz anzeigen lassen.


Kontaktformular:

Schreiben Sie mir und wir bauen gemeinsam Ihre neue Web-Datenbank!

Die Erläuterungen zum Datenschutz habe ich gelesen und stimme diesen zu.

© 2003-2019 Jürgen Auer, Berlin.