Datenstruktur und Eingabeprüfung ◦ ?

Eine komplexere Datenstruktur führt oft zu einfacheren Zugriffsoperationen. Wir veranschaulichen dies am Beispiel einer Eingabeprüfung.

### Eine komplexere Datenstruktur ermöglicht oft einen einfacheren Zugriff

#### Spezifikation

Das Unterformular Testtermine von FrmAllgemeines nennt alle Tests, welche die laufende Aufgabe enthalten. Der folgende Bildschirmausschnitt besagt zum Beispiel, dass die aktuelle Aufgabe im Test 1 (Informatik 1 des Sommersemesters 1997) vorkommt.

Die Autorin ordnet eine Aufgabe durch einen Klick auf den Abwärtspfeil der Spalte Nr. des obigen Kombinationsfelds einem Testtermin zu. Nach dem Klick erscheint das folgende Menü:

Jede Menüzeile enthält einen Testtermin. Weil die gültigen Kombinationen von Veranstaltung, Semester und Jahr fest vorgegeben sind, kann die Testautorin keinen falschen Testtermin zusammenstellen.

#### Datenentwurf

Der obigen Interaktion liegt der folgende Ausschnitt des Datenbankstrukturdiagramms zugrunde:

Jede Zeile von FRAGEN ist über das Verbundattribut Fragenschlüssel mit n Zeilen von FRAGENVERWENDUNG verbunden. Die Tabelle FRAGENVERWENDUNG ist ihrerseits über das Verbundattribut Testschlüssel mit der Nachschlagetabelle TESTS verbunden. In TESTS trägt die Autorin jeden Termin ein einziges Mal ein und wählt ihn jedesmal aus dem obigen Menü, wenn sie ihn einer Aufgabe zuordnet. Fehler können so nur in der (selten benutzten) Nachschlagetabelle TESTS auftreten. Diese Abbildung der m:n-Beziehung zwischen TESTS und FRAGEN durch die Verbindungstabelle FRAGENVERWENDUNG kompliziert zwar die Datenbankstruktur, ermöglicht aber eine einfache Gültigkeitsprüfung.

### Eine einfachere Datenstruktur erfordert oft einen komplexeren Zugriff

#### Datenentwurf

Das folgende Datenbankstrukturdiagramm ist einfacher als das obige, weil es auf die Nachschlagetabelle TESTS verzichtet:

Ein Test wird nicht mehr durch einen künstlichen Testschlüssel identifiziert, sondern durch die Zusammensetzung der Attribute Veranstaltung, Semester und Jahr. Die Tabelle FRAGENVERWENDUNG speichert allerdings diese Termintripel redundant.

#### Spezifikation und Dialogentwurf

Die eben definierte Datenstruktur legt eine andere Art der Eingabe nache. Das folgende Formular lässt die Autorin jedes der drei Terminattribute einzeln eingeben:

Diese Eingabeart macht allerdings unerlaubte Kombinationen von Veranstaltung/Semester/Jahr möglich. Eine naheliegende Eingabeprüfung entnimmt die erlaubten Kombinationen aus einer Nachschlagetabelle, die wie folgt definiert ist:

Jede Termineingabe in das obige Unterformular muss nun den folgenden Einschränkungen genügen:

1. Der Veranstaltungsname muss aus der Spalte Veranstaltung der Nachschlagetabelle stammen.

2. Das Eingabefeld 'Semester oder Quiz' darf der zweiten Spalte nicht widersprechen. Ein Test in "Datenverarbeitung" darf zum Beispiel gemäss der Nachschlagetabelle nur "Ende Sommersemester" stattfinden.

3. Das Jahr muss grösser oder gleich dem abJahr-Wert und kleiner oder gleich dem bisJahr-Wert sein.

Diese drei Einschränkungen lassen sich wie folgt implementieren:

##### Erste Einschränkung

Die Eigenschaft 'Datensatzherkunft' des Kombinationsfelds KmfVeranstaltung enthält eine SQL-Abfrage, die alle möglichen Veranstaltungsnamen ergibt. Die Eigenschaft 'Nur Listeneinträge' stellt sicher, dass der Benutzer keinen anderen Namen eingeben kann:

##### Zweite und dritte Einschränkung

Zur Prüfung der zweiten und dritten Einschränkung setzen wir voraus, dass der Wert der Spalte 'Getestete Veranstaltung' bereits eingegeben worden ist (siehe Bildschirmausschnitt oben). Eine Ereignisprozedur soll dann auf Grund dieser Eingabe die Eigenschaften Herkunftstyp (im Code RowSourceType) und Datensatzherkunft (RowSource) des Kombinationsfeldes bestimmen. Während diese beiden Eigenschaften für KmfVeranstaltung bereits zur Entwurfszeit bekannt sind (siehe obige Abbildung), liegen sie für die Kombinationsfelder 'Semester oder Quiz' und 'Jahr' erst nach der Veranstaltungswahl vor - das heisst erst zur Laufzeit des Programms.

#### Prozeduraler Entwurf

Der folgende Entwurfscode bestimmt den Herkunftstyp und die Datensatzherkunft am Beispiel des Kombinationsfelds KmfJahr. Die Ereignisprozedur KmfJahr_GotFocus() wird durch das Ereignis GotFocus (bei Fokuserhalt) ausgelöst. Ein Steuerelement erhält den Fokus, bevor es eine Eingabe empfangen kann (zum Beispiel nach einem Klick auf das Steuerelement). Der folgende Pseudocode entwirft die Ereignisprozedur KmfJahr_GotFocus():

>     Falls der Testtermin nicht in der Folge Veranstaltung/Semester/Jahr eingegeben wird dann
>       erinnere an die richtige Reihenfolge und gehe auf das richtige Eingabefeld
>     sonst
>       beschränke das Auswahlangebot von KmfJahr so, dass es den obigen Einschränkungen genügt

#### Codierung

Die Codierung verweist die Benutzerin im If-Zweig auf das richtige Eingabefeld. Andernfalls erstellt der Else-Zweig die SQL-Abfrage, welche in KmfJahr die möglichen Testjahre zur Auswahl anbietet.

>     Private Sub KmfJahr_GotFocus()
>       Dim SQLBefehl As String

>       '-- Eingabereihenfolge erzwingen
>       If IsNull([KmfVeranstaltung]) And IsNull([KmfSemester]) Then
>         MsgBox "Bitte zuerst Veranstaltung und Semester einfügen", , ""
>         DoCmd.GoToControl "KmfVeranstaltung"
>       ElseIf IsNull([KmfSemester]) Then
>         MsgBox "Bitte zuerst Semester einfügen", , ""
>         DoCmd.GoToControl "KmfSemester"
>       Else
>        ' Herkunftstyp einer SQL-Abfrage
>        [KmfJahr].RowSourceType = "Table/Query"
>         '-- Datensatzherkunft ist SQLBefehl
>        SQLBefehl = "SELECT JAHR.Jahr " _
>          & "FROM Veranstaltung, Jahr " _
>          & "WHERE (((JAHR.Jahr)>=[abJahr] And (JAHR.Jahr)<=[bisJahr]) AND "
>          & "((VERANSTALTUNG.Veranstaltung)='" & [KmfVeranstaltung] & "') AND " _
>          & "((VERANSTALTUNG.Semester)='" & [KmfSemester] & "'))"
>        [KmfJahr].RowSource = SQLBefehl
>       End If
>     End Sub

Diese Eingabeprüfung ist trotz der einfacheren Datenstruktur schwieriger zu implementieren als die implizite Validitätsprüfung der ersten Variante.