在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 ,每次需要Sheet1writtenvoe时,都必须指定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 

当您将writtenvoeSheet1移动到Module1 ,您已经有效地移除了Sheet1.writtenvoe并创build了Module1.writtenvoe ,从而使得Module1可以轻松访问这些内容。 模块的命名空间是非常宽容的,所以任何在模块中声明为Public东西在任何地方都是可用的 – 另一个模块,任何表单,任何类模块等等。

Sheet1是一个Worksheet对象,一个实例 。 因此,即使您在Sheet1上声明了一切Public内容,也不Sheet1访问该实例即可访问它们。

Dim用于声明局部variables。 它在模块级也是合法的,但是它相当于使用Private来声明它们:没有使用Dim关键字声明的variables将永远是公共可访问的 – 我的build议是对本地使用Dim ,并使用Private / Public作为模块variables。

当你在一个标准模块 (而不是一个类模块 )中声明Publicvariables时,你可以从项目中的任何地方有效地声明全局variables – 每个variables都可以读取和写入 。 如果这听起来是个好主意,请花时间研究一下“全球变数的优缺点” – 不pipe语言如何,它们通常都是一种灾难。 你希望你的variables只能被特定的代码写出来,而你希望variables的范围尽可能地受限制。

学习如何将parameter passing给您的过程。

你正在发现标准模块和类之间的区别:几乎你周围的一切( ApplicationRangeSheet1等)是一个对象 。 对象是某个Excel.ApplicationExcel.RangeExcel.Worksheet等)的实例,每个实例都封装自己的状态。

标准模块非常适合macros的入口点,对于封装来说不是很好 – 封装是面向对象编程(OOP)的基本支柱之一。