Haupt- und Unterformular synchron

Manchmal zeigt das Hauptformular die gleichen Daten wie das Unterformular an – beispielsweise, wenn das Unterformular als übersichtsliste die Daten in der Datenblattansicht liefert und ein Wechseln des Datensatzes im Unterformular zur Anzeige der Details des gleichen Datensatzes in im Hauptformular führen soll. Soll dies auch umgekehrt der Fall sein, also das beim Wechsel des Datensatzes im Hauptformular der entsprechende Datensatz im Unterformular markiert wird, wird es kompliziert. Mögliche Probleme und die Auflösung liefert dieser Beitrag.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1706_HauptUndUnterformularSynchron.accdb.

Beispielkonstellation

Wir wollen die Daten einer Tabelle namens tblHersteller aus unserer Beispiellösung Handyverwaltung herausnehmen und an diesem Beispiel zeigen, wie Haupt- und Unterformular synchron gehalten werden können. Dazu legen wir zunächst ein neues Unterformular namens sfmHersteller an, das die Abfrage qryHerstellerBezeichnungNachAlphabet als Datenherkunft verwendet. Diese Abfrage liefert nur die beiden Felder HerstellerID und Bezeichnung der Tabelle tblHersteller, und zwar alphabetisch nach dem Inhalt des Feldes Bezeichnung sortiert.

Das Hauptformular frmHersteller verwendet eine ähnliche Abfrage namens qryHerstellerNachBezeichnung, welche allerdings alle Felder der Tabelle tblHersteller enthält. Auch hier gibt es eine Sortierung nach dem Feld Bezeichnung.

Das Unterformular platzieren wir wie in Bild 1 im Hauptformular. Nun wollen wir, dass das Hauptformular und das Unterformular immer den gleichen Datensatz anzeigen beziehungsweise dass im Unterformular immer der Datensatz markiert ist, der aktuell im Hauptformular angezeigt wird und umgekehrt.

Haupt- und Unterformular zur Anzeige der Daten aus der gleichen Datenherkunft

Bild 1: Haupt- und Unterformular zur Anzeige der Daten aus der gleichen Datenherkunft

Erster Versuch

Dabei stellen wir uns nun vor, dass Folgendes funktionieren könnte und probieren es aus. Für das Ereignis Beim Anzeigen des Hauptformulars legen wir die folgende Ereignisprozedur an:

Private Sub Form_Current()
    Me!sfmHersteller.Form.Recordset!HerstellerID                                        = Me!HerstellerID
End Sub

Diese Prozedur stellt also den Datensatzmarkierer für das Recordset im Unterformular auf den Datensatz ein, dessen Primärschlüsselfeld HerstellerID dem passenden Wert im Hauptformular entspricht.

Für das entsprechende Ereignis des Unterformulars verwenden wir eine ganz ähnliche Ereignisprozedur, welche die folgende Zeile enthält:

Private Sub Form_Current()
    Me.Parent.Recordset.FindFirst "HerstellerID = "          & Me!HerstellerID
End Sub

Diese versucht, den Datensatzzeiger im Recordset des Hauptformulars auf den Datensatz einzustellen, dessen HerstellerID im Unterformular ausgewählt wurde. öffnen wir nun das Formular in der Formularansicht, erhalten wir die Ansicht aus Bild 2 – es klappt also wie gewünscht.

Beim Anzeigen erscheinen die Datensätze im Haupt- und Unterformular synchron.

Bild 2: Beim Anzeigen erscheinen die Datensätze im Haupt- und Unterformular synchron.

Das ist auch der Fall, wenn wir zwischen den Datensätzen im Haupt- oder im Unterformular navigieren. Es tritt erst ein Problem auf, wenn wir den Datensatzzeiger im Haupt- oder Unterformular auf einen neuen, leeren Datensatz verschieben.

Dann erhalten wir die Fehlermeldung aus Bild 3. Der Grund für diese Fehlermeldung ist, dass Me!HerstellerID zu diesem Zeitpunkt, also beim Anlegen eines neuen Datensatzes, den Wert Null enthält. Dadurch sieht der Ausdruck, der als Kriterium der FindFirst-Methode verwendet wird, wie folgt aus:

Fehler beim Anzeigen eines neuen, leeren Datensatzes

Bild 3: Fehler beim Anzeigen eines neuen, leeren Datensatzes

HerstellerID = 

Diesen Ausdruck kann Access nicht auswerten, also wird die Fehlermeldung aus der Abbildung generiert.

ändern wir die beiden Ereignisprozeduren also etwas ab, um die Fehlermeldung zu verhindern. Dazu fassen wir die Angabe des Wertes Me!Hersteller einfach mit der Funktion Nz ein und geben als zweiten Parameter den Wert 0 an, was dafür sorgt, dass die Funktion den Wert 0 liefert, wenn HerstellerID den Wert Null aufweist:

'Hauptformular
Private Sub Form_Current()
    Me!sfmHersteller.Form.Recordset.FindFirst "HerstellerID = " & Nz(Me!HerstellerID, 0)
End Sub
'Unterformular
Private Sub Form_Current()
    Me.Parent.Recordset.FindFirst "HerstellerID = " & Nz(Me!HerstellerID, 0)
End Sub

Dies führt nun immerhin dazu, dass beim Ansteuern eines neuen, leeren Datensatzes im Haupt- oder Unterformular kein Fehler mehr ausgelöst wird. Allerdings finden wir hier ein etwas merkwürdiges Verhalten vor, denn wenn Sie etwa mit der Tabulator-Taste im Unterformular vom letzten auf den neuen, leeren Datensatz wechseln, springt der Datensatzzeiger auf den ersten Datensatz im Unterformular. Das Gleiche geschieht auch manchmal, wenn Sie mit der Maus von einem anderen Datensatz auf den neuen, leerenDatensatz wechseln. Wenn Sie hingegen soeben auf den letzten Datensatz gewechselt sind und der Datensatzzeiger dadurch auf den ersten Datensatz gesprungen ist und dann mit der Maus auf den neuen, leeren Datensatz klicken, verbleibt der Datensatzzeiger auf diesen Datensatz.

Was geschieht im Hintergrund genau Um das herauszufinden, haben wir den beiden Ereignisprozeduren jeweils eine Debug.Print-Anweisung hinzugefügt, welche einen Hinweis auf die jeweilige Prozedur im Haupt- oder Unterformular im Direktfenster ausgibt:

'Hauptformular
Private Sub Form_Current()
    Debug.Print "Hauptformular_Current"
    Me!sfmHersteller.Form.Recordset.FindFirst "HerstellerID = " & Nz(Me!HerstellerID, 0)
End Sub
'Unterformular
Private Sub Form_Current()
    Debug.Print "Unterformular_Current"
    Me.Parent.Recordset.FindFirst "HerstellerID = " & Nz(Me!HerstellerID, 0)
End Sub

Wenn wir das Formular nun öffnen, werden die Ereignisse in dieser Reihenfolge ausgelöst:

Unterformular_Current
Hauptformular_Current

Das Verschieben des Datensatzzeigers über das Ereignis im Unterformular sorgt also dafür, dass auch das Ereignis Beim Anzeigen im Hauptformular ausgelöst wird. Obwohl dieses wiederum den Datensatzzeiger im Unterformlar verschiebt, löst dies nicht nochmal das Ereignis Beim Anzeigen im Unterformular aus. Offensichtlich hat Access einen Automatismus eingebaut, der Zirkelbezüge zwischen Prozeduren schnell erkennt und nach einmaliger Ausführung abbricht. Dabei wird die Prozedur im Hauptformular genau nach dem Aufruf von FindFirst im Unterformular ausgelöst. Nach dem Abarbeiten der Prozedur im Hauptformular wird dann noch die letzte Zeile der Prozedur im Unterformular erledigt (siehe Bild 4).

Ablauf der beiden Prozeduren beim öffnen des Formulars

Bild 4: Ablauf der beiden Prozeduren beim öffnen des Formulars

Wenn Sie mit der Tabulator-Taste von einem Datensatz zum nächsten wechseln, löst dies jeweils die gleichen Ereignisse aus. Wenn wir auf diese Weise allerdings auf dem neuen, leeren Datensatz landen, werden folgende Ereignisse ausgelöst:

Unterformular_Current
Hauptformular_Current
Unterformular_Current

Dabei löst FindFirst im Unterformular die Prozedur im Hauptformular aus und FindFirst im Hauptformular nochmals die entsprechende Prozedur im Unterformular. Erst danach bricht die Abarbeitung der Ereignisprozeduren ab.

Möchten Sie weiterlesen? Dann lösen Sie Ihr Ticket!
Hier geht es zur Bestellung des Jahresabonnements des Magazins Access [basics]:
Zur Bestellung ...
Danach greifen Sie sofort auf alle rund 400 Artikel unseres Angebots zu - auch auf diesen hier!
Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:

Schreibe einen Kommentar

Haupt- und Unterformular synchron

Es macht wenig Spaß, sich in der Formularansicht durch die Datensätze zu wühlen, bis man endlich zum gesuchten Datensatz gelangt. Genausowenig Freude macht das Bearbeiten von Daten in der Datenblattansicht – zumindest, wenn das Formular nicht alle Felder gleichzeitig anzeigt und man hin- und herscrollen muss.Warum aber nicht beides verbinden und einfach zum Detailformular mit jeweils einem Datensatz noch ein Unterformular hinzufügen, dass alle Datensätze anzeigt und zum Blättern einlädt Dieser Artikel zeigt, wie dies funktioniert.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1303_HauptUndUnterformularSynchron.mdb.

Hauptformular erstellen

Das Hauptformular frmArtikelSynchron soll zunächst an die Tabelle mit den anzuzeigenden Daten gebunden werden, in diesem Fall tblArtikel.

Dazu stellen Sie die Eigenschaft Datenherkunft auf diese Tabelle ein. Dann ziehen Sie alle Felder der Tabelle aus der Feldliste in den Detailbereich des Formulars (siehe Bild 1).

Hauptformular mit Artikeldetails

Bild 1: Hauptformular mit Artikeldetails

Unterformular erstellen

Das Unterformular soll die gleichen Daten wie das Hauptformular enthalten. Was liegt also näher als das bereits erstellte Hauptformular einfach zu kopieren

Schließen Sie dieses also, markieren Sie den Eintrag frmArtikelSynchron im Datenbankfenster beziehungsweise Navigationsbereich und betätigen Sie die Tastenkombinationen Strg + C und Strg + V. Access fragt nun nach einen neuen Namen für das zu kopierende Formular, geben Sie hier einfach sfmArtikelSynchron an.

Dieses Formular benötigt nur eine änderung: öffnen Sie es im Entwurf und stellen Sie die Eigenschaft Standardansicht auf den Wert Datenblatt ein. Dann schließen Sie das Unterformular wieder.

Nun öffnen Sie das Hauptformular erneut in der Entwurfsansicht und ziehen das Unterformular sfmArtikelSynchron in den Detailbereich des Formularentwurfs.

Haupt- und Unterformular zusammenführen

Das Ergebnis sieht in der Entwurfsansicht wie in Bild 2 aus. Wenn Sie nun in die Formularansicht wechseln, sieht das Ergebnis wie in Bild 3 aus. Das ist noch nicht exakt das gewünschte Ergebnis, denn das Unterformular zeigt jeweils nur den Datensatz an, der auch im Hauptformular erscheint. Sie können sogar durch die Datensätze im Hauptformular navigieren, das Unterformular wird immer auf den Datensatz des Hauptformulars eingestellt.

Formularansicht, erster Versuch

Bild 2: Formularansicht, erster Versuch

Haupt- und Unterformular

Bild 3: Haupt- und Unterformular

Warum ist dies so Weil wir das Unterformular direkt in das Hauptformular gezogen haben. Access prüft dann normalerweise automatisch, ob es Felder in den Datenherkünften von Haupt- und Unterformular gibt, zwischen denen eine Beziehung existiert und trägt diese für die beiden Eigenschaften Verknüpfen von und Verknüpfen nach ein. Dadurch soll das Unterformular normalweise nur die Datensätze anzeigen, die mit dem Datensatz im Hauptformular verknüpft sind.

Möchten Sie weiterlesen? Dann lösen Sie Ihr Ticket!
Hier geht es zur Bestellung des Jahresabonnements des Magazins Access [basics]:
Zur Bestellung ...
Danach greifen Sie sofort auf alle rund 400 Artikel unseres Angebots zu - auch auf diesen hier!
Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:

Schreibe einen Kommentar