
缺省引用的原理
在阅读代码的过程中,总是可以看到类似的可执行代码:
Range("A1").Value = 87
有朋友就产生疑问了:VBA不是存在严格的层级关系吗?为何这里不指明工作簿和工作表,就直接使用Range对象了呢?
当代码中没有明确指定 Workbook 和 Worksheet 对象时,VBA解释器会默认使用以下对象来补全层级路径:
|
省略的对象 |
VBA 默认使用的对象 |
说明 |
|
Application |
当前Excel应用程序 |
几乎总是可以省略 |
|
Workbook |
ActiveWorkbook(活动工作簿) |
即当前屏幕上最前端、被激活的那个工作簿 |
|
Worksheet |
ActiveSheet(活动工作表) |
即当前活动工作簿中正在被选中的那个工作表 |
当我们写下 Range("A1").Value=87 时能够直接运行,是VBA为方便起见提供的“语法糖”,它默认依赖于当前的活动工作簿和活动工作表来补全层级关系,完整如下:
ActiveWorkbook.ActiveSheet.Range("A1").Value=87
对于编写快速的一次性脚本,这种方式很便捷。在录制宏或进行简单的自动化操作时,我们大部分操作都集中在当前的活动工作表和活动工作簿上。如果每一次代码都必须从 Application 开始完整地写明所有层级关系,代码会变得冗长和繁琐

改进建议
尽管以上简写很方便,但它也带来了不稳定性风险,设想一下这样一个场景:我们在代码运行过程中意外点击了另一个工作簿或另一个工作表,导致活动窗口发生改变(例如 ActiveSheet 变成了另一个工作表),那么代码就可能不会在期望的工作表上运行,执行出错
为了编写出健壮、可靠的VBA代码,编码时可以通过以下方式规避
2.1 使用完全限定引用
在关键的代码中,最好明确限定工作簿和工作表,形成完整的对象层级引用:
Workbooks("工作簿1.xlsm").Worksheets("Sheet1").Range("A1").Value = 87
或者:
Dim wb As WorkbookDim ws As WorksheetSet wb = Workbooks("工作簿1.xlsm")Set ws = wb.Worksheets("Sheet1")ws.Range("A1").Value = 87
2.2利用 ThisWorkbook 关键字
ThisWorkbook 特指当前正在运行这段VBA代码的工作簿。在绝大多数情况下,使用 ThisWorkbook 比依赖 ActiveWorkbook(当前被用户激活的工作簿,会变动) 要安全得多
所以代码还可以按照如下格式书写:
Dim ws As WorksheetSet ws = ThisWorkbook.Worksheets("Sheet1")ws.Range("A1").Value = 87

结束语
VBA的缺省引用机制是一把双刃剑:既让简单的单次操作变得非常方便,也会在复杂的自动化任务中埋下隐患
因此我们需要理解其背后“依赖活动对象”的逻辑,并根据实际场景选择简写还是完整的显式引用
公众号同时也在不间断地分享免费的编程案例,如果想学习更多的编程知识,无论是用来提升自动化办公效率还是想提升自我,都可以关注我的公众号“努力鸭是黑色的”,解锁更多的VBA技能

被折叠的 条评论
为什么被折叠?



