跳到主要内容

使用 VBA 自动添加前期引用

前面讲过,我们在 VBA 中要访问其他对象,有两种方式,即前期绑定与后期绑定。由于前期绑定(也可以叫前期引用,早期绑定等等)是微软建议的,不但能提高代码运行速度,而且还能直接列出成员属性、方法列表等,对编写代码非常方便,但是前期绑定通常是手工添加的,如果代码换个运行环境,就会导致代码找不到库而无法运行,所以使用 VBA 自动添加引用库就显得非常重要。有两种方法:可以使用 References 对象的 AddFromFile 方法或者 AddFromGuid 方法

AddFromFile 方法

AddFromFile 方法是通过添加具体的文件路径的方法引用,这种方法有很大的局限性,不同的系统、不同的安装路径都会导致同一个库的路径不一致。一般在自已封装 DLL 中使用,比如:

ThisWorkbook.VBProject.References.AddFromFile (ThisWorkbook.Path & "\yourdll.dll")

AddFromGuid 方法

AddFromGuid 方法直接根据全局唯一标识符(globally unique identifier,GUID)添加引用,这种方法可以跨平台、跨版本、跨系统都有效。

语法

object.AddFromGuid (guidmajorminor)

参数说明

参数 说明
object 必填。 一个 对象表达式 ,该表达式的计算结果为“ 应用于 ”列表中的对象。
guid 必填。 表示引用的 GUID 的 字符串表达式 。
major 必填。 指定引用的主要版本号的长整型变量。
minor 必填。 指定引用的次要版本号的长整型变量。

GUID 参数获取

具体的某个引用的 guidmajorminor 参数怎么获取呢?如果你手里有现成的 GUID,直接使用即可,如果没有,可以使用下面的方法获取。

步骤一:开启“信任对 VBA 工程对象模型的访问”

由于此 VBA 代码需要访问工程对象模型,所以需要开启“信任对 VBA 工程对象模型的访问”。

手动操作如下:依次打开【文件】【选项】【信任中心】【信任中心设置】【宏设置】【开发人员宏设置】,选择【信任对 VBA 工程对象模型的访问】复选框。

信任对 VBA 工程对象模型的访问
信任对 VBA 工程对象模型的访问

或者使用 VBA 开启“信任对 VBA 工程对象模型的访问”

步骤二:手动添加要引用的库

手动添加要引用的库,在 VBE 中,单击【工具】【引用】,然后在【引用对话框】中选择需要引用的库。

步骤三:使用 VBA 自动获取 GUID

Sub GetGUID()
    Dim ws As Worksheet
    Dim oRef
    Dim arr()
    Dim i As Long
    
    Set ws = ThisWorkbook.ActiveSheet
    arr = Array("引用的名称", "引用的路径", "GUID", "Major", "Minor", "说明")
    With ws
        .Cells.Clear
        .Range("a1").Resize(1, UBound(arr) + 1) = arr
    End With
    
    i = 2
    '遍历所有的引用
    For Each oRef In ThisWorkbook.VBProject.References
        With oRef
            ws.Cells(i, 1) = .Name
            ws.Cells(i, 2) = .FullPath
            ws.Cells(i, 3) = .GUID
            ws.Cells(i, 4) = .Major
            ws.Cells(i, 5) = .Minor
            ws.Cells(i, 6) = .Description
            i = i + 1
        End With
    Next
End Sub

运行代码结果如下:

获取引用库 GUID
获取引用库 GUID

步骤四:将 GUID 填入代码

将第三步获取的 GUID 参数写入 AddFromGuid 方法。

比如我们要在 Excel 中使用 VBA 操作 PowerPoint,后期绑定代码是:CreateObject("PowerPoint.Application") ,查询第三步表得知,所对应的引用的是 Microsoft PowerPoint 16.0 Object Library,它的 GUID 是 {91493440-5A91-11CF-8700-00AA0060263B},major 是 2,minor 是 12。使用 VBA 自动添加 Microsoft PowerPoint 16.0 Object Library 代码如下:

Sub AutoReference()
    Dim oRef
    '如果已经手动引用,再次引用会冲突,防止“名称与已存在的模板、工程或对象冲突”
    On Error Resume Next
    '添加对PowerPoint的引用
    Set oRef = ThisWorkbook.VBProject.References.AddFromGuid("{91493440-5A91-11CF-8700-00AA0060263B}", 2, 12)
End Sub

如果已经手动添加了引用库,再次用 VBA 代码添加库会弹出“名称与已存在的模板、工程或对象冲突”的提示,所以上面的代码添加了防错语句:On Error Resume Next

如果需要其它引用,修改其 GUID 参数即可。

常用对象自动前期引用的代码

Sub AutoReferenceObj()
    '常用对象自动前期引用
    Dim oRef
    '如果已经手动引用,再次引用会冲突,防止“名称与已存在的模板、工程或对象冲突”
    On Error Resume Next
    
    '添加 Word 对象
    Set oRef = ThisWorkbook.VBProject.References.AddFromGuid("{00020905-0000-0000-C000-000000000046}", 8, 7)
    '添加 PowerPoint 对象用
    Set oRef = ThisWorkbook.VBProject.References.AddFromGuid("{91493440-5A91-11CF-8700-00AA0060263B}", 2, 12)
    '添加 Excel 对象
    Set oRef = ThisWorkbook.VBProject.References.AddFromGuid("{00020813-0000-0000-C000-000000000046}", 1, 9)
    '添加 Access 对象
    Set oRef = ThisWorkbook.VBProject.References.AddFromGuid("{4AFFC9A0-5F99-101B-AF4E-00AA003F0F07}", 9, 0)
    '添加 ADOX 对象
    Set oRef = ThisWorkbook.VBProject.References.AddFromGuid("{00000600-0000-0010-8000-00AA006D2EA4}", 6, 0)
    '添加 VBIDE 对象
    Set oRef = ThisWorkbook.VBProject.References.AddFromGuid("{0002E157-0000-0000-C000-000000000046}", 5, 3)
    '添加 WinHttp 对象
    Set oRef = ThisWorkbook.VBProject.References.AddFromGuid("{662901FC-6951-4854-9EB2-D9A2570F2B2E}", 5, 1)
    '添加 MSHTML 对象
    Set oRef = ThisWorkbook.VBProject.References.AddFromGuid("{3050F1C5-98B5-11CF-BB82-00AA00BDCE0B}", 4, 0)
End Sub

局限性

使用 VBA 自动添加前期引用需要开启【信任对 VBA 工程对象模型的访问】,由于安全限制,此选项默认是关闭的,如果此选项不打开,AddFromGuid 方法也无法使用,所以此方法也有局限性,Excel 也没有提供开启的方法,但是我们可以修改注册表键值来达到这一目的。

从设置开启【信任对 VBA 工程对象模型的访问】到自动引用库完整代码如下:

Sub AutoRef()
    '使用 VBA 自动添加前期引用
    ' https://oacourse.com/excel/automatically-add-references/

    Dim oWshell
    Set oWshell = CreateObject("WScript.Shell")
    '开启“信任对 VBA 工程对象模型的访问”
    oWshell.RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Office\" & Application.Version & "\Excel\Security\AccessVBOM", 1, "REG_DWORD"
    
    Dim oRef
    '如果已经手动引用,再次引用会冲突,防止“名称与已存在的模板、工程或对象冲突”
    On Error Resume Next
    '添加对PowerPoint的引用
    Set oRef = ThisWorkbook.VBProject.References.AddFromGuid("{91493440-5A91-11CF-8700-00AA0060263B}", 2, 12)
End Sub

评论

您的电子邮件地址不会显示出来。*号为必填项。