DAO-Objekte und -Auflistungen, Teil II

Waren Containers, Documents und Properties Thema der letzten Ausgabe über DAO-Objekte, so geht es diesmal abschließend um Relations und Workspaces. Dabei handelt es sich zum einen um die Abbildung und Manipulation von Tabellenbeziehungen im Objektmodell, zum anderen um die sogenannten Arbeitsbereiche der Access Database Engine. Erfahren Sie, wie Tabellenbeziehungen einer Datenbank ermittelt und neu angelegt werden können.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1511_DAORelations.accdb

Beziehungsbeispiel

Die Beispieldatenbank enthält vier uns mittlerweile wohlbekannte Tabellen, die über einige Beziehungen miteinander verknüpft sind. Zu den Feldern IDAnrede, IDOrt und IDLand der Tabelle tblAdressen existieren drei Nachschlagetabellen, die mit ihr auf unterschiedliche Weise in Beziehung stehen (siehe Bild 1). Für unsere Zwecke wurden die Beziehungen zum Testen auf etwas eigentümliche Weise modifiziert, die so allerdings keinen rechten Sinn mehr ergeben.

Beziehungslayout der Beispieldatenbank

Bild 1: Beziehungslayout der Beispieldatenbank

Bild 2 zeigt die Einstellungen für die Beziehung zwischen Adressen- und Anreden-Tabelle. Die Referenzielle Integrität wurde ausgeschaltet, aber der Typ mit 1:n beibehalten. Die Einstellungen für die Nachschlagetabelle zu Orten findet sich in Bild 3. Hier wurde nichts verändert. Schließlich stellt Bild 4 die Beziehung für die Länder-Tabelle dar, bei der jeweils zwei Felder verknüpft wurden. Neben dem eigentlichen Primärschlüsselfeld ID zu IDAnrede ist zusätzlich der Ländername Land selbst in der zweiten Zeile 1:n-verknüpft. Außerdem ist der Typ der Beziehung, erreichbar über die Schaltfläche Verknüpfungstyp…, auf den dritten Modus eingestellt, was sie zu einer Left-Join-Beziehung macht (Bild 5) Mit diesen Vorgaben lässt sich Referenzielle Integrität ohnehin nicht mehr festlegen, weil keine Eindeutigkeit mehr gegeben ist.

Einstellungen für die Beziehung zur Tabelle tblOrte

Bild 2: Einstellungen für die Beziehung zur Tabelle tblOrte

Verknüpfungstyp der Beziehung zu tblLaender

Bild 3: Verknüpfungstyp der Beziehung zu tblLaender

Einstellung für die Beziehung zur Tabelle tblLaender

Bild 4: Einstellung für die Beziehung zur Tabelle tblLaender

Einstellungen der Beziehung zur Tabelle tblAnreden

Bild 5: Einstellungen der Beziehung zur Tabelle tblAnreden

Beziehungen auslesen

Für die Beziehungen einer Datenbank ist über das VBA-Objekt Database deren Auflistungseigenschaft Relations zuständig. Die kurze Routine GetRelations in Listing 1 macht deutlich, wie die einzelnen Relation-Objekte in einer For-Each-Schleife durchlaufen werden können.

Sub GetRelations()
     Dim dbs As Database
     Dim rel As DAO.Relation
     
     Set dbs = CurrentDb
     For Each rel In dbs.Relations
         Debug.Print rel.Name
     Next rel
End Sub

Listing 1: Prozedur zum Durchlaufen der DAO-Auflistung Relations

Zunächst wird die Database-Variable dbs über die Funktion CurrentDb auf eine aktuelle Instanz der Datenbank gesetzt. Als Schleifenvariable kommt die Variable rel vom Typ DAO.Relation zum Einsatz. Im VBA-Direktfenster wird dann lediglich der Name der Beziehung ausgegeben. Als Ergebnis erhalten Sie dies:

MSysNavPaneGroupCategoriesMSysNavPaneGroupsMSysNavPaneGroupsMSysNavPaneGroupToObjectstblAnredentblAdressentblLaendertblAdressentblOrtetblAdressen

Dass Beziehungen überhaupt Namen haben, ist nicht so selbstverständlich, denn diese tauchen in der Oberfläche von Access nirgendwo auf. Im Beziehungsfenster sind sie auch in den Eigenschaftsdialogen nicht angegeben. Wie Sie sehen können, leiten sich die Namen aus den an der Beziehung beteiligten Tabellen ab. Die ersten beiden oben angegebenen Beziehungen sind übrigens in jeder Datenbank im Access 2007-Format vorhanden. Access legt sie selbst an.

Diese speziellen MSys-Tabellen dienen der Verwaltung und Steuerung des Navigationsbereichs.

Weiten wir nun die einfache Prozedur aus Listing 1 einmal ab, um mehr über die Beziehungen zu erfahren. Die Routine in Listing 2 hat den gleichen Grundaufbau, gibt aber neben den Namen auch noch die an der Verknüpfung beteiligten Tabellen über die Eigenschaften Table und ForeignTable der jeweiligen Relations-Objekte wieder. Das Ergebnis, hier unter Ausschluss der MSys-Beziehungen:

Sub GetRelationsTables()
     Dim dbs As Database
     Dim rel As DAO.Relation
     
     Set dbs = CurrentDb
     For Each rel In dbs.Relations
         Debug.Print rel.Name
         Debug.Print , rel.Table
         Debug.Print , rel.ForeignTable
         Debug.Print , rel.Attributes
     Next rel
End Sub

Listing 2: Ausgabe weiterer Bezihungseigenschaften (Tabellen)

tblAnredentblAdressen
               tblAnreden
               tblAdressen
                2 
tblLaendertblAdressen
               tblLaender
               tblAdressen
                33554434 
tblOrtetblAdressen
               tblOrte
               tblAdressen
               0

Table ist also jene Tabelle, welche den Primärschlüssel in der Beziehung aufweist, ForeignTable die Tabelle mit dem Fremdschlüsselfeld. Die Zahl, die Attributes enthält, gibt darüber hinaus Aufschluss auf die Art der Beziehung. Es handelt sich hierbei um eine Kombination von Konstanten der Enumeration RelationAttributeEnum von DAO – siehe Objektkatalog. Der Wert 0 besagt dabei, dass die Beziehung Referenzielle Integrität fordert. Ist dies nicht der Fall, so steht hier eine 2. Die Zahl 33554434 ergibt sich aus der booleschen Addition von dbRelationRight (33554432) mit dbRelationDontEnforce (2), was eine Right-Verknüpfung ohne Referenzielle Integrität symbolisiert. Damit Sie den Typ nicht langwierig über die Analyse der Konstanten im Objektkatalog ermitteln müssen, gibt es im Modul mdlDAORelations die Funktion AttributesString, der Sie die Attributes-Konstante als Parameter übergeben und als Rückgabe eine Textrepräsentation des Typs erhalten:

  AttributesString(2)
> 1:n,Keine Ref. Integrität
  AttributesString(33554434)
> 1:n,Right Join,Keine Ref. Integrität

Sie können, statt die Relation-Methoden explizit anzugeben, auch deren Properties auslesen (Listing 3), und kommen damit zum gleichen Resultat:

Sub GetRelationsProps()
     Dim dbs As Database
     Dim rel As DAO.Relation
     Dim daoPrp As DAO.Property
     
     Set dbs = CurrentDb
     For Each rel In dbs.Relations
         Debug.Print rel.Name
         For Each daoPrp In rel.Properties
             Debug.Print , _
                 daoPrp.Name, _
                 daoPrp.Value
         Next daoPrp
     Next rel
End Sub

Listing 3: Durchlaufen der Properties-Auflistungen der Relations

tblAnredentblAdressen
     Name tblAnredentblAdressen
     Table tblAnreden
     ForeignTable tblAdressen
     Attributes 2 
     PartialReplica Falsch
tblLaendertblAdressen
     Name tblLaendertblAdressen
     Table tblLaender
     ForeignTable tblAdressen
     Attributes 33554434 
     PartialReplica Falsch
tblOrtetblAdressen
     Name tblOrtetblAdressen
     Table tblOrte
     ForeignTable tblAdressen
     Attributes 0 
    PartialReplica Falsch

Hier schleicht sich noch die Eigenschaft PartialReplica ein, die uns nicht weiter interessiert, weil sie nur für replizierte Datenbanken von Belang ist, die ohnehin seit geraumer Zeit nicht mehr direkt von Access unterstützt werden.

Nun haben wir zwar die Tabellen einer Beziehung ermittelt, wissen aber noch nicht, welche Felder genau aus ihnen miteinander verknüpft sind. Die Fields-Auflistung eines Relation-Objekts jedoch gibt uns darüber Auskunft. Sie kann auf analoge Weise durchlaufen werden, wie die Properties (siehe Listing 4). Für jedes Feld fld eines Relation-Objekts werden hier die Eigenschaften Name und ForeignName ausgelesen und mit den jeweiligen Tabellennamen kombiniert, so dass sich dieses Ergebnis zeigt:

Sub GetRelationsFields()
     Dim dbs As Database
     Dim rel As DAO.Relation
     Dim fld As DAO.Field
     
     Set dbs = CurrentDb
     For Each rel In dbs.Relations
         Debug.Print rel.Name
         For Each fld In rel.Fields
             Debug.Print , _
                 rel.Table & "." & _
                 fld.Name & " > " & _
                 rel.ForeignTable & _
                 "." & fld.ForeignName
         Next fld
     Next rel
End Sub

Listing 4: Durchlaufen der Fields-Auflistungen der Relations

tblAnredentblAdressen
   tblAnreden.ID > tblAdressen.IDAnrede
tblLaendertblAdressen
   tblLaender.ID > tblAdressen.IDLand
   tblLaender.Land > tblAdressen.Land
tblOrtetblAdressen
  tblOrte.ID > tblAdressen.IDOrt

Am zweiten Eintrag zur Länder-Beziehung wird deutlich, dass zwei Felder verknüpft wurden, die Fields-Auflistung also zwei Elemente enthält. Obwohl übrigens das Field-Objekt als DAO.Field ausgewiesen ist, kennt es nur genau diese zwei Eigenschaften Name und ForeignName. Alle anderen Methoden des Objekts schlagen hier fehl.

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