在VBA中获取MS access数据库的版本

在VBA中获取MS access数据库的版本,vba,ms-access,Vba,Ms Access,我正在使用下面Excel 365>Visual Basic编辑器中的代码尝试确定使用哪个版本的MS Access创建旧数据库。该代码适用于我作为测试创建的较新的.accdb数据库。据我所知,旧数据库最初是在Access 97中编写/设计的,但我想确定一下 Public Sub GetAccessFormat() ' Attempt to determine the format of an Access database ' Note: Can Access 16.0 (Offi

我正在使用下面Excel 365>Visual Basic编辑器中的代码尝试确定使用哪个版本的MS Access创建旧数据库。该代码适用于我作为测试创建的较新的
.accdb
数据库。据我所知,旧数据库最初是在Access 97中编写/设计的,但我想确定一下

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
错误文本为“您输入的表达式引用的对象已关闭或不存在。”(数据库确实存在,未在其他应用程序中打开,并且数据库上没有锁)

我们安装了Office 365(Access 16.0),因此我假设问题出在
Set objAccess=CreateObject(“Access.Application”)
上,因为我电脑上的“Access应用程序”将无法读取旧格式的Access数据库


这是正确的吗?是否有解决方法来确定旧Access数据库的文件格式?

根据Microsoft的说法:

将Access 97数据库转换为.accdb格式

从Access 2013开始,无法再直接转换 Access 97数据库(.mdb)的.accdb文件格式。然而,你 可以在早期版本的Access中打开Access 97数据库,以及 然后以Access 2013可以打开的格式保存数据库。对于 例如,下面介绍如何使用Access 2003打开Access 97数据库, 然后将其转换为Access 2013可以打开的格式:

  • 在Access 2003中打开Access 97数据库

  • 单击工具>数据库实用程序>转换数据库>访问 2002-2003文件格式

  • 输入数据库的名称,然后单击“保存”

  • 关闭Access 2003和open Access 2013

  • 打开数据库并单击文件>另存为>访问数据库 (.accdb)>另存为>保存

  • 您还可以使用Access 2007或Access 2010转换Access 97 将数据库设置为.accdb格式。在中打开Access 97数据库时 这两种产品中的任何一种,都会出现数据库增强向导 帮助将数据库转换为.accdb格式

    来源:

    替代解决方案:

    如果您没有旧版本的Access并希望提取数据,则可以使用“数据”选项卡上的导入功能,使用任何现代Excel版本进行提取。将数据保存到Excel后,可以将其重新导入以从Excel访问

    测试代码:

    综上所述,下面是一个经过测试的代码版本,可用于Access可以打开的任何DB:

    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
    

    您通常不希望使用完整的fat
    Access.Application
    对象来测试版本,请尝试仅使用
    DAO.DbEngine
    一个:

    ”打开数据库
    作为对象的Dim-dbe
    如果文件名像“*.mdb”,那么
    Set dbe=CreateObject(“DAO.DbEngine.36”)
    “旧喷气式发动机,32位,可能是仍支持Access 2.0的MDAC版本
    其他的
    Set dbe=CreateObject(“DAO.DbEngine.120”)
    “王牌引擎
    如果结束
    作为对象的Dim db
    Set db=dbe.OpenDatabase(文件名)
    '获取文件格式
    Dim文件格式为字符串
    fileFormat=db.Version“解码:https://docs.microsoft.com/en-us/office/client-developer/access/desktop-database-reference/database-version-property-dao
    
    请注意,
    CurrentProject.FileFormat
    Database.Version
    实际上都没有超过12.0

    我们还可以尝试获得更精确的版本:

    fileFormat = db.Properties!Version 'Decode = ???
    
    然而,对于这个版本,我还没有准备好解码器。对于没有最近字段(无bigint/datetime扩展)创建的accdb,它返回“12.0”,这与最近使用的2010功能一致

    但是,如果我添加一个datetime扩展字段,它会跳到“32.0”,这更难解码,特别是从2016年开始,数据库功能与主要的Office版本不一致(2016年早期版本不支持bigint,2016年后期版本支持bigint)。

    您也可以“查看”在文件的第二十一个字节处,并根据以下内容确定其文件类型:

    函数GetAccessFileType(文件路径为字符串)为字符串
    将strm调暗为新的ADODB.Stream
    strm.Type=adTypeBinary
    标准开启
    strm.LoadFromFile文件路径
    标准阅读20
    Dim字节作为变量
    字节=strm.Read(1)
    Dim fileTypeNumber为整数
    fileTypeNumber=CInt(字节(0))
    关门
    设置strm=Nothing
    Dim fileTypeString作为字符串
    选择案例文件类型编号
    案例0:
    fileTypeString=“Access 97或更早版本”
    案例1:
    fileTypeString=“Access 2000/2003”
    案例2:
    fileTypeString=“Access 2007”
    案例3:
    fileTypeString=“Access 2010”
    案例5:
    fileTypeString=“具有BIGINT支持的Access 2016(类型5)”
    其他情况:
    fileTypeString=“未知(&fileTypeNumber&”)
    结束选择
    GetAccessFileType=fileTypeString
    端函数
    
    您不需要像主机那样使用后期绑定声明。它已经被你使用它的天性所载入。删除
    objAccess
    并替换为简单的
    Application
    请注意,Access\u 2013及更新版本将绝对拒绝打开Access\u 97及更早版本中的.mdb文件。@HackSlash:我不确定是否遵循<代码>应用程序有类似于
    ActiveCell
    的成员,但没有
    CurrentProject
    FileFormat
    成员或属性。@AlainD,请在我的回答中查看测试过的代码。如果您看到的是
    ActiveCell
    ,那么听起来您好像在使用Excel。您的标签上写着
    msaccess
    ,因此我假设您使用access作为主机来运行VBA。如果不是预期的VBA主机,请在问题中澄清您正在使用的VBA主机。@HackSlash:是Excel…除Microsoft Office产品外,还有其他
    VBA
    主机吗?我确实澄清了我正在使用Office 365,问题中是否缺少某些内容?Gr