Bild 1: Beispiel für ein mehrwertiges Feld
In einem anderen Beitrag namens „Mehrwertige Felder mit Wertliste loswerden“ (www.access-im-unternehmen.de/13) beschreiben wir, wie man die in Access 2010 eingeführten mehrwertige Felder durch m:n-Beziehungen ersetzt. Es fehlt dann allerdings die praktische Liste mit Kontrollkästchen, mit der man einen oder mehrere der zu verknüpfenden Elemente einfach markieren kann. Auf diese Weise lassen sich schnell die Kategorien zu einem Produkt oder auch die Ausstattungen für Fahrzeuge zusammenklicken. Da für uns das Motto „Wer A sagt, muss auch B sagen“ gilt, liefern wir also noch eine Möglichkeit hinterher, um die aus den mehrwertigen Feldern in eine m:n-Beziehung überführten Daten auf praktische Weise anzuzeigen.
Dabei verwenden wir die Beispiele, die wir in dem oben genannten Beitrag Mehrwertige Felder mit Wertliste loswerden (www.access-im-unternehmen.de/13) verwendet haben. Wir beginnen wieder mit den Produkten und ihren Kategorien. In der Beispieldatenbank finden wir in der Tabelle tblProdukte noch das Feld Kategorien, das als mehrwertiges Feld mit einer Wertliste als Datensatzherkunft ausgestattet ist (siehe Bild 1).
Bild 1: Beispiel für ein mehrwertiges Feld
Wenn wir diese Tabelle als Datensatzquelle für ein Formular verwenden, alle Felder in den Detailbereich ziehen und dann noch das Feld Kategorien in ein Listenfeld umwandeln, erhalten wir eine Ansicht wie in Bild 2. Das ist sehr praktisch und eine schöne Alternative zu den übrigen Möglichkeiten, eine m:n-Beziehung abzubilden.
Bild 2: Beispiel für ein als Listenfeld abgebildetes mehrwertiges Feld
Nun haben wir allerdings das mehrwertige Feld durch eine m:n-Beziehung ersetzt, in der alle Kategorien in der Tabelle tblKategorien gespeichert werden und in der die Verknüpfungstabelle tblProdukteKategorien die Zuordnung von Produkten zu Kategorien aufnimmt (siehe Bild 3). Damit erhalten wir ein Datenmodell, das wir nicht nur komplett steuern können (das mehrwertige Feld wurde intern von Access verwaltet). Wir können ein solches Datenmodell auch zum SQL Server überführen. Dies wäre mit einem mehrwertigen Feld nicht möglich gewesen – hier würden zwar die für ein Produkt ausgewählten Kategorien übernommen werden, aber die Liste aller Kategorien und die Auswahlmöglichkeit fallen unter den Tisch.
Bild 3: Die aufgeteilten Daten eines mehrwertigen Feldes
Das Ziel dieses Beitrags ist es nun, die Daten im Formular so abzubilden, wie es zuvor beim mehrwertigen Feld in der Ausführung als Listenfeld mit Kontrollkästchen der Fall war.
In einem Listenfeld werden wir das nicht abbilden können, denn dieses erlaubt nicht die Verwendung von Kontrollkästchen. Hier könnten wir allenfalls alle für das aktuelle Produkt ausgewählten Kategorien markieren. Alternativ könnten wir auch noch das ListView-Steuerelement nutzen, das ein Kontrollkästchen je Eintrag anzeigen kann. Aber wir wollen in diesem Fall mit Access-Bordmitteln auskommen.
Wie also können wir das erledigen? Die einzigen beiden Möglichkeiten, Datensätze inklusive Kontrollkästchen darzustellen, sind die Endlosansicht und die Datenblattansicht eines Formulars beziehungsweise Unterformulars.
Bei der Datenblattansicht werden allerdings zwingend die Spaltenüberschriften angezeigt. Da wir eine möglichst genaue Abbildung des mehrwertigen Listenfeldes erhalten wollen, fällt diese Variante also weg. Es bleibt noch die Verwendung der Endlosansicht. Diese bietet außerdem alle gestalterischen Möglichkeiten.
Überlegungen zur Darstellung der zugeordneten Datei
Bevor wir loslegen, müssen wir uns überlegen, wie wir die Darstellung erhalten. In einer herkömmlichen Konstellation aus Haupt- und Unterformular zur Darstellung einer m:n-Beziehung landet die m-Tabelle, in diesem Beispiel die Tabelle tblProdukte, im Hauptformular. Im Unterformular bilden wir die Daten der Verknüpfungstabelle ab, gegebenenfalls erweitert um die Daten der n-Tabelle. Das Unterformular-Steuerelement wird so eingerichtet, dass das Unterformular immer nur die Datensätze der m:n-Tabelle anzeigt, die mit dem Datensatz im Hauptformular verknüpft sind.
Wir können üblicherweise mit Haupt- und Unterformular also immer nur alle verknüpften Datensätze der n-Tabelle anzeigen. Wir wollen aber alle Datensätze der n-Tabelle anzeigen und für diejenigen, die über die m:n-Verknüpfungstabelle dem aktuell angezeigten Datensatz der m-Tabelle zugeordnet sind, ein markiertes Kontrollkästchen hinzufügen. Das gelingt auf diesem zunächst eingeschlagenen Weg nicht.
Stattdessen müssen wir eine Darstellung finden, die alle Datensätze der n-Tabelle anzeigt, hier tblKategorien, und die noch ein Kontrollkästchen hinzufügt, das die für den aktuellen Datensatz im Hauptformular selektierten Kategorien liefert. Wir haben es hin- und hergedreht und mit diversen Abfragetypen experimentiert. Wie haben keine praktikable Lösung gefunden. Also wählen wir einen völlig anderen Ansatz.
Alle Kategorien plus Markierung der zugeordneten Kategorien
Die einfachere, weil sichtbare Lösung ist die Verwendung einer temporären Tabelle. Diese nennen wir tblKategorienSelektiert und entwerfen sie wie in Bild 4. Neben den beiden Feldern KategorieID und Kategorie fügen wir dieser das Ja/Nein-Feld Zugeordnet hinzu. Das Feld KategorieID statten wir nicht mit der Autowert-Funktion aus, da wir die Werte für dieses Feld später selbst eintragen wollen.
Bild 4: Temporäre Tabelle
Diese Tabelle fügen wir dem Unterformular hinzu und sorgen per Code dafür, dass diese beim Anzeigen eines Produkt-Datensatzes im Hauptformular jeweils geleert und neu gefüllt wird.
Hauptformular erstellen
Dieses Endlosansicht legen wir in einem Unterformular an. Als Erstes erstellen wir das Hauptformular für unsere Lösung. Dieses verwendet die Tabelle tblProdukte als Datensatzquelle. Aus der Tabelle ziehen wir die beiden Felder ProduktID und Produktname in den Detailbereich des Formulars (siehe Bild 5).
Bild 5: Anlegen des Hauptformulars
Unterformular erstellen
Nun erstellen wir das Unterformular namens sfmProdukteKategorien. Diesem weisen wir die Tabelle tblKategorienSelektiert als Datensatzquelle zu und ziehen die beiden Felder Zugeordnet und Kategorie in den Detailbereich des Formulars.
Die beiden Bezeichnungsfelder, die beim Hineinziehen der Felder in den Detailbereich automatisch angelegt wurden, entfernen wir. Dann ordnen wir die verbleibenden beiden Steuerelemente wie im mehrwertigen Listenfeld an (siehe Bild 6). Für das Textfeld Kategorie stellen wir die Eigenschaft Horizontaler Anker auf Beide ein, damit es beim Verbreitern des Steuerelements angepasst wird.
Bild 6: Unterformular mit den Kategorien und der Möglichkeit zum Selektieren
Schließlich stellen wir noch die Eigenschaft Standardansicht auf Endlosformular ein. Damit die üblichen Elemente eines Formulars ausgeblendet werden, stellen wir außerdem die Eigenschaften Datensatzmarkierer und Navigationsschaltflächen auf Nein ein. Die Eigenschaft Trennlinien ist in neueren Access-Versionen ohnehin bereits deaktiviert.
Außerdem zeigt das Formular seine Datensätze aktuell noch mit alternierender Hintergrundfarbe an. Das ändern wir, indem wir den Detailbereich des Unterformulars markieren und dort im Bereich Format die Eigenschaft Alternative Hintergrundfarbe auf den gleichen Wert einstellen wie die Eigenschaft Hintergrundfarbe.
Um die Optik perfekt zu machen, entfernen wir noch den Rahmen des Textfeldes. Dazu stellen wir die Eigenschaft Rahmenart auf Transparent ein.
Dieses Formular ziehen wir nun als Unterformular in das Formular frmProdukteKategorien. Das Ergebnis sieht wie in Bild 7 aus. Die beiden Eigenschaften Verknüpfen von und Verknüpfen nach des Unterformular-Steuerelements sollten unbedingt leer sein.
Bild 7: Einbau des Unterformulars
Wechseln wir nun in die Formularansicht, erhalten wir schon einmal einen Einblick, wie das Formular später aussehen könnte (siehe Bild 8). Allerdings ist das Unterformular noch leer. Dies ändern wir allerdings jetzt.
Bild 8: Das noch leere Unterformular in der Formularansicht
Unterformular füllen
Dazu hinterlegen wir für das Ereignis Beim Anzeigen des Hauptformulars die Ereignisprozedur aus Listing 1.
Private Sub Form_Current() Dim db As DAO.Database Dim rst As DAO.Recordset Set db = CurrentDb db.Execute "DELETE FROM tblKategorienSelektiert", dbFailOnError db.Execute "INSERT INTO tblKategorienSelektiert(KategorieID, Kategorie) SELECT KategorieID, Kategorie " _ & "FROM tblKategorien ORDER BY Kategorie ASC", dbFailOnError db.Execute "UPDATE tblKategorienSelektiert SET Zugeordnet = -1 WHERE KategorieID IN (SELECT KategorieID " _ & "FROM tblProdukteKategorien WHERE ProduktID = " & Me.ProduktID & ")", dbFailOnError Me.sfmProdukteKategorien.Form.Requery End Sub
Listing 1: Füllen der Datensatzquelle des Unterformulars
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