一 谁的作用范围?
不同对象的作用范围完全不是一回事,不要混淆
比如 sub 和 sub里的变量a 作用范围不是一回事
public sub sub1()
dim a
end sub
二 sub 和 function的作用范围
2.1 语法
- public sub sub_name()
- private sub sub_name()
- static sub sub_name()
2.2 默认值
- 默认是public sub
- 默认是public function
2.3 public sub 用法与注意点 (跨模块级---但一般不跨表)
- public sub sub_name()
- 针对工作簿内所有模块共用,可以在派生类和对象中直接调用
- 但不能跨表
- 特例:但是如果用在包含Option Private Module语句的模块中,则该过程只能用于所在工程中的其它过程。
-
SUB在如果是放在类中就是public.是公用过程
-
也可以放在类的外边,那么就只是一个普通的过程,任何对象都可以调用该过程
2.4 private sub 用法与注意点 (模块级)
- sub等肯定是大于一个过程的
- private 表示在只在一个模块内生效,不能跨模块
- Private Sub一般 在类中使用,用了private,该过程装无法在派生类及派生对象中直接调用
2.5 static sub 本质在于 声明了 内部变量 都是static变量
- static 定义本质不是定义的过程
- 过程本身并没有 static一说
- static 变量:过程结束后,变量值不释放 / 不重置,变量的值将被保持下来。只到脚本关闭才释放。
三 变量作用范围
3.1 原理
- 单个过程作用域:在一个过程中使用 dim 或 static 声明的变量,作用域为本过程,这样的变量称为本地变量
- 单个模块作用域: 在模块的第一个过程之前使用dim 或 private 声明的变量,作用域为声明变量的语句所在模块(这个脚本内)里同的所有过程, 这样的变量称为模块级变量
- 所有模块作用域: 即我上面提到的,在一个模块的第一个过程之前使用public声明的变量,作用域为所有模块这样的变量称为公共变量
类模块级(跨模块级,一般不跨表):
- public 类模块级,可以在这个 工作表/工程 外部调用
- friend 类模块级,但只是全局变量,只能在 工作表的工程内使用
模块级:必须写在 过程/函数 外的 声明关键字
- public 模块级,全局变量
- private 模块级
- dim 模块级(dim 是最特殊的!可能是 模块级 或 过程级)
过程级:必须写在 过程/函数 内的 声明关键字
- dim 过程级
- static 必定过程级
3.2 语法
dim a
如果定义在sub /function 内部 过程级变量
如果定义在模块的第一个过程之前, 模块级变量,可以在模块内通用
private a 模块级过程外,模块变量
public a 跨模块级过程,公共变量
static a 过程内,静态变量
public a,b 等全局声明
- 需要放在模块的开头
- 理论上可以放在任何位置定义(但不能定义在 for if 等结构体内)
- 生效范围是:整个工作簿,跨sheet,但不能跨workbook(不能跨表)
3.3 默认值
默认值 private
3.4 public 一般用法与注意点
- 原则是尽量都用局部变量 private
- 尽量少用 静态变量 static
3.5 private 一般用法与注意点
四 关于 static用法
- 除了static之外,其他变量,都只在 代码使用开始生产,代码sub结束就删除
- Static可以持续到 关闭工程前都生效。每次更新的值也可以被保留
- static跟dim是两种相对的赋值方式,动态变量程序结束后释放,静态变量workbook结束后释放
下面这个sub 执行多次,就可以看出 dim 和 static 变量的差别了
Sub test1()
Dim a As Byte
Static b As Byte
a = a + 1
b = b + 1
Debug.Print "a等于" & a
Debug.Print "b等于" & b
End Sub
五 参考
https://www.cnblogs.com/mq0036/p/4236266.html
http://club.excelhome.net/thread-98177-1-1.html
http://accesshome.5d6d.net/thread-3186-1-1.html
Static Sub m1()
Dim i As Integer
Dim j As Integer
i = i + 1
j = j + 1
Debug.Print "i=" & i & " j=" & j
End Sub
Private Sub m2()
Dim i As Integer
Dim j As Integer
i = i + 1
j = j + 1
Debug.Print "i=" & i & " j=" & j
End Sub
Sub try1()
Dim i As Integer
Debug.Print "静态过程:"
For i = 1 To 10
Call m1
Next i
Debug.Print "私有过程:"
For i = 1 To 10
Call m2
Next i
End Sub
EH的参考图(不是我画的)