刚刚开始在过去一周内使用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中声明变量而受到影响。真的吗?如果是这样,为什么?
谢谢。
答案 0 :(得分:4)
Sheet1
是Worksheet
个对象,类的实例。因此,即使您在Public
上声明所有内容Sheet1
,如果没有先访问实例,您将无法访问它们。
Dim
用于声明本地变量。它在模块级别也是合法的,但它相当于使用Private
来声明它们:使用Dim
关键字声明的变量不会公开访问 - 我的建议是使用{{1对于本地人,并使用Dim
/ Private
作为模块变量。
当您在标准模块(而不是类模块)中声明Public
变量时,您实际上是在声明 global 变量 - 每个都可以从读取和写入访问来自项目中的 。如果这听起来是个好主意,请花时间研究“全局变量的利弊” - 无论语言如何,它们通常都是灾难的秘诀。您希望变量仅由特定代码编写,并且您希望变量的范围尽可能受限制。
了解如何将参数传递给您的程序。
您正在发现标准模块和类之间的区别:您周围的所有内容(Public
,Application
,Range
等)都是对象。对象是某个类(Sheet1
,Excel.Application
,Excel.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
的任何地方都可以在任何地方使用 - 另一个模块,任何工作表,任何类模块等。