Access_Query
Access_Query

Reputation: 99

Find all Access databases, and Compact and Repair

I'm trying to find all Access databases in a directory and Compact and Repair each without opening Access each time. I found the following article explaining how to find them and write to a file: Batch file to find all Access Databases, but ideally I'd like to just find them and compact without writing to a file.

I have searched how to call the /compact command line functionality, but I don't know how to do it on the databases I find. Can a .bat file be written to do this? Something like:

@echo off

"C:\Program Files\Microsoft Office\Office14\MSACCESS.EXE" "C:\Databases\ /s" *.accdb /compact

Any help with the syntax is very much appreciated.

Upvotes: 3

Views: 6099

Answers (1)

Parfait
Parfait

Reputation: 107747

Consider using Access' dedicated CompactRepair method which you can run in VBA (inside an Access database or outside like in an Excel macro). The thing to note is Compact & Repair actually creates a copy of existing database and replaces it with original, so some file handling is needed.

VBA (inside MSAccess.exe)

Sub RunCompactDBs()
    Dim path As String
    Dim accfile As Variant

    path = "C:\Databases\"
    accfile = Dir(path & "*.accdb", vbDirectory)

    Do While Len(accfile) > 0
        bkfile = Replace(accfile, ".accdb", "_bk.accdb")

        ' CREATE COMPACTED BACKUP
        Application.CompactRepair path & accfile, path & bkfile, False      
        ' COPY TO ORIGINAL PATH
        FileCopy path & bkfile, path & accfile     
        ' DESTROY COMPACTED BACKUP
        Kill path & bkfile                    

        accfile = Dir
    Loop

    Set accApp = Nothing
End Sub

VBA (outside MSAccess.exe)

Sub RunCompactDBs()
    Dim path As String
    Dim accfile As Variant
    Dim accApp As Object

    Set accApp = CreateObject("Access.Application")

    path = "C:\Databases\"
    accfile = Dir(path & "*.accdb", vbDirectory)

    Do While Len(accfile) > 0
        bkfile = Replace(accfile, ".accdb", "_bk.accdb")

        accApp.CompactRepair path & accfile, path & bkfile, False      

        FileCopy path & bkfile, path & accfile                           
        Kill path & bkfile

        accfile = Dir
    Loop

    Set accApp = Nothing        
End Sub

And there's no reason to stick with VBA. Any language that can make a COM interface to the Access object library can run the compact and repair procedure like open-source languages:

Python

import os, glob, shutil
import win32com.client

# LAUNCH ACCESS APP
oApp = win32com.client.Dispatch("Access.Application")

for file in glob.glob("C:\\Databases\\*.accdb"):       
    bkfile = file.replace(".accdb", "_bk.accdb")

    oApp.CompactRepair(file, bkfile, False)

    shutil.copyfile(bkfile, file)
    os.remove(bkfile)

oApp = None

R

library(RDCOMClient)

# LAUNCH ACCESS APP
oApp = COMCreate("Access.Application")

accfiles <- list.files(path="C:\\Databases\\", pattern="\\.accdb", full.names=TRUE)

for (file in accfiles){      
  bkfile = sub(".accdb", "_bk.accdb", file)

  oApp$CompactRepair(file, bkfile, FALSE)

  file.copy(bkfile, file, overwrite = TRUE)
  file.remove(bkfile)      
}

oApp <- NULL
gc()

PHP

# LAUNCH ACCESS APP
$acc = new COM("Access.Application", NULL, CP_UTF8) or Die ("Did not instantiate Access");

foreach (glob("C:\\Databases\\*.accdb") as $file) {            
    $bkfile = str_replace(".accdb", "_bk.accdb", $file);

    $acc->Application->CompactRepair($file, $bkfile, false);

    copy($bkfile, $file);
    unlink($bkfile);    
}

$acc = NULL;
unset($acc);

Upvotes: 9

Related Questions