代码之家  ›  专栏  ›  技术社区  ›  Helloguys

延迟绑定全局变量?

  •  3
  • Helloguys  · 技术社区  · 6 年前

    我正在使用VBA for Excel。根据我的理解,全局变量需要在任何sub之外声明。这是所有潜艇都能访问它们的唯一方式。

    同时,我想进行后期绑定以引用“Microsoft脚本运行时”库(以便使用dictionary对象类型),这样最终用户就不必自己进行绑定。

    我的代码如下:

    On Error Resume Next
    strGUID = "{420B2830-E718-11CF-893D-00A0C9054228}"
    ThisWorkbook.VBProject.References.AddFromGuid GUID:=strGUID, Major:=1, Minor:=0
    
    Dim Dic1 As Object
    Set Dic1 = CreateObject("Scripting.Dictionary")
    Dim Dic2 As Object
    Set Dic2 = CreateObject("Scripting.Dictionary")
    

    如果我想用后期绑定声明全局字典对象,该怎么办?看起来VBA不允许我将任何代码放在SUB之外(声明除外)。

    如何在不需要最终用户自己配置库引用的情况下声明全局字典对象?我要做以下事情吗?

    Dim Dic1 As Object
    Dim Dic2 As Object
    
    Sub Prog1()
        On Error Resume Next
        strGUID = "{420B2830-E718-11CF-893D-00A0C9054228}"
        ThisWorkbook.VBProject.References.AddFromGuid GUID:=strGUID, Major:=1, Minor:=0
    
        Set Dic1 = CreateObject("Scripting.Dictionary")
        Set Dic2 = CreateObject("Scripting.Dictionary")
    End Sub
    
    2 回复  |  直到 4 年前
        1
  •  7
  •   Mathieu Guindon    6 年前

    与VBA代码本身一样,当用户打开宿主工作簿时,项目引用不会神奇地消失。它们与宿主文档中的代码一起保存。

    因此,您的问题的前提是错误的:用户永远不需要调整项目引用。

    此外,脚本运行时类型库是标准版本,在本世纪(甚至更早)构建的每台Windows计算机上都提供了完全相同的版本,这意味着除非您的代码需要在Mac上运行,否则无需延迟绑定脚本运行时库。

    如果您的代码需要在Mac上运行,那么库不会延迟绑定,因为它在主机上找不到,因此延迟绑定脚本运行时只会导致愚蠢的拼写错误,并引入其他容易避免的错误 有助于预防。


    ThisWorkbook.VBProject.References.AddFromGuid GUID:=strGUID, Major:=1, Minor:=0
    

    这破坏了后期绑定的全部目的:它使用VBIDE扩展性库(需要较低的宏安全设置)以编程方式添加引用,您可以在设计时通过VBE的 工具 菜单

    后期绑定的代码根本不需要引用。不是在编译时,也不是在运行时。

    添加引用,保存,然后声明对象 As Scripting.Dictionary 并享受早期绑定代码的好处。

    Set Dic1 = New Scripting.Dictionary
    

    这就是你所需要的。


    如果我想用后期绑定声明全局字典对象,该怎么办?看起来VBA不允许我将任何代码放在SUB之外(声明除外)。

    在这方面,后期绑定与早期绑定没有任何不同。这个 只有 后期绑定代码和早期绑定代码之间的区别是 As 声明条款:

    Private foo As Object ' no compile-time type knowledge: late-bound
    Private bar As Dictionary ' compile-time type knowledge: early-bound
    

    初始化对象引用的方式对声明的后期/早期绑定性质没有影响。

    这将在注册表中查找ProgID以查找库和类型:

    Set foo = CreateObject("Scripting.Dictionary")
    

    这将使用项目引用:

    Set foo = New Scripting.Dictionary
    

    两者都是正确的,并且都将对早期或后期绑定的声明起作用。除此之外,如果您已经有了对类型库的引用,那么实际上不需要访问注册表来定位该库-只要 New 加油!

        2
  •  2
  •   Vityata    6 年前

    确实不需要全局变量,应该避免全局变量。但是,如果您出于自己的原因决定使用它们,您可以将它们放在 Workbook_Open 活动:

    Option Explicit
    
    Dim Dic1 As Object
    Dim Dic2 As Object
    
    Private Sub Workbook_Open()
    
        Set Dic1 = CreateObject("Scripting.Dictionary")
        Set Dic2 = CreateObject("Scripting.Dictionary")
    
    End Sub
    

    因此,它将在每次打开工作簿时创建对象。