locked
compact and repair RRS feed

  • Question

  • hi.i want to compact and repair the access database with vba.is it possible?and how?

    regards.


    microsoft

    Saturday, January 14, 2017 6:15 AM

Answers

  • I use this VBA function.

    Public Function pjsCompactDatabase(dbDatabase As DAO.Database) As Boolean
        Dim strDBFileName       As String
        Dim strDBFileType       As String
        Dim strDBFileNameTemp   As String
        
        'Get current database name and create name to compact into
        strDBFileName = dbDatabase.Name
        strDBFileType = pjsGetFileTypeFromFullFileName(strDBFileName)
        strDBFileNameTemp = strDBFileName & ".pjsCompactNewData." & strDBFileType
        
        'Disable name autocorrect before compacting so the new db has the desired settings.
        Call DisableNameAutoCorrect(dbDatabase)
        
        'Close the existing database and flush all writes to disk
        dbDatabase.Close
        Set dbDatabase = Nothing
        DBEngine.Idle dbRefreshCache
        DoEvents
        
        'Compact the database
        DBEngine.CompactDatabase srcName:=strDBFileName, dstName:=strDBFileNameTemp
        DBEngine.Idle dbRefreshCache
        DoEvents
        
        Kill strDBFileName
        Name strDBFileNameTemp As strDBFileName
        
        'Indicate success
        pjsCompactDatabase = True
    End Function


    Paul

    • Marked as answer by majzad Sunday, January 15, 2017 6:36 AM
    Saturday, January 14, 2017 2:07 PM
  • But as I said, Paul's code can't be used on the active database while your customer is using the database. Paul's code also can't be used while there are any active connection to the back-end, so you need to close all the open objects within the FE prior to running the code.

    Daniel Pineault, 2010-2016 Microsoft MVP
    Professional Support: http://www.cardaconsultants.com
    MS Access Tips and Code Samples: http://www.devhut.net



    Sunday, January 15, 2017 1:16 PM

All replies

  • Hi

    I found this on the forum:

    "For MS Access 2010, the only way I have found to compact a database via a button is by executing the following code:-

    SendKeys "%F{TAB}{TAB}{ENTER}"

    Posted by Steve"

    But there is more information and ideas here: Click and read :-)


    Best // Peter Forss Stockholm and Sigtuna GMT +1.00


    Saturday, January 14, 2017 8:40 AM
  • I use this VBA function.

    Public Function pjsCompactDatabase(dbDatabase As DAO.Database) As Boolean
        Dim strDBFileName       As String
        Dim strDBFileType       As String
        Dim strDBFileNameTemp   As String
        
        'Get current database name and create name to compact into
        strDBFileName = dbDatabase.Name
        strDBFileType = pjsGetFileTypeFromFullFileName(strDBFileName)
        strDBFileNameTemp = strDBFileName & ".pjsCompactNewData." & strDBFileType
        
        'Disable name autocorrect before compacting so the new db has the desired settings.
        Call DisableNameAutoCorrect(dbDatabase)
        
        'Close the existing database and flush all writes to disk
        dbDatabase.Close
        Set dbDatabase = Nothing
        DBEngine.Idle dbRefreshCache
        DoEvents
        
        'Compact the database
        DBEngine.CompactDatabase srcName:=strDBFileName, dstName:=strDBFileNameTemp
        DBEngine.Idle dbRefreshCache
        DoEvents
        
        Kill strDBFileName
        Name strDBFileNameTemp As strDBFileName
        
        'Indicate success
        pjsCompactDatabase = True
    End Function


    Paul

    • Marked as answer by majzad Sunday, January 15, 2017 6:36 AM
    Saturday, January 14, 2017 2:07 PM
  • I'd urge you to implement something like what is demonstrated in the following sample database. 

    http://www.rogersaccesslibrary.com/forum/topic377.html

     

    Also, what version of Access are you using?

    The SendKeys suggested by Peter does not appear to work on Access 2013, so if it does work in 2010, it would appear to be version specific.

    The code provided by Paul23 will only work of other databases.  It will not compact the current database.  So this can be very useful when try to compact a Back-End database for instance.

    If you explain a little more exactly what you are after, we may be in a better position to provide guidance on the matter.


    Daniel Pineault, 2010-2016 Microsoft MVP Professional Support: http://www.cardaconsultants.com MS Access Tips and Code Samples: http://www.devhut.net

    Saturday, January 14, 2017 2:35 PM
  • thanks.i use access2007.and i want to repair and compact the customer database for better performance of it during using it.  paul  codes were practical.

    microsoft

    Sunday, January 15, 2017 6:40 AM
  • thanks.it seems these code are useful.

    microsoft

    Sunday, January 15, 2017 6:41 AM
  • thanks.but i use acess2007.i see if it would work.

    microsoft

    Sunday, January 15, 2017 6:45 AM
  • But as I said, Paul's code can't be used on the active database while your customer is using the database. Paul's code also can't be used while there are any active connection to the back-end, so you need to close all the open objects within the FE prior to running the code.

    Daniel Pineault, 2010-2016 Microsoft MVP
    Professional Support: http://www.cardaconsultants.com
    MS Access Tips and Code Samples: http://www.devhut.net



    Sunday, January 15, 2017 1:16 PM
  • unfortunately this code does not work in access2007.some of  it like
    pjsGetFileTypeFromFullFileName
    DisableNameAutoCorrect(dbDatabase)
     makes error.undifined function.

    microsoft

    Monday, January 16, 2017 1:18 PM
  • you right daniel thanks.

    microsoft

    Monday, January 16, 2017 1:22 PM
  • Sorry, that is correct. Those are my own utility functions. You can remove the DisableNameAutoCorrect (which does what it's name suggests- disables the built-in Access option). That's not part of the compact and repair but is a setting I always use. The pjsGetFileTypeFromFullFileName() function returns the file type portion of the file name, so you can replace that with your own code. You can see how it's used in the following code line.


    Paul

    Monday, January 16, 2017 1:26 PM
  • Of course you can do a C&R with VBA.  You can just check the box that says 'Compact on Close' under 'Current Database'.

    Option Compare Database
    Option Explicit
     
    '   Declare an enumeration of long integer
    '   constants, to be used as the return values
    '   for the RepairDatabase() function.
    '   As Access's CompactRepair() method returns
    '   TRUE or FALSE, the Enum uses -1 (TRUE) for
    '   success and 0 for failure.
    Public Enum ryCompactResult
        cmpCompactSuccessful = -1
        cmpCompactFailed = 0
        cmpErrorOccurred = 1
        cmpSourceFileDoesNotExist = 2
        cmpInvalidSourceFileNameExtension = 3
        cmpDestinationFileExists = 4
    End Enum
     
     
    Private Sub TestRepair()
     
        Dim strSource As String
        Dim strDestination As String
        Dim lngRetVal As ryCompactResult
        
        strSource = "C:\MyFolder\db1.mdb"
        strDestination = "C:\MyFolder\db2.mdb"
        
        '   Call the function:
        lngRetVal = RepairDatabase(strSource, strDestination)
        
        '   Examine the return value from the function
        '   and display appropriate message:
        Select Case lngRetVal
        
        Case cmpCompactSuccessful
            MsgBox "Compact & repair successful.", _
                vbOKOnly + vbInformation, _
                "Program Information"
                
        Case cmpSourceFileDoesNotExist
            MsgBox strSource & vbNewLine & vbNewLine _
                & "The above file does not exist.", _
                vbOKOnly + vbExclamation, _
                "Program Finished"
                
        Case cmpInvalidSourceFileNameExtension
            MsgBox strSource & vbNewLine & vbNewLine _
                & "The above file has an invalid filename " _
                & "extension.", vbOKOnly + vbExclamation, _
                "Program Finished"
                
        Case cmpDestinationFileExists
            MsgBox strDestination & vbNewLine & vbNewLine _
                & "The above destination file exists. " _
                & vbNewLine _
                & "Please delete the above file or " _
                & "use a different destination filename.", _
                vbOKOnly + vbExclamation, "Program Finished"
                
        Case cmpErrorOccurred
            '   The RepairDatabase() function has
            '   already displayed an error message.
            
        End Select
        
        
    End Sub
     
    Function RepairDatabase( _
        strSource As String, _
        strDestination As String) As ryCompactResult
        
        ' IN:
        '
        '   strSource:
        '       The full path to the database that is
        '       to be compacted.
        '
        '   strDestination:
        '       The full path to the resultant database
        '       after strSource has been compacted.
        '
        ' OUT:
        '
        '   This function returns one of the values in
        '   the ryCompactResult Enum.
     
     
        Dim lngRetVal As ryCompactResult
        Dim strFileName As String
        Dim strFileNameExtn As String
        Dim lngPos As Long
     
     
    On Error GoTo Error_RepairDatabase
     
        '   See if source file exists:
        strFileName = Dir(strSource)
        If Len(strFileName) = 0 Then
            lngRetVal = cmpSourceFileDoesNotExist
            GoTo Exit_RepairDatabase
        End If
     
        '   See if source filename has appropriate
        '   filename extension (mdb or accdb).
        '   First, see if filename contains a period:
        lngPos = InStr(strFileName, ".")
        If lngPos = 0 Then
            '   Period not found in filename;
            '   i.e. no filename extension found.
            lngRetVal = cmpInvalidSourceFileNameExtension
            GoTo Exit_RepairDatabase
        Else
            '   Get filename extension:
            strFileNameExtn = Mid(strFileName, lngPos + 1)
            strFileNameExtn = LCase(strFileNameExtn)
     
            Select Case strFileNameExtn
            Case "mdb", "accdb"
                '   Correct filename extension found.
                '   We can proceed with compact & repair.
            Case Else
                '   Invalid filename extension found.
                lngRetVal = cmpInvalidSourceFileNameExtension
                GoTo Exit_RepairDatabase
            End Select
        End If
     
        '   Destination file must not exist:
        strFileName = Dir(strDestination)
        If Len(strFileName) > 0 Then
            lngRetVal = cmpDestinationFileExists
            GoTo Exit_RepairDatabase
        End If
     
        '   Compact and repair database:
        lngRetVal = Application.CompactRepair( _
                    strSource, strDestination, True)
     
    Exit_RepairDatabase:
        
        RepairDatabase = lngRetVal
        Exit Function
     
    Error_RepairDatabase:
        
        lngRetVal = cmpErrorOccurred
        MsgBox "Error No: " & Err.Number _
            & vbNewLine & vbNewLine _
            & Err.Description, _
            vbOKOnly + vbExclamation, _
            "Error Information"
            
        Resume Exit_RepairDatabase
        
    End Function


    MY BOOK


    • Edited by ryguy72 Monday, January 16, 2017 6:16 PM
    Monday, January 16, 2017 6:16 PM
  • what a big code.thanks.i need a long time to understand.i will test it.thanks.

    microsoft

    Tuesday, January 17, 2017 7:29 AM
  • running the above code i recived an error that the database is already open even though database.close and set nothing is before compact.why?

    microsoft

    Thursday, January 19, 2017 7:07 AM
  • when we want the name without path and extension what should we do?for example in this case to compact the database with another name?and how to separate database extension ?

    microsoft

    Thursday, January 19, 2017 7:11 AM
  • you right daniel.but it seems database.close or set database=nothing does not work in my case.and i receive an error in compact line.

    microsoft

    Saturday, January 21, 2017 7:05 AM
  • Does not work, could you elaborate.

    Receive and error in compact line, which error, which line, how are you calling the function?


    Daniel Pineault, 2010-2016 Microsoft MVP Professional Support: http://www.cardaconsultants.com MS Access Tips and Code Samples: http://www.devhut.net

    Saturday, January 21, 2017 3:06 PM
  • error7846.that says can not compact and repair the current database.i have tested JRO as well .but it seems that it is not for accdb or acde database formats.

    microsoft

    Sunday, January 22, 2017 7:41 AM
  • As I posted originally, you cannot compact the current database programmatically. No clue why Microsoft made this so complicated, but the did. If you want to compact the database you are actively in, then review my original link which provides the necessary code to accomplish this. The basic principle is to simply turn on (change the setting) of the Compact on Close property. Thus the db will get compact upon exiting and then you reset the setting once reopened (to avoid always compacting on close which is to be avoided).

    Daniel Pineault, 2010-2016 Microsoft MVP Professional Support: http://www.cardaconsultants.com MS Access Tips and Code Samples: http://www.devhut.net

    Sunday, January 22, 2017 4:30 PM