1:n-Beziehungen in Unterformularen

Wenn Sie ein Abonnement des Magazins 'Access im Unternehmen' besitzen, können Sie sich anmelden und den kompletten Artikel lesen.
Anderenfalls können Sie das Abonnement hier im Shop erwerben.

1:n-Beziehungen in Unterformularen

Meistens zeigt man 1:n-Beziehungen in einem Haupt- und einem Unterformular an. Was aber, wenn man die Datensätze beider Seiten im Überblick anzeigen möchte – etwa wenn Sie alle Kategorien in einer Liste und die Artikel zur ausgewählten Kategorie in einer anderen Liste darzustellen? Oder, um es noch eine Nummer komplizierter zu machen, im Hauptformular die Kunden, im ersten Unterformular ihre Bestellungen und im zweiten Unterformular die Bestellpositionen der im ersten Unterformular ausgewählten Bestellung? Dann ist meist ein kleiner Trick erforderlich, um dies zu bewerkstelligen – wie der vorliegende Beitrag zeigt.

Herkömmliche Darstellung

Normalerweise verwendet man zur Darstellung von 1:n-Beziehungen ein Haupt- und ein Unterformular. Das Hauptformular zeigt dabei die Datensätze der Mastertabelle an, also beispielsweise die Daten der Tabelle tblKategorien. Die Anzeige ist dabei allerdings auf Formularansicht eingestellt, was bewirkt, dass nur die Daten jeweils eines Datensatzes im Formular erscheinen.

Das Unterformular zeigt die Daten der Detailtabelle an, also der Tabelle, die über ein Fremdschlüsselfeld mit den Datensätzen der Mastertabelle verknüpft ist. In unserem Beispiel handelt es sich dabei um die Tabelle tblArtikel.

Das Formular aus Bild 1 ist genau wie beschrieben aufgebaut – es zeigt die Daten der Tabelle tblKategorien im Hauptformular und die der Tabelle tblArtikel im Unterformular an. Damit das Unterformular nur die Daten der Tabelle tblArtikel anzeigt, die über das Fremdschlüsselfeld KategorieID mit dem aktuellen Datensatz der Tabelle tblKategorien im Hauptformular verknüpft sind, trägt man für die Eigenschaft Verknüpfen von des Unterformular-Steuerelements den Namen des Fremdschlüsselfeldes der Tabelle im Unterformular ein (hier KategorieID) und für die Eigenschaft Verknüpfen nach den Namen des Primärschlüsselfeldes der im Hauptformular abgebildeten Tabelle tblKategorien. Das Ergebnis finden Sie in Bild 2 vor: Sie können durch die Datensätze im Hauptformular navigieren und das Unterformular zeigt jeweils nur die passenden Datensätze an.

1:n-Beziehung in Haupt- und Unterformular mit Verknüpfungseigenschaften

Bild 1: 1:n-Beziehung in Haupt- und Unterformular mit Verknüpfungseigenschaften

1:n-Beziehung in Haupt- und Unterformular

Bild 2: 1:n-Beziehung in Haupt- und Unterformular

Zwei Unterformulare

Nun gehen wir eine Stufe weiter: Wir wollen die Kategorien nicht mehr im Hauptformular anzeigen, sondern in einem weiteren Unterformular. So hat der Benutzer nicht nur die mit einer Kategorie verknüpften Artikel im Überblick, sondern kann auch gleich die Liste der Kategorien einsehen und die gewünschte Kategorie auswählen.

Um dies zu erreichen, legen Sie zunächst ein neues Hauptformular namens frmKategorienArtikelUFUF an (UFUF für Unterformular/Unterformular). Dann erstellen Sie ein Formular namens sfmKategorienUFUF, das die Tabelle tblKategorien als Datenherkunft verwendet und seine Daten in der Datenblattansicht anzeigt. Auf ähnliche Weise erstellen Sie das Formular sfmArtikelUFUF, das Sie mit der Tabelle tblArtikel füllen – ebenfalls in der Datenblattansicht. Ziehen Sie beide Unterformulare in das Hauptformular. Da das Hauptformular seinerseits keine Daten anzeigen soll, entfernen Sie der Übersichtlichkeit halber Elemente wie die Navigationsschaltflächen, Bildlaufleisten und Datensatzmarkierer, indem Sie die entsprechenden Eigenschaften jeweils auf den Wert Nein einstellen. Beide Formulare ziehen Sie nun nebeneinander in das Hauptformular frmKategorienArtikelUFUF, sodass dieses wie in Bild 3 aussieht.

Zwei Unterformulare, die miteinander verknüpft werden sollen

Bild 3: Zwei Unterformulare, die miteinander verknüpft werden sollen

Ein Wechsel in die Formularansicht zeigt, dass die Daten schon einmal wie gewünscht erscheinen (s. Bild 4). Allerdings filtert das rechte Unterformular seine Daten noch nicht nach dem aktuell im linken Unterformular angezeigten Wert.

Aktuell zeigen beide Formulare alle Daten an, aber die Artikel werden nicht nach der aktuellen Kategorie gefiltert.

Bild 4: Aktuell zeigen beide Formulare alle Daten an, aber die Artikel werden nicht nach der aktuellen Kategorie gefiltert.

Dummerweise erkennt Access auch nicht automatisch, was wir hier vorhaben, daher füllt es die beiden Eigenschaften Verknüpfen von und Verknüpfen nach nicht automatisch aus wie im vorherigen Beispiel. Kommen wir hier überhaupt mit den beiden Eigenschaften aus? Ein Versuch, für die Eigenschaft Verknüpfen Nach einen direkten Bezug zum anderen Unterformular unterzubringen wie in Bild 5, scheitert allerdings – Access fragt den Ausdruck Parent!sfmKategorienUFUF!KategorieID in einer Inputbox ab und das Unterformular sfmArtikelUFUF bleibt leer.

Diese Einstellung funktioniert nicht.

Bild 5: Diese Einstellung funktioniert nicht.

Allerdings sollte man immer mehrere Varianten ausprobieren und vor allem eventuelle Tipp- oder Syntaxfehler ausschließen. In diesem Fall war es kein Syntaxfehler, Access kann den zunächst verwendeten Ausdruck schlicht nicht verarbeiten. Mit dem folgenden Ausdruck für die Eigenschaft Verknüpfen nach haben wir allerdings mehr Erfolg:

Forms!frmKategorienArtikelUFUF! sfmKategorienUFUF!KategorieID

Das Unterformular sfmArtikelUFUF zeigt nach dem Wechsel in die Entwurfsansicht die korrekten Daten an, also nur diejenigen Artikel, die zur aktuellen Kategorie gehören. Dummerweise ist die Begeisterung nach dem Wechsel zu einer anderen Kategorie schon wieder erledigt: Die zuvor angezeigten Artikel werden nicht gegen die der nun eingestellten Kategorie ausgetauscht.

Erst wenn man links eine neue Kategorie auswählt, dann in das rechte Unterformular klickt und dann mit der Taste F5 die Datenherkunft aktualisiert, zeigt dieses Unterformular die gewünschten Artikel-Datensätze an. Das ist allerdings ein wenig umständlich.

Also kommen wir nicht umhin, mit einer kleinen VBA-Prozedur nachzuhelfen. Da das rechte Unterformular immer dann aktualisiert werden soll, wenn der Benutzer im linken Unterformular einen anderen Datensatz ausgewählt hat, benötigen wir eine Ereignisprozedur, die durch das Ereignis Beim Anzeigen des linken Unterformulars ausgelöst wird.

Das wäre also vom linken Unterformular aus ein Verweis auf das Parent-Objekt und von dort aus auf das Unterformular-Steuerelement sfmArtikelUFUF und dann auf das darin enthaltene Form-Objekt. Für dieses soll dann die Requery-Methode ausgeführt werden, was wie folgt aussehen könnte:

Private Sub Form_Current()
     Me.Parent!sfmArtikelUFUF.Form.Requery
End Sub

Access macht uns aber beim Öffnen des Formulars mit der Fehlermeldung aus Bild 6 einen Strich durch die Rechnung.

Fehlermeldung beim Öffnen des Formulars

Bild 6: Fehlermeldung beim Öffnen des Formulars

In einem solchen Fall klickt man am besten auf die Debuggen-Schaltfläche und untersucht die aktuelle Situation durch entsprechende Prüfungen im Direktfenster des VBA-Fensters. Möglicherweise haben wir ja irgendwo einen Syntaxfehler eingebaut?

Also hangeln wir uns durch die referenzierten Elemente, wobei wir uns von links nach rechts vorarbeiten und am besten immer eine gängige Eigenschaft des jeweils referenzierten Elements abfragen. Wir starten mit dieser Abfrage:

  Me.Parent.Name
frmKategorienArtikelUFUF

Dies klappt also. Gehen wir einen Schritt weiter:

Dies war die Leseprobe dieses Artikels.
Melden Sie sich an, um auf den vollständigen Artikel zuzugreifen.

Bitte geben Sie die Zeichenfolge in das nachfolgende Textfeld ein

Die mit einem * markierten Felder sind Pflichtfelder.

Neues aus unseren Magazinen
Listenfeld: Reihenfolge mehrerer Einträge...

Wir haben bereits in mehreren Beiträgen beschrieben, wie Sie die individuelle Reihenfolge von Elementen einer Tabelle über den Inhalt eines Feldes etwa namens »ReihenfolgeID« einstellen können –... [mehr]

Diagramme mit gefilterten Daten

In Ausgabe 2/2019 haben wir in zwei Artikeln die modernen Diagramme von Access vorgestellt. Im vorliegenen Beitrag zeigen wir Ihnen, wie Sie diese abhängig von den in einem Formular angezeigten... [mehr]

Benutzerverwaltung mit verschlüsselten...

Wenn Sie in einer Access-Anwendung Benutzer verwalten wollen, die sich per Benutzername und Kennwort an die Anwendung anmelden, sollten Sie sehr sensibel mit den in der Anwendung gespeicherten... [mehr]

HTML-Tabellen mit fester Kopfzeile

In den vorherigen Ausgaben von Access im Unternehmen und in der aktuellen Ausgabe arbeiten wir in einigen Beiträgen mit dem Webbrowser-Steuerelement und stellen Daten, die wir mit den Bordmitteln... [mehr]

Flexible HTML-Tabellen mit fester Kopfzeile

Im Beitrag »HTML-Tabellen mit fester Kopfzeile« haben wir gezeigt, wie Sie Daten aus einer bestimmten Abfrage in einem Webbrowser-Steuerelement so anzeigen, dass die Spaltenköpfe oben fixiert... [mehr]

Berechtigungen per HTML verwalten

Im Beitrag »Benutzerverwaltung mit verschlüsselten Kennwörtern« stellen wir eine Lösung vor, in der wir die Berechtigungen von Benutzergruppen an Datenbankobjekten definieren. Dort benötigen wir... [mehr]

Benutzer und Berechtigungen ermitteln

In den Beiträgen »Benutzerverwaltung mit verschlüsselten Kennwörtern« und »Berechtigungen per HTML verwalten« haben wir die Voraussetzungen für eine Benutzerverwaltung geschaffen. Im vorliegenden... [mehr]

Zugriffsrechte mit Datenmakros

Es gibt verschiedene Möglichkeiten, auf Basis des aktuell angemeldeten Benutzers sicherzustellen, dass dieser nur die für ihn vorgesehenen Aktionen mit Daten durchführen darf – beispielsweise durch... [mehr]

Kennwörter generieren

Für den einen oder anderen Zweck möchten Sie vielleicht Kennwörter generieren oder in einer Benutzeroberfläche die Möglichkeit zum Generieren von Kennwörtern anbieten. Wenn Sie etwa Benutzer zu... [mehr]

Neuer Datensatz von Frontend zu Backend

Für manche Themen gibt es keine kurze, prägnante Überschrift. In diesem Fall wollen wir zeigen, wie Sie einen neuen Datensatz anlegen, der in einer temporären Tabelle im Frontend gespeichert wird,... [mehr]