Warum noch ein Access-Buch?
Für wen ist das Buch?
Jetzt bestellen
+ direkter Download des eBooks!
Nur EUR 59,95!
Fehler gefunden?
Bitte melden!
Wünsche an das Buch?
Her damit!
Was denken die Leser über dieses Buch?
Lesen Sie aktuelle Rezensionen!
Kapitel des noch nicht veröffentlichten Buchs zum Downloaden, Probelesen und Kommentieren
Beispieldatenbanken
Zusätzliches Material

Das Buch im HTML-Format

Für unbestimmte Zeit bieten Addison-Wesley und André Minhorst den kompletten Inhalt des Buchs als Download an. Schauen Sie rein und informieren Sie sich über den Inhalt! Und wenn Ihnen das Buch nützlich erscheint und Sie glauben, dass Sie etwas gelernt haben oder durch das Gelesene sogar etwas Zeit und somit Geld bei Ihrer Arbeit einsparen konnten, können Sie sich ja beim Autor und beim Verlag revanchieren - beispielsweise durch den Kauf dieses Buchs.

Am schönsten wäre es natürlich, wenn Sie das Buch direkt hier bestellen - Sie erhalten das Buch dann direkt vom Verlag, und der Autor und Verlag haben dann noch mehr davon, als wenn Sie es anderswo kaufen.

Danke für Ihr Interesse!

4.5.10 m:n- Beziehungen in Haupt- und Unterformular

4.5.11 m:n-Beziehungen per Listenfeld

Die Verwaltung von Daten aus m:n-Beziehungen erfolgt verhältnismäßig selten mit Hilfe von Listenfeldern. Der Grund ist, dass Listenfelder keine direkte Bearbeitung der angezeigten Daten ermöglichen. Daher sind Listenfelder eher zum übersichtlichen Zuweisen von Datensätzen der n-Seite zu den Datensätzen der m-Seite einer Beziehung einsetzbar.

Einsatzzwecke für die Anwendung von Listenfeldern in Zusammenhang mit m:n-Beziehungen gibt es genug: Die Verwaltung von Verteilerlisten, die das Zuordnen von Empfängern zu einer Publikation ermöglichen, Benutzer und Benutzergruppen (wie im obigen Beispiel) oder Fahrzeuge und Sonderausstattungen.

Das folgende Formular soll anhand des Beispiels der Fahrzeuge und Ausstattungsmerkmale hergeleitet werden. Zum Nachvollziehen benötigen Sie drei Tabellen: Die beiden Tabellen tblFahrzeuge und tblAusstattungen werden über die Tabelle tblFahrzeugeAusstattungen miteinander verknüpft (siehe Abbildung 4.49). Für die beiden Beziehungen legen Sie jeweils referentielle Integrität mit Löschweitergabe fest.

Abbildung 4.49: Datenmodell der Beispieltabellen

Das Formular zur Verwaltung der enthaltenen Daten besitzt als Datensatzquelle die Tabelle tblFahrzeuge und enthält die folgenden Steuerelemente (siehe Abbildung 4.50):

  • FahrzeugID und Fahrzeug: Textfelder, gebunden an die Datensatzquelle des Formulars.
  • lstVorhandeneAusstattung: Zeigt alle Datensätze der Tabelle tblAusstattungen an, die über die Tabelle tblFahrzeugeAusstattungen mit der Tabelle tblFahrzeuge verknüpft sind.
  • lstNichtVorhandeneAusstattung: Zeigt alle Datensätze der Tabelle tblAusstattungen an, die das Listenfeld lstVorhandeneAusstattung nicht anzeigt.
  • cmdEntfernen: Verschiebt das aktuell im linken Listenfeld markierte Ausstattungsmerkmal in das rechte Listenfeld.
  • cmdAlleEntfernen: Verschiebt alle Einträge des linken Listenfeldes in das rechte Listenfeld.
  • cmdHinzufuegen: Verschiebt das aktuell im rechten Listenfeld markierte Ausstattungsmerkmal in das linke Listenfeld.
  • cmdAlleHinzufuegen: Verschiebt alle Einträge des rechten Listenfeldes in das linke Listenfeld.
  • Zusätzlich zu den bereits erwähnten Funktionen soll ein Doppelklick auf einen Eintrag eines der Listenfelder den betroffenen Eintrag in das jeweils andere Listenfeld verschieben.

    Abbildung 4.50: Entwurfsansicht des Formulars zum Festlegen der Ausstattungsmerkmale eines Fahrzeugs

    Datensatzherkunft der Listenfelder

    Die Beschreibung der Steuerelemente des Formulars hat den Inhalt der beiden Listenfelder bereits scharf umrissen. Da der Inhalt des rechten Listenfeldes vom Inhalt des linken Listenfeldes abhängt, beginnen Sie mit dem linken Listenfeld.

    Es soll alle Datensätze der Tabelle tblAusstattungen enthalten, die über die Tabelle tblFahrzeugeAusstattungen mit der Tabelle tblFahrzeuge verknüpft sind. Das aktuell angezeigte Fahrzeug lässt sich über das Feld FahrzeugID identifizieren. Da die Verknüpfungstabelle den entsprechenden Wert bereits enthält, besteht die Abfrage für die Datensatzherkunft aus den beiden Tabellen tblFahrzeugeAusstattungen und tblAusstattungen (siehe Abbildung 4.51).

    Das Listenfeld soll die Bezeichnung des Ausstattungsmerkmals anzeigen, aber das Feld AusstattungID als gebundene Spalte verwenden; das Feld FahrzeugID ist nur als Kriterium vorgesehen und muss gar nicht angezeigt werden.

    Damit das Listenfeld die erste Spalte mit dem Feld AusstattungID ausblendet, stellen Sie die Eigenschaften Spaltenanzahl und Spaltenbreite auf die Werte 2 beziehungsweise 0cm ein.

    Abbildung 4.51: Datensatzherkunft des Listenfeldes lstVorhandeneAusstattung (»frmFahrzeuge«)

    Wenn Sie die Tabellen aus der Beispieldatenbank verwenden oder bereits selbst Beispieldaten eingegeben haben, können Sie nun ausprobieren, ob das Listenfeld die gewünschten Daten anzeigt. Beim ersten angezeigten Fahrzeug sollte dies funktionieren, beim Blättern zum nächsten Fahrzeug verändert sich der Inhalt des Listenfeldes allerdings nicht. Das liegt daran, dass seine Datensatzherkunft nicht aktualisiert wird.

    Legen Sie also die folgende Prozedur an, die durch das Ereignis Beim Anzeigen des Formulars ausgelöst wird:

    Private Sub Form_Current()
        'Aktualisieren des linken Listenfeldes
        Me!lstVorhandeneAusstattung.Requery
    End Sub

    Listing 4.17: Diese Prozedur sorgt für die Aktualisierung des Listenfeldes beim Datensatzwechsel

    Legen Sie nun die Abfrage an, die als Datensatzherkunft für das zweite Listenfeld dient. Das Listenfeld soll alle Ausstattungen anzeigen, die nicht zu einem Fahrzeug gehören und die nicht über die Tabelle tblFahrzeugeAusstattungen mit der Tabelle tblFahrzeuge verknüpft sind. Das sind alle Datensätze der Tabelle tblAusstattungen, die nicht im linken Listenfeld angezeigt werden - also formulieren Sie die Abfrage auch einfach so. Diese enthält zunächst lediglich die beiden Felder der Tabelle tblAusstattungen. Den Bezug zu der Abfrage, die als Datensatzherkunft des linken Listenfeldes dient, erstellen Sie über das Kriterium für das Feld AusstattungID: Dort schließen Sie über das Schlüsselwort NOT IN alle Ausstattungen der Abfrage des linken Listenfeldes aus. Allerdings müssen Sie die dortige Abfrage noch ein wenig bearbeiten, da die für IN-Bedingungen verwendeten Unterabfragen nur ein Feld ausgeben dürfen. Den in Abbildung 4.52 nicht komplett zu erkennenden Ausdruck für die Bedingung finden Sie hier:

    Nicht In (SELECT tblAusstattungen.AusstattungID FROM tblAusstattungen
    INNER JOIN tblFahrzeugeAusstattungen ON tblAusstattungen.AusstattungID = tblFahrzeugeAusstattungen.AusstattungID WHERE tblFahrzeugeAusstattungen.FahrzeugID=[Forms]![frmFahrzeuge]![FahrzeugID])

    Abbildung 4.52: Datensatzherkunft des Listenfeldes der nicht vorhandenen Ausstattungsmerkmale (»frmFahrzeuge«)

    Nun zeigen die beiden Listenfelder bereits die gewünschten Daten an (siehe Abbildung 4.53). Als Nächstes bringen Sie ein wenig Leben in die Schaltflächen und Listenfelder, um das Formular zum Hinzufügen und Entfernen von Datensätzen in der Tabelle tblFahrzeugeAusstattungen verwenden zu können.

    Damit auch das rechte Listenfeld beim Datensatzwechsel aktualisiert wird, ergänzen Sie die Ereignisprozedur Form_Current wie im folgenden Listing:

    Private Sub Form_Current()
        'Aktualisieren des linken Listenfeldes
        Me!lstVorhandeneAusstattung.Requery
        'Aktualisieren des rechten Listenfeldes
        Me!lstNichtVorhandeneAusstattung.Requery
    End Sub

    Listing 4.18: Aktualisieren der Listenfelder

    Abbildung 4.53: Die Listenfelder zeigen bereits die richtigen Daten an (»frmFahrzeuge«)

    Hinzufügen eines Ausstattungsmerkmals

    Das Formular bietet zwei Möglichkeiten zum Hinzufügen eines einzelnen Ausstattungsmerkmals zu einem Fahrzeug: per Doppelklick auf den gewünschten Eintrag im Listenfeld lstNichtVorhanden oder durch Markieren des Eintrags im selben Listenfeld und anschließendes Betätigen der Schaltfläche cmdHinzufuegen.

    Da in beiden Varianten die gleiche Aktion ausgelöst werden soll, legen Sie diese in einer separaten Prozedur an, die von der jeweiligen Ereignisprozedur der beiden Steuerelemente aus aufgerufen wird.

    Für das Anlegen des neuen Datensatzes in der Tabelle tblFahrzeugeAusstattungen müssen Sie die zukünftigen Werte der Felder FahrzeugID und AusstattungID kennen. Diese ermitteln Sie in den beiden Ereignisprozeduren Beim Klicken der Schaltfläche cmdHinzufuegen und Beim Doppelklicken des Listenfeldes lstNichtVorhanden und rufen von dort aus die Prozedur Hinzufuegen auf. Sollte einer der beiden Werte nicht vorhanden sein, was der Fall ist, wenn entweder kein hinzuzufügender Eintrag des Listenfeldes markiert ist oder das Formular einen neu angelegten Fahrzeug-Datensatz enthält, wird die Hinzufuegen-Prozedur nicht aufgerufen.

    Private Sub cmdHinzufuegen_Click()
        If Not IsNull(Me!FahrzeugID) And _
            Not IsNull(Me!lstNichtVorhandeneAusstattung) Then
            Hinzufuegen Me!FahrzeugID, Me!lstNichtVorhandeneAusstattung
        End If
    End Sub

    Private Sub lstNichtVorhandeneAusstattung_DblClick(Cancel As Integer)
        If Not IsNull(Me!FahrzeugID) And _
            Not IsNull(Me!lstNichtVorhandeneAusstattung) Then
            Hinzufuegen Me!FahrzeugID, Me!lstNichtVorhandeneAusstattung
        End If
    End Sub

    Listing 4.19: Aufrufen der Prozedur zum Anlegen eines neuen Datensatzes in der Tabelle tblFahrzeugeAusstattungen

    Die Prozedur Hinzufuegen erwartet als Parameter die Fahrzeug-ID und die Ausstattungs-ID des zu erstellenden Datensatzes. Nach der Durchführung der Aktionsabfrage aktualisiert die Prozedur die beiden Listenfelder.

    Private Sub Hinzufuegen(lngFahrzeugID As Long, _
        lngAusstattungID As Long)
        Dim db As DAO.Database
        Dim strSQL As String
        Set db = CurrentDb
        'Zusammen der Anfügeabfrage
        strSQL = "INSERT INTO tblFahrzeugeAusstattungen" _
            & "(FahrzeugID, AusstattungID) VALUES(" _
            & lngFahrzeugID & ", " & lngAusstattungID & ")"
        'Ausführen der Anfügeabfrage
        db. Execute strSQL
        'Aktualisieren der Listenfelder
        Me!lstVorhandeneAusstattung.Requery
        Me!lstNichtVorhandeneAusstattung.Requery
        Set db = Nothing
    End Sub

    Listing 4.20: Prozedur zum Hinzufügen eines Datensatzes zur Tabelle tblFahrzeugeAusstattungen

    Entfernen eines Ausstattungsmerkmals

    Zum Entfernen eines Ausstattungsmerkmals eines Fahrzeugs gibt es ebenfalls zwei Möglichkeiten. Entweder Sie markieren den zu entfernenden Datensatz und klicken auf die Schaltfläche zum Entfernen eines Datensatzes oder Sie klicken doppelt auf den zu entfernenden Eintrag im Listenfeld. Der Aufbau der dadurch ausgelösten Prozeduren ist identisch mit dem der Prozeduren zum Hinzufügen eines Ausstattungsmerkmals und die Prozedur Entfernen ist das Pendant zur Prozedur Hinzufuegen. Lediglich die verwendete SQL-Anweisung hat ein anderes Aussehen:

    Private Sub Entfernen(lngFahrzeugID As Long, lngAusstattungID As Long)
        Dim db As DAO.Database
        Dim strSQL As String
        Set db = CurrentDb
        strSQL = "DELETE FROM tblFahrzeugeAusstattungen " _
            & "WHERE FahrzeugID = " & lngFahrzeugID _
            & " AND AusstattungID = " & lngAusstattungID
        db. Execute strSQL
        Me!lstVorhandeneAusstattung.Requery
        Me!lstNichtVorhandeneAusstattung.Requery
        Set db = Nothing
    End Sub

    Listing 4.21: Prozedur zum Entfernen eines Ausstattungsmerkmals eines Fahrzeugs

    Hinzufügen oder Entfernen aller Ausstattungsmerkmale

    Die beiden Schaltflächen mit dem doppelten Kleiner- beziehungsweise Größer-Zeichen bewegen jeweils alle Ausstattungen eines Fahrzeugs von einem Listenfeld ins andere. Aus Datensicht bedeutet das, dass entweder für jedes Ausstattungsmerkmal in Kombination mit dem aktuell angezeigten Fahrzeug ein Datensatz in der Tabelle tblFahrzeugeAusstattungen angelegt wird oder dass alle vorhandenen Einträge für ein Fahrzeug entfernt werden. Das Hinzufügen aller Ausstattungsmerkmale erledigt die Prozedur, die durch das Ereignis Beim Klicken der Schaltfläche cmdAlleHinzufuegen ausgelöst wird. Im Gegensatz zu den Prozeduren zum Hinzufügen eines einzelnen Datensatzes braucht hier nicht geprüft zu werden, ob ein Eintrag des Listenfeldes markiert ist:

    Private Sub cmdAlleHinzufuegen_Click()
        Dim db As DAO.Database
        Dim strSQL As String
        If Not IsNull(Me!FahrzeugID) Then
            Set db = CurrentDb
            strSQL = "INSERT INTO tblFahrzeugeAusstattungen " _
                & "SELECT " & Me!FahrzeugID & " AS FahrzeugID, " _
                & "AusstattungID FROM tblAusstattungen"
            db.Execute strSQL
            Me!lstVorhandeneAusstattung.Requery
            Me!lstNichtVorhandeneAusstattung.Requery

            Set db = Nothing
        End If
    End Sub

    Listing 4.22: Hinzufügen aller vorhandenen Ausstattungsmerkmale zu einem Fahrzeug

    Das Entfernen aller Ausstattungen eines Fahrzeugs geschieht in der folgenden Prozedur. Der wesentliche Unterschied zur vorherigen Prozedur liegt in der SQL-Anweisung:

    Private Sub cmdAlleEntfernen_Click()
        Dim db As DAO.Database
        Dim strSQL As String
        If Not IsNull(Me!FahrzeugID) Then
            Set db = CurrentDb
            strSQL = "DELETE FROM tblFahrzeugeAusstattungen " _
                & "WHERE FahrzeugID = " & Me!FahrzeugID
            db.Execute strSQL
            Me!lstVorhandeneAusstattung.Requery
            Me!lstNichtVorhandeneAusstattung.Requery
            Set db = Nothing
        End If
    End Sub

    Listing 4.23: Entfernen aller Ausstattungsmerkmale eines Fahrzeugs

    Nächster Abschnitt:

    4.5.12 Reflexive Beziehungen

    © 2006-2008 André Minhorst Alle Rechte vorbehalten.