Get version of MS access database in VBA

Viewed 1364

I'm using the code below in Excel 365 > Visual Basic Editor to attempt to determine which version of MS Access was used to create an old database. The code works for a newer .accdb database I created as a test. As far as I know the older database was originally written/designed in Access 97, but I want to find out for sure.

Public Sub GetAccessFormat()
    ' Attempt to determine the format of an Access database
    ' Note: Can Access 16.0 (Office 365) read databases from Office 2013 and earlier?
    On Error GoTo Error_NotAccessDatabase
    Dim fileName As String
    'fileName = "C:\Tmp\old.mdb"  ' Fails
    fileName = "C:\Tmp\new.accdb" ' Works
    
    If IsEmpty(Dir(fileName)) Then
        MsgBox "Could not find: " & fileName
        Exit Sub
    End If
    
    ' Open the database
    Dim objAccess As Object
    Set objAccess = CreateObject("Access.Application") ' Is this the problem?
    objAccess.OpenCurrentDatabase fileName
    objAccess.Visible = False
    
    ' Get the file format
    Dim fileFormat As Integer
    fileFormat = objAccess.CurrentProject.FileFormat ' Gets here and fails for .mdb (returns "12" for the .accdb)
    Dim strAccessFormat As String
    strAccessFormat = "Your database is: "
    
    Select Case fileFormat
        Case 2
            strAccessFormat = (strAccessFormat & "Microsoft Access 2")
        Case 7
            strAccessFormat = (strAccessFormat & "Microsoft Access 95")
        Case 8
            strAccessFormat = (strAccessFormat & "Microsoft Access 97")
        Case 9
            strAccessFormat = (strAccessFormat & "Microsoft Access 2000")
        Case 10
            strAccessFormat = (strAccessFormat & "Microsoft Access 2002")
        Case 11
            strAccessFormat = (strAccessFormat & "Microsoft Access 2003")
        Case 12
            strAccessFormat = (strAccessFormat & "Microsoft Access 2007")
        Case 14
            strAccessFormat = (strAccessFormat & "Microsoft Access 2010")
        Case 15
            strAccessFormat = (strAccessFormat & "Microsoft Access 2013")
        Case 16
            strAccessFormat = (strAccessFormat & "Microsoft Access 2016/9")
        Case Else
            strAccessFormat = "Unknown Access file format"
    End Select
    
    ' Close database and display the format information
    objAccess.CloseCurrentDatabase
    strAccessFormat = (strAccessFormat + " (" & fileFormat & ".0)")
    MsgBox strAccessFormat
    Exit Sub

Error_NotAccessDatabase:
    ' Unable to open the database (not Access or not supported by this version of Office?)
    MsgBox "Unable to open as Access database: " & strFile & ", Error: " & Err.Description
    Exit Sub
End Sub

The error text is "The expression you entered refers to an object that is closed or doesn't exist." (The database does exist, is not open in another application and there is no lock on the database)

We have Office 365 (with Access 16.0) installed, so I assume the problem is with Set objAccess = CreateObject("Access.Application") because the "Access Application" on my PC will be unable to read older format access databases.

Is this correct? And is there a workaround to determine the file format of old Access databases?

3 Answers

You can also "peek" at the twenty-first byte of the file and determine its file type from that:

Function GetAccessFileType(filePath As String) As String
    Dim strm As New ADODB.Stream
    strm.Type = adTypeBinary
    strm.Open
    strm.LoadFromFile filePath
    strm.Read 20
    Dim bytes As Variant
    bytes = strm.Read(1)
    Dim fileTypeNumber As Integer
    fileTypeNumber = CInt(bytes(0))
    strm.Close
    Set strm = Nothing
    Dim fileTypeString As String
    Select Case fileTypeNumber
        Case 0:
            fileTypeString = "Access 97 or older"
        Case 1:
            fileTypeString = "Access 2000/2003"
        Case 2:
            fileTypeString = "Access 2007"
        Case 3:
            fileTypeString = "Access 2010"
        Case 5:
            fileTypeString = "Access 2016 with BIGINT support (Type 5)"
        Case Else:
            fileTypeString = "Unknown (" & fileTypeNumber & ")"
    End Select
    GetAccessFileType = fileTypeString
End Function

You generally don't want to use a full fat Access.Application object for testing the version, try just using a DAO.DbEngine one:

    ' Open the database
    Dim dbe As Object
    If fileName Like "*.mdb" Then
        Set dbe = CreateObject("DAO.DbEngine.36") 
        'Old JET engine, on 32-bits likely the MDAC version that still supports Access 2.0
    Else
        Set dbe = CreateObject("DAO.DbEngine.120")
        'ACE engine
    End If
    Dim db As Object
    Set db = dbe.OpenDatabase(fileName)
    
    ' Get the file format
    Dim fileFormat As String
    fileFormat = db.Version 'Decode: https://docs.microsoft.com/en-us/office/client-developer/access/desktop-database-reference/database-version-property-dao

Note that both CurrentProject.FileFormat and Database.Version don't really go beyond 12.0.

We can also attempt to get the more exact version:

fileFormat = db.Properties!Version 'Decode = ???

However, for this version, I don't have a decoder ready. For an accdb created without recent fields (no bigint/datetime extended), it returns "12.0", which is in line with 2010 features being the most recent used.

However, if I add a datetime extended field, it jumps to "32.0", which is harder to decode, especially since starting with 2016, database features haven't corresponded to major Office releases (early 2016 builds don't support bigint, late 2016 builds do).

According to Microsoft:

Convert an Access 97 database to the .accdb format

Starting with Access 2013, it’s no longer possible to directly convert an Access 97 database (.mdb) to the .accdb file format. However, you can open an Access 97 database in a previous version of Access, and then save the database in a format that Access 2013 can open. For example, here’s how to use Access 2003 to open an Access 97 database, then convert it to a format that can be opened by Access 2013:

  1. Open the Access 97 database in Access 2003.

  2. Click Tools > Database Utilities > Convert Database > to Access 2002-2003 file format.

  3. Enter a name for the database and click Save.

  4. Close Access 2003 and open Access 2013.

  5. Open the database and click File > Save As > Access Database (.accdb) > Save As > Save.

You can also use Access 2007 or Access 2010 to convert an Access 97 database to the .accdb format. When you open an Access 97 database in either of these two products, the Database Enhancement wizard appears to help convert the database to an .accdb format.

SOURCE: https://support.microsoft.com/en-us/office/convert-a-database-to-the-accdb-file-format-098ddd31-5f84-4e89-8f44-db0cf7c11acd#__convert_an_access

ALTERNATE SOLUTION:

If you don't have an old version of Access and want to pull the data out you can do so using any modern Excel version using the import function found on the Data tab. Once you have the data saved out to Excel you can import it back in to Access from Excel.

TESTED CODE:

All that said, here is a tested version of your code that works with any DB that Access can open:

Public Sub GetAccessFormat()
    ' Attempt to determine the format of an Access database
    On Error GoTo Error_NotAccessDatabase
    Dim fileName As String
    'fileName = "C:\Tmp\old.mdb"  ' Fails
    fileName = "C:\Tmp\new.accdb" ' Works
    
    If IsEmpty(Dir(fileName)) Then
        MsgBox "Could not find: " & fileName
        Exit Sub
    End If
    
    ' Open the database
    Application.OpenCurrentDatabase fileName
    Application.Visible = False
    
    ' Get the file format
    Dim strAccessFormat As String
    strAccessFormat = "Your database is: "
    
    Select Case Application.CurrentProject.FileFormat
        Case acFileFormatAccess2
            strAccessFormat = (strAccessFormat & "Microsoft Access 2")
        Case acFileFormatAccess95
            strAccessFormat = (strAccessFormat & "Microsoft Access 95")
        Case acFileFormatAccess97
            strAccessFormat = (strAccessFormat & "Microsoft Access 97")
        Case acFileFormatAccess2000
            strAccessFormat = (strAccessFormat & "Microsoft Access 2000")
        Case acFileFormatAccess2002
            strAccessFormat = (strAccessFormat & "Microsoft Access 2002")
        Case 11
            strAccessFormat = (strAccessFormat & "Microsoft Access 2003")
        Case 12
            strAccessFormat = (strAccessFormat & "Microsoft Access 2007")
        Case 14
            strAccessFormat = (strAccessFormat & "Microsoft Access 2010")
        Case 15
            strAccessFormat = (strAccessFormat & "Microsoft Access 2013")
        Case 16
            strAccessFormat = (strAccessFormat & "Microsoft Access 2016/9")
        Case Else
            strAccessFormat = "Unknown Access file format"
    End Select
    
    ' Close database and display the format information
    strAccessFormat = (strAccessFormat + " (" & Application.CurrentProject.FileFormat & ".0)")
    MsgBox strAccessFormat
    
    Application.CloseCurrentDatabase
    Exit Sub

Error_NotAccessDatabase:
    ' Unable to open the database (not Access or not supported by this version of Office?)
    MsgBox "Unable to open as Access database: " & fileName & ", Error: " & Err.Description
    Exit Sub
End Sub
Related