变量
范围
可以声明变量(增加可见性级别):
- 在程序级别,在任何程序中使用
Dim
关键字; 一个局部变量。 - 在模块级别,在任何类型的模块中使用
Private
关键字; 一个私人领域。 - 在实例级别,在任何类型的类模块中使用
Friend
关键字; 一个朋友的领域。 - 在实例级别,在任何类型的类模块中使用
Public
关键字; 一个公共领域。 - 在全局范围内,在标准模块中使用
Public
关键字 ; 一个全局变量。
应始终使用尽可能小的范围声明变量:首选将参数传递给过程,而不是声明全局变量。
有关更多信息,请参阅访问修饰符 。
局部变量
使用 Dim
关键字声明一个局部变量 :
Dim identifierName [As Type][, identifierName [As Type], ...]
声明语法的 [As Type]
部分是可选的。指定时,它设置变量的数据类型,该类型确定将为该变量分配多少内存。这声明了一个 String
变量:
Dim identifierName As String
如果未指定类型,则类型隐式为 Variant
:
Dim identifierName 'As Variant is implicit
VBA 语法还支持在单个语句中声明多个变量:
Dim someString As String, someVariant, someValue As Long
请注意,必须为每个变量指定 [As Type]
(除了’Variant’之外)。这是一个相对常见的陷阱:
Dim integer1, integer2, integer3 As Integer 'Only integer3 is an Integer.
'The rest are Variant.
静态变量
局部变量也可以是 Static
。在 VBA 中,Static
关键字用于使变量记住它具有的值,上次调用过程时:
Private Sub DoSomething()
Static values As Collection
If values Is Nothing Then
Set values = New Collection
values.Add "foo"
values.Add "bar"
End If
DoSomethingElse values
End Sub
这里的 values
系列被声明为 Static
local; 因为它是一个对象变量,它被初始化为 Nothing
。声明后面的条件验证对象引用之前是否为 Set
- 如果它是第一次运行该过程,则集合将被初始化。DoSomethingElse
可能正在添加或删除项目,并且下次调用 DoSomething
时它们仍然会在集合中。
替代
VBA 的
Static
关键字很容易被误解 - 特别是经常使用其他语言的经验丰富的程序员。在许多语言中,static
用于使类成员(字段,属性,方法,…)属于类型而不是实例。static
上下文中的代码不能引用实例上下文中的代码。VBAStatic
关键字意味着完全不同的东西。
通常,Static
本地也可以作为 Private
,模块级变量(字段)实现 - 但是这挑战了应该以尽可能小的范围声明变量的原则; 相信你的直觉,使用你喜欢的任何一个 - 两者都会起作用……但是使用 Static
而不了解它的作用可能会导致有趣的错误。
昏暗与私人
Dim
关键字在程序和模块级别是合法的; 它在模块级别的使用等同于使用 Private
关键字:
Option Explicit
Dim privateField1 As Long 'same as Private privateField2 as Long
Private privateField2 As Long 'same as Dim privateField2 as Long
Private
关键字仅在模块级别合法; 这邀请保留 Dim
用于局部变量并使用 Private
声明模块变量,特别是使用对比的 Public
关键字,无论如何必须使用它来声明公共成员。或者在任何地方使用 Dim
- 重要的是一致性 :
私人领域
- 请使用
Private
声明模块级变量。 - 请使用
Dim
声明一个局部变量。 - 请勿使用
Dim
声明模块级变量。
无处不在
- 请使用
Dim
声明任何私人/本地。 - 请勿使用
Private
声明模块级变量。 - 避免声明
Public
字段。*
*一般来说,无论如何都应该避免宣称 Public
或 Global
字段。
字段
在模块级别的声明部分中,在模块级别声明的变量是一个字段。在标准模块中声明的 Public
字段是全局变量 :
Public PublicField As Long
可以从任何地方访问具有全局范围的变量,包括将引用其声明的项目的其他 VBA 项目。
要创建变量 global / public,但仅在项目中可见,请使用 Friend
修饰符:
Friend FriendField As Long
这在加载项中尤其有用,其中的意图是其他 VBA 项目引用加载项项目并且可以使用公共 API。
Friend FriendField As Long 'public within the project, aka for "friend" code
Public PublicField As Long 'public within and beyond the project
朋友字段在标准模块中不可用。
实例字段
在模块级声明的变量,在声明部分在一个类模块的主体的顶部(包括 ThisWorkbook
,ThisDocument
,Worksheet
,UserForm
和类模块 ),是一个实例字段 :只要有一个它只存在实例的上课。
'> Class1
Option Explicit
Public PublicField As Long
'> Module1
Option Explicit
Public Sub DoSomething()
'Class1.PublicField means nothing here
With New Class1
.PublicField = 42
End With
'Class1.PublicField means nothing here
End Sub
封装字段
实例数据通常保留为 Private
,并且被称为封装。可以使用 Property
程序公开私有字段。要公开公开私有变量而不给调用者提供写访问权,类模块(或标准模块)实现了 Property Get
成员:
Option Explicit
Private encapsulated As Long
Public Property Get SomeValue() As Long
SomeValue = encapsulated
End Property
Public Sub DoSomething()
encapsulated = 42
End Sub
类本身可以修改封装的值,但调用代码只能访问 Public
成员(如果调用者在同一个项目中,则访问 Friend
成员)。
允许调用者修改:
- 一个封装的值,一个模块暴露了
Property Let
成员。 - 封装对象引用,模块公开
Property Set
成员。