在VBA中使用全局变量

时间:2017-09-22 16:33:28

标签: excel vba

刚刚开始在过去一周内使用VBA,我正在玩Sheets vs. Modules并定义变量。这是我目前的代码:

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(第2子程序):

Public Sub test()

If writtenvoe = True Then Sheet1.[N37] = "Yes" Else Sheet1.[N37] = "No"

End Sub

我注意到在这种当前格式中,Sub ImpDocs工作正常并且变量确定正确,但Sub测试总是​​返回false。但是,如果我将所有代码放入模块1中,则每个代码都按预期工作。看起来只有Sub测试会因在Sheet1和Module1中声明变量而受到影响。真的吗?如果是这样,为什么?

谢谢。

2 个答案:

答案 0 :(得分:4)

Sheet1Worksheet个对象,实例。因此,即使您在Public上声明所有内容Sheet1,如果没有先访问实例,您将无法访问它们。

Dim用于声明本地变量。它在模块级别也是合法的,但它相当于使用Private来声明它们:使用Dim关键字声明的变量不会公开访问 - 我的建议是使用{{1对于本地人,并使用Dim / Private作为模块变量。

当您在标准模块(而不是类模块)中声明Public变量时,您实际上是在声明 global 变量 - 每个都可以从读取和写入访问来自项目中的 。如果这听起来是个好主意,请花时间研究“全局变量的利弊” - 无论语言如何,它们通常都是灾难的秘诀。您希望变量仅由特定代码编写,并且您希望变量的范围尽可能受限制。

了解如何将参数传递给您的程序。

您正在发现标准模块和类之间的区别:您周围的所有内容(PublicApplicationRange等)都是对象。对象是某个Sheet1Excel.ApplicationExcel.Range等的实例,并且每个实例封装自己的状态。

标准模块非常适合宏入口点,对于封装来说并不是那么好 - 封装是面向对象编程(OOP)的基本支柱之一。 / p>

答案 1 :(得分:3)

这是关于VBA如何执行其命名空间(https://en.wikipedia.org/wiki/Namespace)的一个怪癖。回到Sheet1,您需要让writtenvoe成为Sheet1的Public成员:

Public writtenvoe As Boolean

然后,回到Module1,每当您想要writtenvoe Sheet1时,您必须指定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并创建了Module1.writtenvoe,从而轻松制作了一些内容可通过Module1访问。模块的命名空间非常宽松,因此模块内部声明Public的任何地方都可以在任何地方使用 - 另一个模块,任何工作表,任何类模块等。