代码之家  ›  专栏  ›  技术社区  ›  Sam Cogan

VBA全局变量,多个工作簿

  •  1
  • Sam Cogan  · 技术社区  · 14 年前

    我有一个VB应用程序,它使用一些全局变量来存储多个窗体和模块所需的数据,这很好。但是,如果用户打开另一个工作簿,运行同一个VBA应用程序,那么他们最终会访问(并更改)同一公共变量。

    如何使用工作簿级别的全局变量,或者如果不可能,存储所有窗体和模块都可以访问但只能在特定工作簿中访问的数据的最佳方法是什么?

    这是一个VBA加载项,全局变量在标准模块中声明。

    4 回复  |  直到 13 年前
        1
  •  1
  •   Marc Thibault    14 年前

    我可以用一个叫乔治的简单XLA来复制这个问题:

    Public harry As Variant
    
    Public Sub setHarry(x)
        harry = x
    End Sub
    
    Public Function getHarry()
        getHarry = harry
    End Function
    

    我安装了XLA。然后,我创建了alice.xls,其中有一个文本框,当它发生变化时,该文本框会调用setharry,并且其中包含一个带有=getharry()的单元格。我一直很简单:

    Private Sub TextBox1_Change()
        Run "george.xla!setHarry", TextBox1
    End Sub
    

    然后我把alice.xls复制成bob.xls,并把它们都运行了。正如所料,如果任一工作簿更改了Harry,则两个工作簿都会看到结果。

    我说是预期的,因为XLA和DLL一样,因为内存中只有一个副本是所有人共享的;显然这包括全局变量,这是有意义的。我只是想测试一下这个理论。

    在我看来,解决这个问题的最好方法是使用类模块而不是普通模块。通过这种方式,您可以在工作簿的“打开”事件中为每个工作簿提供自己的类实例及其变量。如果变量声明为public,则不需要属性gets和set,但如果有值可以使用它们。

        2
  •  1
  •   Dick Kusleika    14 年前
    Public myvar as Variant
    

    声明为public的变量的作用域是它们所在的工作簿。如果您有另一个带有myvar的工作簿,在一个工作簿中更改它的值不会在另一个工作簿中更改它。也许您有一个事件,它设置了ActiveSheet中的变量,该变量在两个项目中触发,并将变量设置为相同的内容。

        3
  •  1
  •   Charles Williams    14 年前

    全局变量的作用域是全局的。 我会将它们存储在每个工作簿中的隐藏名称中,然后在每次激活工作簿时重置全局变量(也会将值重新存储在已停用的工作簿中)。

        4
  •  1
  •   Oneide    14 年前

    我认为您可以在运行时获得工作簿名称。

    因此,一个集合可能会完成这项工作。

    '//-- module --
    Public var As Collection
    
    Public Function SetVar(Value)
       If var Is Nothing Then
          Set var = New Collection
       End If
       var.Add Value, ThisWorkbook.Name
    End Function
    
    Public Function GetVar() As Variant
       If var Is Nothing Then
          GetVar = Null
       Else
          GetVar = var.Item(ThisWorkbook.Name)
       End If
    End Function
    

    但不确定它是否适合您的加载项。