Excel VBA全局变量

3

在这个问题中,你想要在代码开始时声明并分配一个变量,可以通过任何使用它的模块更改。这个变化应该在下一个方法调用它时反映出来。请问,在ThisWorkbook Excel对象的Private Sub Workbook_Open中声明的变量能否被另一个模块中的另一种方法访问?

我有一个在模块中赋值给公共变量的子程序。我需要这个由module1设置的值能够被module2访问。


在过程范围内声明的变量不能是全局的,它只是该过程的本地变量。了解作用域,并学习如何在过程之间传递参数。99% 的全局变量操作都可以用参数来代替。 - Mathieu Guindon
5个回答

10
一个全局变量需要具有公共可访问性,并在标准模块 (.bas) 中以模块范围声明。
Option Explicit
Public Foo As Long ' global variable

全局变量的问题在于它们可以被任何代码中的任何部分读取和写入:全局状态很容易导致难以维护的代码,应尽可能避免使用。

有许多替代方案,其中主要是使用参数

Option Explicit

Public Sub SomeEntryPoint()
    Dim foo As Long ' local variable
    DoSomething foo
    MsgBox foo 'prints 42
End Sub

'this procedure could be in any module, public.
Private Sub DoSomething(ByRef foo As Long)
    foo = 42 'byref assignment; caller will receive the updated value
End Sub

如果变量需要由声明它的模块写入,但需要从其他地方读取,则可以使用属性作为另一种选择:

Option Explicit
Private foo As Long ' private field

Public Sub DoSomething()
    'do stuff...
    foo = 42
    '...
End Sub

Public Property Get SomeFoo() As Long
    SomeFoo = foo
End Property

现在该模块中的代码可以根据需要写入foo,其他模块只能通过SomeFoo属性读取foo - 假设字段和属性在Module1中定义:
Debug.Print Module1.SomeFoo 'gets the value of the encapsulated private field

6

在 @David 的回答基础上,这是如何使用 Dim 和 Public 及它们之间的区别(在一个名为 Modul1 的模块中编写以下代码,并运行 TestMe):

Dim a           As String
Public b        As String
Private c       As String
Global d        As String

Private Sub TestA()
'Whatever is not declared in TestMe, would take its value from here for the print.
'^-If it is declared, the value would be attached to the public/private/dim/glb above.    
    a = 11
    b = 22
    c = 33
    d = 44        
End Sub

Private Sub TestMe()

    Dim a       As String
    'Dim b       As String
    'Dim c       As String
    Dim d       As String

    a = 1
    b = 2
    c = 3
    d = 4

    TestA

    Debug.Print a; vbTab; Modul1.a
    Debug.Print "----------------"
    Debug.Print b; vbTab; Modul1.b
    Debug.Print "----------------"
    Debug.Print c; vbTab; Modul1.c
    Debug.Print "----------------"
    Debug.Print d; vbTab; Modul1.d

End Sub

这是您所获得的内容:
1    11
----------------
22    22
----------------
33    33
----------------
4    44

2
不,这个变量应该在普通模块中声明为公共变量。

0
' Public variable
Public a as String

' Local variable
Public sub hello()
    Dim a as String
End sub

第一个a是公共的,您可以在任何地方使用;而第二个变量是本地的,您只能在函数hello()中使用。因此,这两个变量是不同的。


2
Dim从来不是公共的。这个答案是错误和误导性的。那个“私有变量”实际上是一个本地变量,而你所谓的“公共变量”实际上是一个私有字段,一个只能在该模块内访问的模块范围变量。 - Mathieu Guindon
@Mat'sMug 感谢您的评论,您是正确的。我已经修改了我的答案。 - David

0

无法调用,因为您正在调用一个私有子程序。

为了拥有可以公开更改的变量,请尝试在任何子程序之外:

Public wBk As Workbook 
Public var As String

这将声明变量。要修改值,您需要在公共子例程中设置它们:

Public Sub myPublicVar()
Set wBk = Workbooks("Workbook1.xlsm")
Set var = "Whatever you like"
End Sub

如果你想让你的模块或子程序包含变量,你需要执行以下操作:
Sub myOtherSub()
Call myPublicVar
MsgBox var
End Sub

希望这能帮到你!


公共变量1为字符串类型子程序M1() 变量1 = "Excel" 结束子程序子程序M2() 消息框(var1) 结束子程序 - Ryan Cardoza
好的,所以:Public var1 as String - 将var1变成公共字符串。使用Public Sub M1()代替Sub M1(),这样可以让你在另一个子程序中使用该变量。在你的第三个子程序中,你需要执行以下操作:Sub M2(), call M1, MsgBox var1, End Sub - itChi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接