Erledigt-Status in Haupt- und Unterformular synchron

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.

Tabelle für die Produktionsaufträge

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).

Tabelle für die Produktionsteile

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).

Beziehung zwischen den beiden Tabellen

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).

Entwurf des Unterformulars

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.

Entwurf des Hauptformulars

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).

Eingabe von Beispieldaten

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).

Anlegen einer Ereignisprozedur für das Kontrollkästchen

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.

Synchronisierte Daten in Haupt- und Unterformular

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).

Dreifachen Status für das Kontrollkästchen aktivieren

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

Schreibe einen Kommentar