Einzelnen Beitrag anzeigen
Alt 06.02.2005, 12:40   #5
Sascha Trowitzsch
MOF Guru
MOF Guru
Standard

Das Thema "Backup erstellen per VBA" wurde in letzter Zeit recht häufig hier im Forum diskutiert.
Was mich dabei etwas wundert ist, dass es dabei immer nur um die technische Umsetzung des Datei-Kopierens geht. (Dazu findet man inzwischen haufenweise Code.)
Die Frage, ob das überhaupt sinnvoll oder erlaubt ist wird praktisch nie behandelt.

Deshalb muss ich doch mal was grundsätzliches dazu sagen:
Das Kopieren einer offenen Datenbank ist immer mit dem Risiko verbunden, dass dabei was kaputt geht.
In der Regel werden das dann Datensätze sein. Da aber auch das VBA-Projekt (Module, Formularcode) in Tabellen gespeichert wird (z.B. MSysAccessObjects), kann auch VBA-Code beschädigt werden.
Wohlgemerkt: In der angelegten Kopie natürlich. Wenn dieses Backup später mal wiederhergestellt wird, dann kann es eben Fehler haben.

Um dieses Risiko zu minimieren hier ein paar Tipps...
Grundsätzlich sollte man nur das verknüpfte Backend kopieren, nicht das Frontend, da dieses nun mal offen ist und Access durch nichts zu bewegen ist, irgendwelche temporären Vorgänge vor dem Schließen auszuführen. (Beispielsweise werden gelöschte Datensätze oder Objekte bis zum Schließen von Access in der Zwischenablage gehalten, um ein UNDO zu ermöglichen. Außerdem bleiben diverse interne Zustands-Flags und Properties gesetzt, und werden erst beim endgültigen Schließen physisch in die MDB geschrieben.)
- Alle Objekte in der DB sollten zunächst geschlossen sein.
Das kann z.B. durch folgenden Code erwirkt werden:
Code:

Sub CloseAllObjects()
    Dim oObj As Object, sTmp As String
 
    On Error Resume Next
 
    'Alle Formulare schließen
    For Each oObj In Forms
        DoCmd.Close acForm, oObj.Name, acSaveYes
    Next oObj
 
    'Alle Berichte schließen
    For Each oObj In Reports
        DoCmd.Close acReport, oObj.Name, acSaveYes
    Next oObj
 
    'Evtl. offene Tabellen oder Abfragen schließen
    Do
        sTmp = vbNullString
        sTmp = Screen.ActiveDatasheet.Name
        DoCmd.Close acTable, sTmp
        DoCmd.Close acQuery, sTmp
        DoEvents
    Loop Until Len(sTmp) = 0
 
    'Evtl. offene Recordsets schließen
    For Each oObj In DBEngine(0)(0).Recordsets
        oObj.Close
    Next oObj
 
    Set oObj = Nothing
 
End Sub
- Dann sollte sichergestellt werden, dass alle Schreibvorgänge der Datenbank-Engine beendet wurden; z.B. so:
Code:

Sub FlushAllData()
 
    '"Nulltransaktion": Evtl. ausstehende Schreibvorgänge erzwingen
    DBEngine.BeginTrans
    DBEngine.CommitTrans dbForceOSFlush
 
    'Datenbank-Engine "resetten":
    DBEngine.Idle
 
End Sub
- Auf das Backend sollte zum Zeitpunkt des Kopierens niemand mehr zugreifen. D.h., es darf keine .LDB-Datei zur Backend-MDB existieren und außerdem sollte Exklusiv-Zugriff bestehen:
Code:

Function IsBackendReady(sBackendFile As String) As Boolean
    Dim sLDB
 
    If Len(Dir(sBackendFile)) = 0 Then Exit Function
 
    'Existenz des zugehörigen LDB-Files ermitteln
    sLDB = Left(sBackendFile, InStrRev(sBackendFile, ".") - 1) & ".LDB"
    If Len(Dir(sLDB)) = 0 Then IsBackendReady = True
 
    On Error Resume Next
    'Zur Sicherheit Möglichkeit des Vollzugriff auf Backend ermitteln
    Open sBackendFile For Binary Access Read Lock Read Write As #1
    If Err.Number <> 0 Then IsBackendReady = False
    Close #1
 
End Function
Der Backup-Vorgang sähe dann schlussendlich so aus:
Code:

Function MakeBackup(sBackendFile As String) As Boolean
 
    CloseAllObjects
    FlushAllData
    If IsBackendReady(sBackendFile) Then
        'Call CopyBackendToAnyWhere
        '...
        MakeBackup = True
    Else
        MsgBox "Backend kann momentan nicht ausgeführt werden." & vbCrLf & _
               "Versuchen Sie es zu einem späteren Zeitpunkt."
    End If
 
End Function
...An die Stelle von "Call CopyBackendToAnyWhere" kann man dann die üblichen Codes zum Kopieren per API oder FileSystemObject setzen.

Und trotzdem: Sage keiner hinterher, er sei nicht gewarnt worden!

Ciao, Sascha

__________________

Microsoft Access MVP
O2k bis O2010, VB6, VS2008, Delphi7, ...
Bitte keine ungefragten E-Mails. Probleme werden hier gelöst.
Bitte beachten: Grundlegendes zum Access-Forum

Knowhow auf Access-im-Unternehmen | Das Access 2007 Praxisbuch für Entwickler | www.mossTOOLs.de
Sascha Trowitzsch ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten