Access “Compact and Repair” programmatically

前端 未结 7 598
逝去的感伤
逝去的感伤 2020-12-03 22:28

Is it possible to \"compact and repair\" an Access database programmatically somehow (using ADOX, using OleDbConnection etc.)?

相关标签:
7条回答
  • 2020-12-03 22:35

    Add ref to: Microsoft ActiveX Data Objects 2.x Library Microsoft Jet and Replication Objects 2.x Library

    sDB = "c:\DB\myDb.mdb"
    sDBtmp = "c:\DB\tempMyDb.mdb"
    sPASSWORD = "password"
    
    Dim oApp As Access.Application
    Set oApp = New Access.Application
    Call oApp.DBEngine.CompactDatabase(sDB, sDBtmp, dbLangGeneral, , ";pwd=" & sPASSWORD)
    
    'wait for the app to finish
            DoEvents
    'remove the uncompressed original
            Kill sDB
    'rename the compressed file to the original to restore for other functions
            Name sDBtmp As sDB
    
    0 讨论(0)
  • 2020-12-03 22:37

    This solution works with the Access 2010 Database Engine:

    Required reference:

    Microsoft.Office.interop.access.dao
    

    Code:

    public void CompactDb(
        string sourceFilePath, string destFilePath, string password)
    {
        var dbEngine = new Microsoft.Office.Interop.Access.Dao.DBEngine();
    
        dbEngine.CompactDatabase(sourceFilePath, destFilePath,
            ";pwd=" + password, null, ";pwd=" + password);
    }
    

    (The sourceFilePath and destFilePath should not be the same!)

    CompactDatabase method parameters (from reflection):

    void CompactDatabase(
        string SrcName, string DstName,
        object DstLocale = Type.Missing,
        object Options = Type.Missing,
        object SrcLocale = Type.Missing);
    

    Make sure you run it under the same platform as the AccessDatabaseEngine (or Office) you installed (x86/x64).

    0 讨论(0)
  • 2020-12-03 22:41

    Sample code for VBScript.

    Dim objEngine
    Dim objProcess
    'Dim objDB
    Dim strDb1
    
    Dim strPath
    Dim strFile
    Dim strDAOversion
    Dim strApplicationName
    Dim strErr
    
    Dim strMsg
    Dim FSO
    
    strPath = "C:\Docs\"
    
    strFile = "Some.mdb"
    strDb1 = strPath & strFile
    
    Set FSO=CreateObject("Scripting.FileSystemObject")
    
    strDAOversion = "DAO.DBEngine.36"
    strApplicationName = "Some.mdb"
    
    strMsg = "About to perform a COMPACT on "
    strMsg = strMsg & chr(10) & chr(10)
    strmsg = strMsg & strApplicationName
    strMsg = strMsg & chr(10) & chr(10)
    strmsg = strmsg & "Please ask everyone to EXIT THE SYSTEM."
    strMsg = strmsg & chr(10) & chr(10)
    strmsg = strmsg & space(12) & "It is VITAL you do not exit windows until"
    strMsg = strMsg & chr(10)
    strMsg = strMsg & space(12) & "you receive the confirmation message."
    strMsg = strmsg & chr(10) & chr(10)
    strMsg = strMsg & space(6) & "Press OK to continue or Cancel to stop the process."
    
    
    If MsgBox(strMsg, 1, strApplicationName) = 1 Then
    
      Set objEngine = WScript.CreateObject(strDAOversion)
    
      Call CompactDB(FSO, objEngine, strDb1, "password")
    
      If strErr="True" Then
        strMsg = "Please correct the problem and try again."
        MsgBox strMsg, 1, strApplicationName
      Else
        strMsg = "Database compacting complete."
        MsgBox strMsg, 1, strApplicationName
      End If
    End If
    
    
    Function CompactDB(objFSO, objEngine, strDb, pwd)
    
    'Compact the database
    
    Dim strdbtemp
    Dim MsgText
    
    strdbtemp = Left(strDb, Len(strDb) - 3) & "ldb"
    
    If FSO.FileExists(strdbtemp) = True Then 'if ldb file exists, db is still open.
    MsgText = "You have not exited the file. Please close and try again."
    MsgBox MsgText, 1, strApplicationName
    strErr="True"
    Exit Function
    End If
    
    If FSO.FileExists(strDb1) = False Then
    MsgText = "Cannot locate the database at " & strDB
    MsgBox MsgText, 1, strApplicationName
    strErr="True"
    Exit Function
    End If
    
    strdbtemp = Left(strDb, Len(strDb) - 3) & "tmp"
    
    If pwd = "" Then
    objEngine.CompactDatabase strDb, strdbtemp
    Else
    objEngine.CompactDatabase strDb, strdbtemp, , , ";pwd=" & pwd
    End If
    
    If Err = 0 Then
    FSO.deletefile strDb
    FSO.copyfile strdbtemp,strDb
    FSO.deletefile strdbtemp
    Else
    MsgText = "Error during COMPACT process for " & strDB
    MsgBox MsgText, 1, strApplicationName
    strErr="True"
    End If
    
    End Function
    
    0 讨论(0)
  • 2020-12-03 22:50

    Here is the official MS link, any further comments would be redundant. DBEngine.CompactDatabase Method

    0 讨论(0)
  • 2020-12-03 22:54

    It is just four lines of code in c#.net

    First use a library:

    using JRO;
    

    You want to compact and repair test.mdb with the following code:

    string currentdirectory = System.IO.Directory.GetCurrentDirectory();
    string oldmdbfile = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + currentdirectory + "\\test.mdb;Jet OLEDB:Database Password='xyz'";
    string newmdbfile = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + currentdirectory + "\\test1.mdb;Jet OLEDB:Database Password='xyz'";
    string oldmdbfilepath = currentdirectory + "\\test.mdb";
    string newmdbfilepath = currentdirectory + "\\test1.mdb";
    
    JRO.JetEngine engine = new JetEngine();
    engine.CompactDatabase(oldmdbfile, newmdbfile);
    File.Delete(oldmdbfilepath);
    File.Move(newmdbfilepath, oldmdbfilepath);
    MessageBox.Show("Database compact and repaired successfully !",);
    

    Thus test.mdb will be compacted and repaired and a new file test1.mdb will be created. Then you just have to delete test.mdb and rename test1.mdb to test.mdb.

    0 讨论(0)
  • 2020-12-03 22:58

    I don't have enough rep to reply to a previous "answer", but I wanted to provide some info that might be helpful to someone else in regards to the OP's question.

    I have been using the JRO method for years to compact/repair my Access 2000 databases from VB.net. Every once in a blue moon, I have a client that has managed to corrupt a database (usually when connected to the database over a network and they suffer an unexpected network interruption). JRO (in my experience) works fine, as long as the database IS NOT CORRUPTED. I never could figure out why the database COULD be repaired if I used the Access application to do it, but when using MY application (which uses JRO), the compact/repair would always fail (database is in an unrecognized format).

    So, after coming across this thread just an hour ago, I dropped a reference to DAO into my app and tried out its ability to repair a corrupted database as I just today had a client corrupt their database (third time its happened in about 8 years). Guess what, DAO was able to repair the database when JRO failed!

    OK, so that is my experience with JRO vs. DAO. Hope it helps. Here is a piece of sample code for using CompactDatabase from DAO:

    Dim dbCorrupt As String = "c:\CorruptedDB.mdb"
    Dim dbRepaired As String = Path.Combine(Path.GetDirectoryName(dbPath), Path.GetFileNameWithoutExtension(dbPath) & "_Repaired.mdb")
    
    Dim dao As New dao.DBEngine
    dao.CompactDatabase(dbCorrupt, dbRepaired)
    
    0 讨论(0)
提交回复
热议问题