Beziehungen per DAO verwalten

Beziehungen legt man normalerweise über das Beziehungsfenster an – oder man bemüht den Nachschlage-Assistenten, der zusätzlich zum Nachschlagefeld auch noch die Beziehung erstellt. Manche Anforderungen verlangen jedoch, dass man Beziehungen per VBA erstellt oder diese ausliest. In diesem Beitrag finden Sie daher alles, was Sie zum Thema Beziehungen und DAO wissen müssen.

Beziehungen

Beziehungen dienen dazu, Datensätze verschiedener Tabellen zu verknüpfen. Dabei besitzt die eine Tabelle einen eindeutigen Wert im Primärschlüsselfeld. Die andere Tabelle besitzt ein Fremdschlüsselfeld, das im Normalfall nur Werte aufnehmen sollte, die im Primärschlüsselfeld der ersten Tabelle vorkommen. Die beiden Tabellen heißen Master- und Detailtabelle, wobei die Tabelle mit dem an der Beziehung beteiligten Primärschlüsselfeld die Mastertabelle und die mit dem Fremdschlüsselfeld die Detailtabelle ist.

Beziehungen auslesen

Wenn Sie per Code die Beziehungen einer Datenbank auslesen möchten, erledigen Sie dies beispielsweise mit dem Relation-Objekt der DAO-Bibliothek. Es gibt für jede Beziehung, also für jeden Beziehungspfeil im Beziehungsfenster, ein Relation-Objekt in der Datenbank. Die Relation-Objekte referenzieren Sie entweder über die Relations-Auflistung. Diese Auflistung ist wiederum ein Element des Database-Objekts. Dies führt zu einer recht einfachen Prozedur, um die Anzahl der Beziehungen und deren Namen auszugeben – hier für die Beziehungen der Südsturm-Datenbank aus Bild 1:

pic001.png

Bild 1: Beziehungen in der Südsturm-Datenbank

Public Sub BeziehungenAuflisten()
    Dim db As DAO.Database
    Dim rel As DAO.Relation
    Set db = CurrentDb
    Debug.Print "Anzahl Beziehungen: " _
& db.Relations.Count
    For Each rel In db.Relations
        Debug.Print rel.Name
    Next rel
End Sub

Das Ergebnis sind die Anzahl und eine Liste der Namen der Beziehungen, die sich jeweils aus den in beiden Tabellen gespeicherten Elementen zusammensetzen:

Anzahl Beziehungen: 7
ArtikelBestelldetails
BestellungenBestelldetails
KategorienArtikel
LieferantenArtikel
PersonalBestellungen
tblKundentblBestellungen
VersandfirmenBestellungen

Welche Informationen liefert ein solches Relation-Objekt Natürlich finden Sie dort zumindest die für eine Beziehung notwendigen Informationen, also die Namen der beteiligten Felder und Tabellen: der Mastertabelle mit dem Primärschlüsselfeld und der Detailtabelle mit dem Fremdschlüsselfeld.

Diese Informationen liefert beispielsweise die folgende Prozedur:

Public Sub BeziehungsdatenAusgeben()
    Dim db As DAO.Database
    Dim rel As DAO.Relation
    Set db = CurrentDb
    For Each rel In db.Relations
        Debug.Print rel.Name
        Debug.Print "=================="
        Debug.Print "Mastertabelle:"
        Debug.Print "  " & rel.Table
        Debug.Print "  " & rel.Fields(0).Name
        Debug.Print "Detailtabelle:"
        Debug.Print "  " & rel.ForeignTable
        Debug.Print "  " & rel.Fields(0).ForeignName
        Debug.Print ""
    Next rel
End Sub

Für eine einzige Beziehung sieht das Ergebnis etwa wie folgt aus:

tblKundentblBestellungen
==================
Mastertabelle:
  tblKunden
  KundeID
Detailtabelle:
  tblBestellungen
  KundeID

Dabei legen Sie im Fremdschlüsselfeld KundeID der Detailtabelle tblBestellungen fest, zu welchem Kunden aus der Tabelle tblKunden, hier referenziert über einen der Werte des Primärschlüsselfeldes KundeID der Mastertabelle, eine Bestellung gehört.

Wichtig ist, dass Table und Fields(0).Name immer die Daten zur Mastertabelle und ForeignTable und Fields(0).ForeignName die Daten zur Detailtabelle liefern.

Ach, und warum eigentlich der Bezug zum ersten Element der Fields-Auflistung Kann es denn Beziehungen geben, die mehr als ein Feld enthalten Ja, das funktioniert, und zwar wie in Bild 3.

pic009.png

Bild 3: Beziehung über zwei Felder

Dies macht in der Praxis nur wenig Sinn, aber für genau eine solche Definition können Sie mehr als ein Feld aus der Fields-Auflistung des Relation-Objekts auslesen. Im Modul mdlDAOBeziehungen der Beispieldatenbank finden Sie unter BeziehungsdatenAusgeben_MehrereFelder ein Beispiel, wie Sie auch die Felder solcher Beziehungen auslesen können (wir werden Ihnen nicht zeigen, wie Sie solche Beziehungen per VBA anlegen …).

Attribute der Beziehung

Weitere Informationen liefert die Eigenschaft Attributes. Diese enthält einen Zahlenwert, der verschiedene Eigenschaftswerte verknüpft.

Die möglichen Werte lauten wie folgt und sind etwa im Objektkatalog zu finden (s. Bild 2):

pic002.png

Bild 2: Attributes-Konstanten im Objektkatalog

  • dbRelationUnique (1): Kennzeichnet eine 1:1-Beziehung.
  • dbRelationDontEnforce (2): Beziehung ohne referentielle Integrität.
  • dbRelationInherited (4): Beziehung besteht zwischen den Tabellen einer verknüpften Datenbank.
  • dbRelationUpdateCascade (256): Beziehung mit Aktualisierungsweitergabe.
  • dbRelationDeleteCascade (4096): Beziehung mit Löschweitergabe.
  • dbRelationLeft (16777216): Kennzeichnet ein LEFT JOIN zwischen den Tabellen.
  • dbRelationRight (33554432): Kennzeichnet ein RIGHT JOIN zwischen den Tabellen.

Alle Informationen über eine Beziehung liefert nun die Prozedur aus Bild 4):

Listing 1: Ermitteln aller Eigenschaften einer Beziehung

Public Sub BeziehungsdatenAusgeben()
    Dim db As DAO.Database
    Dim rel As DAO.Relation
    Set db = CurrentDb
    For Each rel In db.Relations
        Debug.Print rel.Name
        Debug.Print "=================="
        Debug.Print "Mastertabelle: " & rel.Table & " (" & rel.Fields(0).Name & ")"
        Debug.Print "Detailtabelle: " & rel.ForeignTable & " (" & rel.Fields(0).ForeignName & ")"
        Debug.Print "Attribute: ", rel.Attributes
        If (rel.Attributes And dbRelationUnique) = dbRelationUnique Then
            Debug.Print " 1 - dbRelationUnique"
        End If
        If (rel.Attributes And dbRelationDontEnforce) = dbRelationDontEnforce Then
            Debug.Print " 2 - dbRelationDontEnforce"
        End If
        If (rel.Attributes And dbRelationInherited) = dbRelationInherited Then
            Debug.Print " 4 - dbRelationInherited"
        End If
        If (rel.Attributes And dbRelationUpdateCascade) = dbRelationUpdateCascade Then
            Debug.Print " 256 - dbRelationUpdateCascade"
        End If
        If (rel.Attributes And dbRelationDeleteCascade) = dbRelationDeleteCascade Then
            Debug.Print " 4096 - dbRelationDeleteCascade"
        End If
        If (rel.Attributes And dbRelationLeft) = dbRelationLeft Then
            Debug.Print " 16777216 - dbRelationLeft"
        End If
        If (rel.Attributes And dbRelationRight) = dbRelationRight Then
            Debug.Print " 33554432 - dbRelationRight"
        End If
        Debug.Print ""
    Next rel
End Sub

pic004.png

Bild 4: Einfache relationale Beziehung

KategorienArtikel
==================
Mastertabelle: tblKategorien (KategorieID)
Detailtabelle: tblArtikel (KategorieID)
Attribute:     0 

Das bedeutet, dass die Beziehung keine Löschweitergabe und keine Aktualisierungsweitergabe enthält, aber dass referentielle Integrität definiert wurde. Dies ist der Standardfall: Besteht keine referentielle Integrität, würde Attributes den Wert 2 (RelationDontEnforce) enthalten. Eine 1:1-Beziehung mit Lösch- und Aktualisierungsweitergabe liefert hingegen diese Ausgabe – man achte auf den Wert dbRelationUnique (s. Bild 5):

pic003.png

Bild 5: 1:1-Beziehung mit Lösch- und Aktualisierungsweitergabe

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