【问题标题】:Add references programmatically以编程方式添加引用
【发布时间】:2011-08-01 09:41:47
【问题描述】:

我们有一个在某些客户端上不起作用的 Access-Application,主要是因为引用已损坏。例如,当您使用 access runtime 2007 启动 access 应用程序但安装了版本 2003 或 2000 的 office 时,就会发生这种情况。 Left/Right/Trim 等功能将停止工作。

我认为解决此问题的唯一方法是以编程方式检查安装了哪个 Office 版本并以编程方式添加引用,因为在这些异构环境中,我们无法控制用户安装的内容。具体来说,我需要参考 Excel 和 Word 的 Microsoft Office 对象库。

但我既没有所有 office 版本的指南,也不知道如何自动检查它们。

【问题讨论】:

  • 对 Word 和 Excel 使用后期绑定。然后你的问题就消失了。
  • 如果你得到了错误的 Access 库版本,即使是内置函数也停止工作,所以后期绑定也无济于事。但这只发生在同时安装了不同版本的机器上。

标签: ms-access vba ms-office


【解决方案1】:

所以是的,这个答案有点晚了,但以防有人像我在寻找答案一样偶然发现这个问题,我想出了以下代码来添加一个 excel 参考,它似乎也可以正常工作在 MDE/ACCDE 中!

If Dir("C:\Program Files (x86)\Microsoft Office\Office12\EXCEL.exe") <> "" And Not refExists("excel") Then
    Access.References.AddFromFile ("C:\Program Files (x86)\Microsoft Office\Office12\EXCEL.exe")
End If
If Dir("C:\Program Files (x86)\Microsoft Office\Office14\EXCEL.exe") <> "" And Not refExists("excel") Then
    Access.References.AddFromFile ("C:\Program Files (x86)\Microsoft Office\Office14\EXCEL.exe")
End If
If Dir("C:\Program Files (x86)\Microsoft Office\Office12\EXCEL.exe") = "" And Dir("C:\Program Files (x86)\Microsoft Office\Office14\EXCEL.exe") = "" Then
    MsgBox ("ERROR: Excel not found")
End If

并且 refExists 引用了以下函数:

Private Function refExists(naam As String)
Dim ref As Reference
refExists = False
For Each ref In References
    If ref.Name = naam Then
        refExists = True
    End If
Next
End Function

【讨论】:

    【解决方案2】:

    如果您发布了 MDE/ACCDE,则无法更新您的参考资料。

    但是哪些具体的参考资料给您带来了问题?您可能正在引用 Word、Excel 或 Outlook。如果是这样,请使用后期绑定,因此您的解决方案与客户端系统上安装的版本无关。

    后期绑定意味着您可以安全地删除引用,并且只有在应用执行相关代码行时才会出现错误。而不是在启动应用程序时出错并且根本不允许用户进入应用程序。或者在点击中间、左侧或修剪函数调用时。

    当您不知道外部应用程序的版本将驻留在目标系统上时,这也非常有用。或者,如果您的组织正在从一个版本迁移到另一个版本。

    有关更多信息,包括附加文本和一些详细链接,请参阅“Late Binding in Microsoft Access”页面。

    【讨论】:

    • 但是如果我创建一个 Excel.Application 对象,Excel 不会启动吗?
    • 你用 Excel 做什么?
    • Falcon,是的,Excel 将在您创建对象后启动。但是,当您开始使用被引用的 Excel 对象时,就会发生这种情况。
    • Tony...我是否正确假设如果我使用后期绑定,我必须为我正在自动化的每个 Office 应用程序编写例程,每个应用程序版本使用不同的语法。例如,我拥有的应用程序是 Access 的一个非典型用例,因为我使用它来构建一个快速 GUI,允许人们在现场自动化 ppt 演示、excel 工作簿、outlook 电子邮件、xml 数据文件、word 文档等.因此,我必须为每个作业的 Word 2000、Word 2003、Word 2007 等编写流程的副本......以便使用后期绑定,并且仍然保留功能?
    • 不,每个版本不需要不同的语法。您编写的代码与使用该参考的代码基本相同。唯一的区别是您不使用引用的外部库中的数据类型,并且您必须手动实例化外部应用程序的实例。否则,它是完全相同的代码。您为什么不实际尝试按照使用后期绑定的说明来看看它是如何工作的?
    【解决方案3】:

    这是一个示例 - 它检查某些引用 - 删除它们并导入 Access 2000 变体。只是为了确保所有客户端都使用相同(最低)版本的依赖项

    Sub CheckReference()
    ' This refers to your VBA project.
        Dim chkRef As Reference ' A reference.
    
        Dim foundWord, foundExcel As Boolean
    
        foundWord = False
        foundExcel = False
    
        ' Check through the selected references in the References dialog box.
        For Each chkRef In References
    
    
            ' If the reference is broken, send the name to the Immediate Window.
            If chkRef.IsBroken Then
               Debug.Print chkRef.Name
            End If
    
            If InStr(UCase(chkRef.FullPath), UCase("MSWORD9.olb")) <> 0 Then
                foundWord = True
            End If
    
            If InStr(UCase(chkRef.FullPath), UCase("EXCEL9.OLB")) <> 0 Then
                foundExcel = True
            End If
    
            If InStr(UCase(chkRef.FullPath), UCase("MSWORD.olb")) <> 0 Then
                References.Remove chkRef
            ElseIf InStr(UCase(chkRef.FullPath), UCase("EXCEL.EXE")) <> 0 Then
                References.Remove chkRef
            End If
    
    
        Next
    
        If (foundWord = False) Then
            References.AddFromFile ("\\pathto\database\MSWORD9.OLB")
        End If
    
        If (foundExcel = False) Then
            References.AddFromFile ("\\pathto\database\EXCEL9.OLB")
        End If
    
    End Sub
    

    【讨论】:

    • 我会投票支持后期绑定而不是搞砸修复引用。
    • 您无法修复 MDE/ACCDE 中的引用。
    • 我不同意,上面的代码来自现场工作环境。
    • 这是来自 MDE/ACCDE 的?
    【解决方案4】:

    这是一个代码示例,用于检查损坏的引用。我知道这不是你的全部解决方案,但它会给你一些线索如何做到这一点。

    Public Function CheckRefs()
        On Error GoTo Handler
    
        Dim rs As Recordset
        Dim ref As Reference
        Dim msg As String
    
        For Each ref In Application.References
            ' Check IsBroken property.
            If ref.IsBroken = True Then
                msg = msg & "Name: " & ref.Name & vbTab
                msg = msg & "FullPath: " & ref.FullPath & vbTab
                msg = msg & "Version: " & ref.Major & "." & ref.Minor & vbCrLf
            End If
        Next ref
    
        If Len(msg) > 0 Then MsgBox msg
        Exit Function
    
    Handler:
        ' error codes 3075 and 3085 need special handling
    
        If Err.Number = 3075 Or Err.Number = 3085 Then
            Err.Clear
            FixUpRefs
        Else
            rs.Close
            Set rs = Nothing
        End If
    End Function
    
    Private Sub FixUpRefs()
        Dim r As Reference, r1 As Reference
        Dim s As String
    
        ' search the first ref which isn't Access or VBA
        For Each r In Application.References
            If r.Name <> "Access" And r.Name <> "VBA" Then
                Set r1 = r
                Exit For
            End If
        Next
        s = r1.FullPath
    
        ' remove the reference and add it again from file
        References.Remove r1
        References.AddFromFile s
    
        ' hidden syscmd to compile the db
        Call SysCmd(504, 16483)
    End Sub
    

    【讨论】:

    • 在我的应用程序中,我完全避免了这个问题,除了默认的 3、Access、VBA 和 DAO 之外,我从不使用任何引用。在我看来,后期绑定确实是要走的路。
    • 就个人而言,我两者都做。在开发过程中,我使用引用进行类型检查并查看代码完成情况,然后切换到后期绑定。
    • 双,正确。我的后期绑定页面提到了该技​​术以及示例代码,以使切换更加容易。
    • 我可以设置一个足够长的参考来获得 Intellisense,然后摆脱它。对于自动化 Office 应用程序,我什至不再这样做 - 相反,我只是启动有问题的应用程序,打开其 VBE 并使用本机 Intellisense。
    • dwo,没有 Access 不会自动删除丢失的引用。相反,您会在代码的其他地方遇到奇怪的、难以理解的错误,例如在使用 trim、left 或 mid 等字符串函数时。
    猜你喜欢
    • 2011-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-10
    • 2012-04-10
    相关资源
    最近更新 更多