Button Home/Top/Zurück


Verknüpfungen




Um eine Access-Datenbank echt mehrbenutzerfähig zu machen, wird die Aufteilung der Datenbank in Fornt- und Backend empfohlen.
Dabei wird die Datenbank in zwei Datenbanken aufgeteilt, wobei in der Regel alle Tabellen im Backend und alle Formulare, Berichte, Abfragen und Module im Frontend sind.
Die Backend-Datenbank wird dann auf einem Netzwerk-Verzeichnis deponiert während die Frontend-Datenbank auf den Client-Rechnern verbleibt.
Die Verbindung zwischen Front- und Backend erfolgt durch das Verknüpfen der Backend-Tabellen mit der Frontend-Datenbank.

Bei der Verknüpfung werden im Frontend u.a. Angaben zum Ort der Backend-Datenbank gespeichert. Dies mit vollständiger Pfadangabe.
Für den Fall, daß die Backend-Datenbank auf dem Netzwerk verschoben wird o.ä. unangenehme Dinge passieren, stimmen die Informationen über die verknüpften Tabellen im Frontend nicht mehr.

Nun hat man die Möglichkeit, den Benutzern eine manuelle Aktualisierung der Verknüpfungen vornehmen zu lassen oder diese halbautomatisiert durchzuführen.

Bei der manuellen Aktualisierung sind folgende Schritte durchzuführen:
  1. Löschen aller verknüpften Tabellen aus Frontend-Datenbank.
    Die Tabellen sind mit folgendem Symbol gekennzeichnet Access-Verknüpfungs-Icon
  2. Öffnen der aktuellen Backend-Datenbank über Datei - Externe Daten - Tabellen verknüpfen
  3. Auswählen der korrekten Tabelle und Verknüpfung durchführen.


Bei der halbautomatischen Aktualisierung lässt man dem Benutzer die aktuelle Backend-Datenbak auswählen (suchen) und aktualisiert die Verknüpfungen via VBA.

Das erste Problem, auf daß man stößt ist die Frage, woran man eigentlich erkennt, daß die Verknüpfungen nicht mehr aktuell sind.
Im einfachsten Fall daran, daß sich ein Benutzer meldet, weil er ständig die Fehlermeldung
Datei '..../Backend.mdb' nicht gefunden oder den Laufzeitfehler 63725 angezeigt bekommt.

Das ist natürlich unter unserer Würde, es muss also einen besseren Weg geben.
Man kann z.B. beim Öffnen der Datenbank bzw. beim Öffnen des ersten Dialoges (diesen kann man im unter Extras - Start festlegen) alle Verknüpfungen prüfen.

Dazu folgendes Code-Beispiel:
Public Function PruefeVerknuepfung(sDBListe As String) As Boolean
'
' Prüft, ob die Verknüpfung in der aktuellen DB noch
' gültig sind. D.h. es wird geprüft, ob die Datenbank
' noch an dem selben Ort liegt.
'
' Alle Datenbanken die nicht gefunden wurden, werden in der
' Rückgabevariablen sDBListe gespeichert.
'
' IN:   sDBListe    Rückgabe einer Liste aller Datenbanken,
'                   die nicht mehr aktuell sind.
'
' OUT:  True        wenn Datenbank noch vorhanden ist
'       False       sonst
'
Dim cDB As Database         ' Beim Zugriff auf TableDefs braucht
                            ' Access ein Database-Objekt :(
Dim TabDef As TableDef      ' Tabellendefinition
Dim i As Integer            ' Zähler
Dim bRet As Boolean         ' Returnwert
Dim sDBName As String       ' Name des Datenbank, aus der Tabellen
                            ' verknüpft wurden.
Dim Pos1 As Integer         ' Position des ersten "="
    '
    ' Default-Returnwert setzen (optimistisch)
    '
    bRet = True
    '
    sDBListe = ""
    '
    ' Database-Objekt setzen (warum kann man eigentlich
    ' auf Tabellendefinitionen nicht über CurrentDb zugreifen)
    '
    Set cDB = CurrentDb
    '
    ' Schleife über alle Tabellendefinitionen der aktuellen
    ' Datenbank
    '
    For i = 0 To cDB.TableDefs.Count - 1
        '
        ' Tabellendefinition setzen
        '
        Set TabDef = cDB.TableDefs(i)
        '
        ' Prüfen, ob die Tabelle verknüpft ist.
        ' In diesem Fall ist die Eigenschaft Connect nicht leer
        '
        If TabDef.Connect <> "" Then
            '
            ' Bei verknüpften Tabellen steht in .Connect so etwas drin
            '
            ' DATABASE=C:\Temp\Beispiel.mdb
            '
            ' Daraus brauchen wir alles was hinter dem "=" steht.
            '
            Pos1 = InStr(TabDef.Connect, "=")
            sDBName = Right$(TabDef.Connect, Len(TabDef.Connect) - Pos1)
            '
            ' Prüfen, ob es die Datenbank noch gibt.
            '
            If Dir$(sDBName) = "" Then
                '
                ' Datenbank nicht gefunden, Returnwert auf FALSE setzen
                '
                bRet = False
                '
                ' Name der Datenbank in die Liste der nichtmehr aktuellen
                ' Datenbanken aufnehmen
                '
                If InStr(sDBListe, sDBName) = 0 Then
                    sDBListe = sDBListe & sDBName & ";"
                End If
                '
                ' Hier wird mit Absicht nicht die Funktion verlassen, für
                ' den Fall das Tabellen aus mehreren Datenbanken
                ' verknüpft sind, werden alle Verknüpfungen geprüft.
                '
            End If
        End If
 
    Next i
    '
    ' Das letzt Semikolon aus der Liste der nichtmehr aktuellen
    ' Datenbanken entfernen
    '
    If sDBListe <> "" Then
        sDBListe = Left(sDBListe, Len(sDBListe) - 1)
    End If
    '
    PruefeVerknuepfung = bRet
 
End Function

Diese Funktion ermittelt aus den Tabellendefinition der aktuellen Datenbank (Frontend-Datenbank) alle verknüpften Tabellen. Diese werden daran erkannt, daß in der Eigenschaft Connect etwas eingetragen ist. Im Fall von verknüpften Access-Tabellen ist steht dort DATABASE= gefolgt vom Namen der Access-Datenbank, aus dem die Tabelle stammt, z.B. DATABASE=C:\Temp\Beispiel.mdb. Eine Verknüpfung ist aktuell, wenn der Zugriff auf diese Datenbank möglich ist.

Hinweis:
In dieser Funktion wird nicht geprüft, ob die verknüpfte Tabelle noch in der entsprechenden Datenbank vorhanden ist.
Diese Funktion ist nicht für ODBC-Verknüpfungen getestet.


Nachdem wir nun festgestellt haben, daß einige Verknüpfungen nicht mehr aktuell sind, geht es an die Aktualisierung.
Die vorhergehende Funktion liefert uns praktischer Weise einen String zurück, indem die Namen aller Datenbanken enthalten sind, die vom Frontend aus nicht mehr zu sehen sind.
Im einfachsten Falle enthält dieser Sting den Namen einer Datenbank (der Backend-Datenbank).

Die folgende Funktion aktualisiert die Verknüpfungen für eine Datenbank. Werden von der Funktion PruefeVerknuepfung mehrere Datenbanken geliefert, muss vorher eine Stringzerlegung implementiert werden.
Public Function NeuVerknuepfen(sOldDBName As String) As Boolean
'
' Aktualisieren aller Tabellen Verknüpfungen zu einer anderen
' Datenbank.
'
' IN:   sOldDBName      Name der alten Verknüpfung
'
' OUT:  True            wenn die Aktualisierung erfolgreich war
'       False           sonst
'
' Anhängigkeiten
'
' Module:
'   modMSStringFunctions
'   modFileDialogs
'
Dim sNewDBName As String    ' Name der neuen Verknüpfung
Dim sOpenTitel As String    ' Titel des OpenFile-Dialoges
Dim sStartVerz As String    ' Verzeichnis, in dem der OpenFile-Dialog
                            ' die Suche startet.
Dim bRet As Boolean         ' Returnwert
 
Dim cDB As Database         ' Beim Zugriff auf TableDefs braucht
                            ' Access ein Database-Objekt :(
Dim TabDef As TableDef      ' Tabellendefinition
Dim i As Integer            ' Zähler
    '
    ' Default-Returnwert (pessimistisch)
    '
    bRet = False
    '
    ' Prüfen, ob eine alte Verknüpfung angegeben ist
    '
    If Trim(sOldDBName) = "" Then
        NeuVerknuepfen = bRet
        Exit Function
    End If
    '
    ' Als Titel des OpenFile-Dialoges wird der Name der
    ' alten Datenbank ausgegeben
    '
    sOpenTitel = "Datenbank " & GetFilename(sOldDBName) & " suchen"
    '
    ' Startverzeichnis ist das Verzeichnis in dem die alte
    ' Datenbank abgelegt war.
    '
    sStartVerz = GetPathname(sOldDBName)
    '
    ' Den Benutzer. über den OpenFile-Dialog, die neue Verknüpfung
    ' (Datenbank) suchen lassen
    '
    sNewDBName = FileDialog(True, sOpenTitel, _
    "MS-Access Datenbank (*.mdb)" & Chr(0) & "*.mdb" & Chr(0) & _
    "Alle Dateien (*.*)" & Chr(0) & "*.*", "*.tmp", sStartVerz)
    '
    ' Wenn der Benutzer keine Datenbank ausgewählt hat, dann
    ' wird hier abgebrochen.
    '
    If sNewDBName = "" Then
        NeuVerknuepfen = bRet
        Exit Function
    End If
    '
    ' Das ärgert mich immer wieder !
    ' Warum kann man nicht die TableDef-Auflistung der
    ' CurrentDb durchlaufen ?!?
    '
    Set cDB = CurrentDb
    For i = 0 To cDB.TableDefs.Count - 1
        '
        ' Schleife über alle Tabellendefinition
        ' der aktuellen Datenbank
        '
        Set TabDef = cDB.TableDefs(i)
        '
        ' Wenn in einer verknüpften Tabelle der Name der
        ' alten Datenbank vorkommt, dann...
        '
        If InStr(TabDef.Connect, sOldDBName) Then
            '
            ' ...diese Verknüpfung aktualisieren
            '
            TabDef.Connect = ";DATABASE=" & sNewDBName
            TabDef.RefreshLink
 
        End If
 
    Next i
 
    bRet = True
    NeuVerknuepfen = bRet
 
End Function

In dieser Funktion wird über den OpenFile-Dialog (gibt es bei Reinhard Kraasch) vom Benutzer der Name (mit Pfad) der Backend-Datenbank abgefragt. Darum ist dies auch eine halbautomatische Variante. Wenn der Benutzer die Backend-Datenbank ausgewählt hat, werden in den Tabellendefinitionen der Frontend-Datenbank alle Tabellen herausgesucht, in denen in der Eigenschaft Connect der alte Datenbankname enthalten ist. Hier wird dann der neuen Datenbankname eingetragen und die Verknüpfung aktualisiert.
Hinweis:
Wenn man bei der Zuweisung an die Connect-Eigenschaft einen Fehler macht, erscheint der Laufzeitfehler 3170 / Installierbares ISAM nicht gefunden.
In diesem Fall die Ruhe bewahren, wahrscheinlich habt Ihr euch nur vertippt. Die genaue Syntax könnt Ihr oben nachlesen.

Zum Abschluss noch ein weiteres Modul, welches alle Verknüpfungen in der Frontend-Datenbank aktualisiert und alle neuen Tabellen der Backend-Datenbank als neue Verknüpfungen einbindet.
Sub TabellenEinbinden(AccessDatenbank$)
 
Dim AktDB As Database       ' aktuelle Datenbank
Dim AktTab As TableDef      '   eine Tabelle der akt. Datenbank
Dim AktCnt                  '   Zähler über alle Tabellen der akt. Datenbank
Dim AktSet As Boolean       '   Kennzeichen, ob Tabelle in akt. Datenbank aktualisiert wurde
Dim ExtDB As Database       ' externe Datenbank
Dim ExtTab As TableDef      '   eine Tabelle der ext. Datenbank
Dim ExtCnt                  '   Zähler über alle Tabellen der ext. Datenbank
 
Dim i
Dim TMAnz As Integer
 
On Error GoTo Err_TabellenEinbinden
    '
    ' Prüfen ob überhaupt eine Access-DB angegeben ist
    '
    If Trim$(AccessDatenbank$) = "" Then GoTo ExitTabellenEinbinden
    '
    ' Verbindung zur aktuellen Datenbank öffnen (in der dieses Modul steckt)
    '
    Set AktDB = CurrentDb
    AktDB.TableDefs.Refresh
    '
    'Verbindung zur externen Datenbank öffnen
    '
    Set ExtDB = OpenDatabase(AccessDatenbank$)
    '
    ' Schleife über alle Tabellen der externen Datenbank
    '
    For ExtCnt = 0 To ExtDB.TableDefs.Count - 1
        '
        ' nächste Tabelle der ext. Datenbank auswählen
        '
        Set ExtTab = ExtDB.TableDefs(ExtCnt)
        '
        ' Systemtabellen nicht einbinden
        '
        If InStr(ExtTab.Name, "MSys") > 0 Then GoTo NaechsteExterneTabelle
        '
        ' Kennz. ext. Tabelle in akt. Datenbank gefunden zurücksetzen
        '
        AktSet = False
        '
        ' Schleife über alle Tabellen der aktuellen Datenbank
        '
        For AktCnt = 0 To AktDB.TableDefs.Count - 1
            '
            ' nächste Tabelle der akt. Datenbank auswählen
            '
            Set AktTab = AktDB.TableDefs(AktCnt)
            '
            ' Tabellennamen vergleichen
            '
            If ExtTab.Name = AktTab.Name Then
                '
                ' ext. Tabelle in akt. Datenbank gefunden
                '
                AktSet = True
                '
                ' Prüfen ob die Tabelle der akt. Datenbank eingebunden ist.
                ' Wenn nicht, kann diese nicht neu eingebunden werden
                '
                If AktTab.Connect <> "" Then
                    '
                    ' Einbindung der Tabelle der akt. Datenbank aktualisieren
                    '
                    AktTab.Connect = ";DATABASE=" & AccessDatenbank$
                    AktTab.RefreshLink
 
                End If
                '
                ' Tabelle gefunden, Schleife kann hier verlassen werden
                '
                GoTo AktTabelleGefunden
            End If
 
        Next AktCnt
 
AktTabelleGefunden:
        '
        ' Prüfen, ob ext. Tabelle in akt. Datenbank nicht gefunden wurde
        '
        If Not AktSet Then
            '
            ' ext. Tabelle als neue Einbindung der akt. Datenbank anlegen
            '
            Set AktTab = AktDB.CreateTableDef(ExtTab.Name)
            AktTab.SourceTableName = ExtTab.Name
            AktTab.Connect = ";DATABASE=" & AccessDatenbank$
            AktDB.TableDefs.Append AktTab
            AktDB.TableDefs.Refresh
 
        End If
NaechsteExterneTabelle:
    Next ExtCnt
 
ExitTabellenEinbinden:
 
    ' Datenbanken schließen
    ExtDB.Close
    AktDB.Close
 
 
    Exit Sub
 
Err_TabellenEinbinden:
    MsgBox ExtTab.Name + " / " + AktTab.Name + " // " + Err.Description
    Resume ExitTabellenEinbinden
 
End Sub

Die, in diesen Modulen verwendeten Funktionen zu Ermittlung von Dateinamen und Pfadangaben aus einem Filenamen gibt es hier.

Die Module gibt es, wie immer, als Textfiles zum downloaden.
Modul Icon Verknüpfungen Prüfen und neu Einbinden als Textfile zum Downloaden
Modul Icon Alle Tabellen einbinden als Textfile zum Downloaden

Button Home/Top/Zurück