Ein Kunde hatte neulich die Anforderung, dass er Produktionsaufträge mit den zu produzierenden Teilen im Haupt- und Unterformular abbilden wollte. An sich kein Problem, wenn man Haupt- und Unterformular entsprechend verknüpft. Er wünschte sich jedoch sowohl in der Tabelle der Produktionsaufträge als auch in der für die Teile jeweils ein Kontrollkästchen, das den Status abbildet. Wenn der vollständige Auftrag erledigt ist, soll dieser samt Teileliste einen Haken erhalten. Ist der Auftrag noch offen, sind alle Kontrollkästchen leer. Aber wenn nicht alle Teile fertig produziert sind, sollte dies im Produktionsauftrag auf eine spezielle Art gekennzeichnet werden. Er hat dabei den Dreifachstatus des Kontrollkästchens entdeckt und wünschte sich, dass das Kontrollkästchen in diesem Fall für den Produktionsauftrag den dritten Status anzeigt – in aktuellen Access-Versionen ein gefülltes Kontrollkästchen mit einem Minus-Zeichen. Wie das gelingt und wie wir die Zustände von Produktionsauftrag und Teilen synchron halten, zeigen wir in diesem Beitrag.
Datenmodell
Zunächst stellen wir die beiden Tabellen zusammen, mit denen wir die Produktionsaufträge und die enthaltenen, zu fertigenden Teile verwalten.
Die erste Tabelle heißt tblProduktionsauftraege und soll die Felder aus Bild 1 enthalten. Neben dem Primärschlüsselfeld und dem Feld für die Bezeichnung des Produktionsauftrags finden wir das Ja/Nein-Feld Erledigt.

Bild 1: Tabelle für die Produktionsaufträge
Die zweite Tabelle namens tblProduktionsteile enthält ähnliche Felder, also auch das Feld Erledigt mit dem Datentyp Ja/Nein. Außerdem finden wir hier noch das Feld ProduktionsauftragID, mit dem wir das zu produzierende Teil dem jeweiligen Produktionsauftrag zuweisen können (siehe Bild 2).

Bild 2: Tabelle für die Produktionsteile
Zwischen den beiden Tabellen stellen wir über das Fremdschlüsselfeld ProduktionsauftragID eine Beziehung her und definieren referenzielle Integrität zwischen den beiden Tabellen (siehe Bild 3).

Bild 3: Beziehung zwischen den beiden Tabellen
Formulare für das Beispiel
Nun erstellen wir zunächst das Unterformular, das die Produktionsteile zu einem Produktionsauftrag anzeigen soll. Dazu fügen wir einem leeren Formular die Tabelle tblProduktionsteile als Datensatzquelle hinzu und ziehen alle Felder außer ProduktionsauftragID zur Detailansicht hinzu.
Die Eigenschaft Standardansicht legen wir auf den Wert Datenblatt fest. Anschließend speichern wir das Formular unter dem Namen sfmProduktionsauftraege und schließen es (siehe Bild 4).

Bild 4: Entwurf des Unterformulars
Das Hauptformular erstellen wir auf ähnliche Weise, allerdings verwenden wir hier die Tabelle tblProduktionsauftraege als Datensatzquelle.
Zudem ziehen wir hier noch das soeben erstellte Unterformular sfmProduktionsauftraege in den Detailbereich, sodass das Ergebnis wie in Bild 5 aussieht.

Bild 5: Entwurf des Hauptformulars
Hier prüfen wir noch, ob die Eigenschaften Verknüpfen von und Verknüpfen nach für das Unterformular-Steuerelement korrekt eingestellt wurden.
Anschließend können wir in die Formularansicht wechseln und direkt einige Beispieldaten in Haupt- und Unterformular eingeben (siehe Bild 6).

Bild 6: Eingabe von Beispieldaten
Erledigt-Status synchron halten
Damit kommen wir zur eigentlichen Aufgabe:
- Wenn der Benutzer nun das Feld Erledigt für den Produktionsauftrag im Hauptformular markiert, sollen auch alle Einträge im Unterformular markiert werden.
- Wenn der Benutzer die Markierung dieses Feldes aufhebt, sollen auch alle Einträge im Unterformular abgewählt werden.
- Setzt der Benutzer die Markierung für einen Eintrag im Unterformular oder hebt diese auf, soll geprüft werden, ob aktuell alle Einträge markiert sind oder auch nur einige oder keiner. Sind alle Einträge markiert, soll auch das Feld Erledigt im Hauptformular einen Haken erhalten. Wenn kein Haken markiert ist, soll Erledigt im Hauptformular auch abgewählt werden. Und schließlich fehlt noch der Fall, dass nur einige Einträge markiert sind: Dann soll das Feld Erledigt im Hauptformular den dritten Status eines Kontrollkästchens erhalten.
Wie das gelingt, beschreiben wir in den nächsten Abschnitten.
Kontrollkästchen umbenennen
Zuvor versehen wir die beiden Kontrollkästchen im Haupt- und Unterformular jedoch noch mit einem entsprechenden Präfix, hier chk für Checkbox (Kontrollkästchen). Beide heißen nun chkErledigt.
Produktionsauftrag als vollständig erledigt markieren
Wenn der Benutzer den Produktionsauftrag als erledigt kennzeichnet, sollen alle Produktionsteile zu diesem Auftrag auch als erledigt markiert werden. Um auf die Änderung des Zustandes des Kontrollkästchens chkErledigt im Hauptformular zu reagieren, hinterlegen wir eine Ereignisprozedur für das Ereignis Nach Aktualisierung (siehe Bild 7).

Bild 7: Anlegen einer Ereignisprozedur für das Kontrollkästchen
Dazu wählen wir hier den Eintrag [Ereignisprozedur] aus und klicken auf die Schaltfläche mit den drei Punkten.
Die jetzt im VBA-Editor erscheinende Ereignisprozedur füllen wir wie in Listing 1. Hier deklarieren wir ein Database-Objekt, das wir mit einem Verweis auf die aktuelle Datenbank füllen, sowie eine Variable namens bolErledigt, in die wir den aktuellen Zustand des Kontrollkästchens chkErledigt aus dem Hauptformular einlesen.
Private Sub chkErledigt_AfterUpdate() Dim db As DAO.Database Dim bolErledigt As Boolean Set db = CurrentDb bolErledigt = Me.chkErledigt db.Execute "UPDATE tblProduktionsteile SET Erledigt = " & CInt(bolErledigt) & " WHERE ProduktionsauftragID = " _ & Me.ProduktionsauftragID, dbFailOnError Me.sfmProduktionsauftraege.Form.Requery End Sub
Listing 1: Übertragen der Markierung aus dem Hauptformular in das Unterformular
Dann führen wir eine Aktualisierungsabfrage aus, die für alle Datensätze der Tabelle tblProduktionsteile, die zum aktuellen Produktionsauftrag gehören, den Wert aus der Variablen bolErledigt einträgt.
Dabei konvertieren wir den Wert des Boolean-Feldes mit der CInt-Funktion noch in den Datentyp Integer. Das ist nötig, da Boolean-Werte bei der Ausgabe als Wahr oder Falsch ausgegeben werden und die SQL-Anweisung damit nichts anfangen kann. Also transformieren wir den Wert zuvor noch in -1 oder 0.
Danach aktualisieren wir noch die Daten im Unterformular und erhalten das Ergebnis aus Bild 8.

Bild 8: Synchronisierte Daten in Haupt- und Unterformular
Hier stellt sich noch die Frage, ob wir dies ohne vorherige Rückfrage durchführen wollen, wenn bereits einige Einträge im Unterformular abgehakt wurden.
Zur Sicherheit bauen wir also noch eine Meldung ein, die wir aber nicht erst im Ereignis Nach Aktualisierung aufrufen, sondern bereits im Ereignis Vor Aktualisierung von chkErledigt im Hauptformular. Nach dem Anlegen sehen wir auch, warum dies sinnvoller ist:
Private Sub chkErledigt_BeforeUpdate(Cancel As Integer) End Sub
Diese Ereignisprozedur bietet nämlich einen Parameter namens Cancel an, den wir auf True einstellen können, wenn der Benutzer sich gegen eine Aktualisierung entscheidet. Damit verwerfen wir automatisch auch die Eingabe des Benutzers. Die Prozedur füllen wir wie in Listing 2.
Private Sub chkErledigt_BeforeUpdate(Cancel As Integer) If MsgBox("Dies setzt den Status Erledigt für alle Teile auf ''" & CBool(Me.chkErledigt) & "''. Fortsetzen?", _ vbYesNo, "Status ändern") = vbNo Then Cancel = True End If End Sub
Listing 2: Rückfrage, ob die Änderung übertragen werden soll
Hier fragen wir den Benutzer in einer MsgBox-Funktion, ob die Änderung auf die Teile übertragen werden soll. Wählt der Benutzer hier die Schaltfläche Nein, stellt die Prozedur den Parameter Cancel auf True ein, wodurch die Änderung verworfen wird.
Das Ereignis chkErledigt_AfterUpdate wird in diesem Fall nicht aufgerufen.
Mit dieser Vorgehensweise erledigen wir direkt das vollständige Aus- und Abwählen der untergeordneten Elemente.
Aktualisieren von Einträgen im Unterformular
Damit folgt der spannendere Teil. Wenn der Benutzer einen der Einträge im Unterformular auf Erledigt setzt oder eine solche Markierung entfernt, soll auch die Markierung im Hauptformular angepasst werden:
- Wenn der Wert des Feldes Erledigt für alle Produktionsteile auf True eingestellt ist, soll der Wert des entsprechenden Feldes im Hauptformular auch True lauten.
- Sind noch keine Produktionsteile für den aktuellen Produktionsauftrag gefertigt, soll das Feld Erledigt für den Produktionsauftrag den Wert False erhalten.
- Ist mindestens ein Produktionsteil erledigt, aber nicht alle, dann soll das Feld Erledigt für den Produktionsauftrag den Wert Null erhalten und das Kontrollkästchen soll den dritten Status anzeigen.
Dazu müssen wir zunächst die Eigenschaft Dreifacher Status für das Feld Erledigt im Hauptformular auf Ja einstellen (siehe Bild 9).

Bild 9: Dreifachen Status für das Kontrollkästchen aktivieren
Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...
den kompletten Artikel im PDF-Format mit Beispieldatenbank
diesen und alle anderen Artikel mit dem Jahresabo
