在VBA中使用全局variables
刚刚在上周开始使用VBA,正在玩Sheets vs. Modules和定义variables。 这是我现在的代码:
工作表Sheet1:
Dim writtenvoe As Boolean Dim verbalvoe As Boolean Dim voerequired As Boolean Dim CA14 As Boolean Dim CA15 As Boolean Dim W2s As Boolean Dim tranapp As Boolean
模块1:
Public Sub ImpDocs() 'Is written voe on file? If Sheet1.CheckBox6.Value = True Or Sheet1.CheckBox8.Value = True Or Sheet1.CheckBox9.Value = True Or Sheet1.CheckBox10.Value = True Then writtenvoe = True Else writtenvoe = False If Sheet1.CheckBox6.Value = True Then Sheet1.[O40] = "hello" Else Sheet1.[O40] = "" If writtenvoe = True Then Sheet1.[O39] = "writtenvoe = true" Else Sheet1.[O39] = "writtenvoe=false" 'Is verbal voe on file? If Sheet1.CheckBox11.Value = True Then verbalvoe = True 'Is a written VOE required? If Sheet1.CheckBox16.Value = True Or Sheet1.CheckBox18.Value = True Or Not IsEmpty(Sheet1.[H33]) Then voerequired = True If voerequired = True Then Sheet1.[J35] = "hello" Else Sheet1.[J35] = "" 'Are tax docs CA14 or CA15? If Sheet1.CheckBox31.Value = True Or Sheet1.CheckBox7.Value = True Or Sheet1.CheckBox32.Value = True Or Sheet1.[H29].Value > 25 Then CA15 = True Else CA15 = False If CA15 = False Then CA14 = True Else CA14 = False 'Are W-2's on file? If Sheet1.CheckBox12.Value = True And Sheet1.CheckBox13.Value = True Then W2s = True 'Are 4506-T's on file? If Sheet1.CheckBox60.Value = True And Sheet1.CheckBox61.Value = True Then tranapp = True 'Order Wage transcripts if W-2s and 4506-T not on file If W2s = False And tranapp = False And CA14 = True Then Sheet4.fullCA14 End Sub
另外模块1(第二子程序):
Public Sub test() If writtenvoe = True Then Sheet1.[N37] = "Yes" Else Sheet1.[N37] = "No" End Sub
我注意到在这种当前格式下,Sub ImpDocs工作正常,variables被正确地确定,但Subtesting总是返回false。 但是,如果我把所有的代码放到模块1中,每个代码都按预期工作。 似乎只有Subtesting会受到Sheet1与Module1中声明variables的影响。 真的吗? 如果是这样,为什么?
谢谢。
这是VBA如何执行命名空间的一个怪癖( https://en.wikipedia.org/wiki/Namespace )。 回到Sheet1中,您需要将writtenvoe
作为Sheet1的Public
成员:
Public writtenvoe As Boolean
然后,在Module1
,每次需要Sheet1
的writtenvoe
时,都必须指定Sheet1.writtenvoe
,例如:
'Is written voe on file? If Sheet1.CheckBox6.Value = True Or Sheet1.CheckBox8.Value = True Or Sheet1.CheckBox9.Value = True Or Sheet1.CheckBox10.Value = True Then Sheet1.writtenvoe = True Else Sheet1.writtenvoe = False
当您将writtenvoe
从Sheet1
移动到Module1
,您已经有效地移除了Sheet1.writtenvoe
并创build了Module1.writtenvoe
,从而使得Module1可以轻松访问这些内容。 模块的命名空间是非常宽容的,所以任何在模块中声明为Public
东西在任何地方都是可用的 – 另一个模块,任何表单,任何类模块等等。
Sheet1
是一个Worksheet
对象,一个类的实例 。 因此,即使您在Sheet1
上声明了一切Public
内容,也不Sheet1
访问该实例即可访问它们。
Dim
用于声明局部variables。 它在模块级也是合法的,但是它相当于使用Private
来声明它们:没有使用Dim
关键字声明的variables将永远是公共可访问的 – 我的build议是对本地使用Dim
,并使用Private
/ Public
作为模块variables。
当你在一个标准模块 (而不是一个类模块 )中声明Public
variables时,你可以从项目中的任何地方有效地声明全局variables – 每个variables都可以读取和写入 。 如果这听起来是个好主意,请花时间研究一下“全球变数的优缺点” – 不pipe语言如何,它们通常都是一种灾难。 你希望你的variables只能被特定的代码写出来,而你希望variables的范围尽可能地受限制。
学习如何将parameter passing给您的过程。
你正在发现标准模块和类之间的区别:几乎你周围的一切( Application
, Range
, Sheet1
等)是一个对象 。 对象是某个类 ( Excel.Application
, Excel.Range
, Excel.Worksheet
等)的实例,每个实例都封装自己的状态。
标准模块非常适合macros的入口点,对于封装来说不是很好 – 封装是面向对象编程(OOP)的基本支柱之一。