文章背景: VBA中,变量的作用域,决定变量在哪里能被获取和使用。VBA中的过程和函数,与变量类似,也具有不同的作用域。
1 变量的作用域
1.1 过程作用域
1.2 模块作用域
1.3 工程作用域
1.4 全局作用域
1.5 作用域冲突
2 过程或函数的作用域
2.1 模块作用域
2.2 工程作用域
2.3 全局作用域
1 变量的作用域
根据变量的声明位置和声明方式,变量的作用域有以下四种:
(1)过程作用域
(2)模块作用域
(3)工程作用域
(4)全局作用域
1.1 过程作用域
在过程或函数内部声明的变量,只有在当前过程或函数内被使用。例如:
代码语言:javascript复制Sub Test()
Dim name As String
Dim age As Integer
name = "张三"
age = 35
End Sub
1.2 模块作用域
一个模块中,在任何一个过程和函数外面,使用关键词 Private
或 Dim
声明的变量,称之为模块变量,其作用域是当前模块。例如,
Dim guest As String
Sub Test()
Dim message As String
guest = "张三"
message = "你好"
MsgBox message & "!" & guest
End Sub
使用关键词 Private
或 Dim
声明的变量,都是模块变量,因此以下两种声明方式是等效的。
Dim guest As String
Private guest As String
1.3 工程作用域
Excel VBA 中,一个 Excel 工作簿是一个 VBA 工程。与之对应,工程作用域表示变量在当前工程中的模块、Excel 对象、用户窗体、类模块中均可以被使用。
工程级别变量,在所在模块顶部声明 Option Private Module
修饰语句前提下,在过程或函数外面,使用关键词 Public
声明的变量,其作用域是当前工程。例如,
Option Private Module
Public guest As String
Sub Test()
Dim message As String
guest = "张三"
message = "你好"
MsgBox message & "!" & guest
End Sub
1.4 全局作用域
全局作用域表示,全局变量在打开的任何一个工作簿都可以被使用。全局变量的声明方式与工程变量相似,不同点是不使用模块顶部的 Option Private Module
修饰语句。
Public guest As String
Sub Test()
Dim message As String
guest = "张三"
message = "你好"
MsgBox message & "!" & guest
End Sub
1.5 作用域冲突
代码语言:javascript复制Dim aa As Integer
Sub Test()
Dim aa As String
aa = "李四"
MsgBox aa
End Sub
以上例子中,两次声明 aa
变量,分别是模块变量和过程变量。根据就近原则,在过程内部使用时,将使用过程变量。
2 过程或函数的作用域
根据声明位置和方式,过程或函数有三种作用域:
(1)模块作用域
(2)工程作用域
(3)全局作用域
2.1 模块作用域
在模块中,使用 Private 关键词声明的过程或函数,具备模块作用域,只能在当前模块中使用。
代码语言:javascript复制Private Sub Test()
End Sub
2.2 工程作用域
在模块中,顶部声明 Option Private Module
修饰语句,并且直接声明或使用 Public 关键词声明的过程或函数,具备工程作用域,在当前工程的所有模块中使用。
Option Private Module
Sub Test1()
End Sub
Public Sub Test2()
End Sub
以上例子中,Test1 过程和 Test2 过程均具备工程作用域。由于直接声明和使用关键词 Public
是等效的,因此可以省略 Public
关键词。
2.3 全局作用域
在模块中,直接声明或使用 Public 关键词声明的过程或函数,具备全局作用域。例如,
代码语言:javascript复制Sub Test1()
End Sub
Public Sub Test2()
End Sub
以上例子中,Test1 过程和 Test2 过程均具备全局作用域,可以在打开的任何一个工作簿中使用。
此外,它们还能直接在工作簿宏列表中执行。
参考资料:
[1] VBA 变量作用域(https://www.lanrenexcel.com/vba-variable-scope/)
[2] VBA 过程或函数作用域(https://www.lanrenexcel.com/vba-procedure-scope/)