it-swarm.com.de

So komprimieren Sie die aktuelle MS Access-Datenbank über die VBA-Funktion

Ich möchte in der Lage sein, den Prozess "Kompaktieren und Reparieren" in einem VBA-Modul in der Datenbank auszuführen.

Ich habe einen Batch-Prozess, den ich gelegentlich ausführe. Er löscht einige alte Tabellen, importiert sie erneut aus anderen Datenbanken, benennt einige Felder um, führt einige Aktualisierungen durch und nimmt einige kleinere Änderungen vor. Der Prozess ist keine Raketenwissenschaft, aber es gibt mehrere Schritte, so dass er wirklich automatisiert werden muss.

Das Problem ist, dass einige der Schritte (die UPDATEs) vorübergehend die Größe der Datenbank erhöhen, was zu Problemen bei nachfolgenden Importen führen kann.

Wenn ich den Vorgang manuell durchführe (einschließlich Komprimieren), funktioniert alles einwandfrei und ich erhalte eine 800-MByte-Datenbank. Wenn ich mein automatisiertes VBA-Skript verwende (ohne es zu komprimieren), stürzt es zur Hälfte ab, wenn die Datenbank das 2-GByte-Limit überschreitet.

Ich habe mehrere Themen zu diesem Thema gefunden, aber sie sind alle drei oder vier Jahre alt (oder älter) und die Methoden, die sie beschreiben, scheinen nicht mehr zu funktionieren.

Gibt es Lösungen, die mit Office 365 (Version 1720) funktionieren?

Durch die automatische Komprimierung wird die Datenbank beim Schließen komprimiert. Die Komprimierung der Datenbank kann NICHT zwischen den Schritten hinzugefügt werden.

Ich habe das versucht:

Public Sub CompactDb2()
  Dim control As Office.CommandBarControl
  Set control = CommandBars.FindControl(Id:=2071)
 control.accDoDefaultAction
End Sub

Und das:

Public Sub CompactDb1()
    CommandBars("Menu Bar").Controls("Tools").Controls("Database utilities"). _
    Controls("Compact and repair database...").accDoDefaultAction
End Sub

Und das....

Public Sub CompactDb3()
    Application.SetOption "Auto compact", True
End Sub

Unter anderem

3
ConanTheGerbil

Das ist einfach nicht möglich. Zum Komprimieren und Reparieren einer Datenbank muss die Datenbank geschlossen werden. Daher können Sie eine Datenbank nicht zwischen Schritten in einem Unterabschnitt oder einer Prozedur komprimieren und reparieren, da die Datenbank beim Ausführen der Prozedur geöffnet ist.

Möglicherweise stellen Sie fest, dass die Schaltfläche Kompaktieren und Reparieren in der Multifunktionsleiste eine exklusive Sperre erfordert, die Datenbank schließt, komprimiert und repariert und dann erneut öffnet.

Mein Rat: Führen Sie den Prozess entweder aus einer externen Datenbank, einer VBScript-Datei oder PowerShell aus. Führen Sie den ersten Teil Ihres Stapels aus, schließen Sie die Datei, komprimieren und reparieren Sie sie, öffnen Sie sie erneut und führen Sie den zweiten Teil aus

Beispielcode

Dim fileLocation As String
DBEngine.CompactDatabase fileLocation, fileLocation & "_1"
Kill fileLocation
Name fileLocation & "_1" As fileLocation

Möglicherweise stellen Sie auch fest, dass die Schaltfläche Zugriff kompakt und reparieren etwas Ähnliches bewirkt. Wenn Sie compact & Repair ausführen, werden die Daten in eine Datenbank mit dem Namen Database.accdb in Ihrem aktuellen Ordner verschoben (der Name kann je nach vorhandenem Namen/Datenbanktyp variieren). Anschließend wird Ihre aktuelle Datenbank gelöscht und anschließend benennt den neuen um.


Nun, aber nichts ist unmöglich, oder?

Nun, einige Dinge sind es, aber dies ist keines davon, wenn Sie bereit sind, seltsame Tricks zu machen. Wie ich gerade sagte, ist das Hauptproblem, dass die aktuelle Datenbank geschlossen werden muss. Die Problemumgehung führt also Folgendes aus:

  1. Erstellen Sie programmgesteuert eine VBScript-Datei
  2. Fügen Sie dieser Datei Code hinzu, damit wir unsere Datenbank komprimieren und reparieren können, ohne sie öffnen zu müssen
  3. Öffnen Sie diese Datei und führen Sie sie asynchron aus
  4. Schließen Sie unsere Datenbank, bevor die Kompakt- und Reparaturarbeiten durchgeführt werden
  5. Komprimieren und reparieren Sie die Datenbank (erstellen Sie eine Kopie), löschen Sie die alte und benennen Sie die Kopie um
  6. Öffnen Sie unsere Datenbank erneut und setzen Sie den Stapel fort
  7. Löschen Sie die neu erstellte Datei

Zum Glück hatte ich etwas Zeit, so dass ich die folgende Lösung fand:

Public Sub CompactRepairViaExternalScript()
    Dim vbscrPath As String
    vbscrPath = CurrentProject.Path & "\CRHelper.vbs"
    If Dir(CurrentProject.Path & "\CRHelper.vbs") <> "" Then
        Kill CurrentProject.Path & "\CRHelper.vbs"
    End If
    Dim vbStr As String
    vbStr = "dbName = """ & CurrentProject.FullName & """" & vbCrLf & _
    "resumeFunction = ""ResumeBatch""" & vbCrLf & _
    "Set app = CreateObject(""Access.Application"")" & vbCrLf & _
    "Set dbe = app.DBEngine" & vbCrLf & _
    "Set objFSO = CreateObject(""Scripting.FileSystemObject"")" & vbCrLf & _
    "On Error Resume Next" & vbCrLf & _
    "Do" & vbCrLf & _
    "If Err.Number <> 0 Then Err.Clear" & vbCrLf & _
    "WScript.Sleep 500" & vbCrLf & _
    "dbe.CompactDatabase dbName, dbName & ""_1""" & vbCrLf & _
    "errCount = errCount + 1" & vbCrLf & _
    "Loop While err.Number <> 0 And errCount < 100" & vbCrLf & _
    "If errCount < 100 Then" & vbCrLf & _
    "objFSO.DeleteFile dbName" & vbCrLf & _
    "objFSO.MoveFile dbName & ""_1"", dbName" & vbCrLf & _
    "app.OpenCurrentDatabase dbName" & vbCrLf & _
    "app.UserControl = True" & vbCrLf & _
    "app.Run resumeFunction" & vbCrLf & _
    "End If" & vbCrLf & _
    "objFSO.DeleteFile Wscript.ScriptFullName" & vbCrLf
    Dim fileHandle As Long
    fileHandle = FreeFile
    Open vbscrPath For Output As #fileHandle
    Print #fileHandle, vbStr
    Close #fileHandle
    Dim wsh As Object
    Set wsh = CreateObject("WScript.Shell")
    wsh.Run """" & vbscrPath & """"
    Set wsh = Nothing
    Application.Quit
End Sub

Dies führt alle oben beschriebenen Schritte aus und setzt den Stapel fort, indem die Funktion ResumeBatch in der Datenbank aufgerufen wird, die diese Funktion aufgerufen hat (ohne Parameter). Beachten Sie, dass Dinge wie Click-to-Run-Schutz und Antivirus/Richtlinien, die VBScript-Dateien nicht mögen, diesen Ansatz ruinieren können.

4
Erik A

Hier ist der VBA-Code, den ich ausprobiert und bearbeitet habe und der von Excel ausgeführt wird.

Sub CompactAndRepairAccessDB()

    Dim Acc As Object
    Set Acc = CreateObject("access.application")

    Dim dbPath As String, dbPathX As String
    dbPath = Application.ThisWorkbook.Path & "\" & "YourDatabaseNameHere.accdb"
    dbPathX = Application.ThisWorkbook.Path & "\" & "tmp.accdb"

    Acc.DBEngine.CompactDatabase dbPath, dbPathX
    Acc.Quit
    Set Acc = Nothing
    Kill dbPath
    Name dbPathX As dbPath

End Sub

Habe die Lösung in diesem Link gefunden und ein wenig modifiziert.

http://www.vbaexpress.com/forum/showthread.php?9262-Solved-VBA-Compact-and-Repair

0
Sacid Karacuha