Workbook_BeforeSave调用update_all_ranges报语法错误:原因及解决方法
VBA编译错误:调用无参数Sub过程的语法问题
问题回顾
你在Modules文件夹里写了两个VBA过程,其中update_all_ranges是无参数的Sub过程。直接在Workbook_BeforeSave事件里调用update_all_ranges()时触发了编译错误,但分开调用update_range ("range1")和update_range ("range2")却能正常运行。
你的代码片段:
' Modules中的代码 Sub update_range(namedRange As String) Dim rangeData As Range Dim startRow As Integer Set rangeData = ThisWorkbook.Names(namedRange).RefersToRange startRow = rangeData.Row Set rangeData = rangeData.CurrentRegion If rangeData.Row < startRow Then Dim extraTopRow As Integer extraTopRow = startRow - rangeData.Row Set rangeData = rangeData.Resize(rangeData.Rows.Count - extraTopRow) Set rangeData = rangeData.Offset(extraTopRow) End If rangeData.Name = namedRange End Sub Sub update_all_ranges() update_range ("range1") update_range ("range2") End Sub ' ThisWorkbook中出错的代码 Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) update_all_ranges() ' 这里触发编译错误 End Sub
错误原因
这是VBA的语法规则导致的典型问题:
- 当调用无参数的Sub过程时,直接加括号会违反语法逻辑。VBA会把带括号的调用理解为试图获取过程的返回值,但Sub过程本身没有返回值,因此直接触发编译错误。
- 你调用带参数的
update_range ("range1")能运行,是因为括号在这里是把字符串"range1"作为表达式传递(本质上是强制按值传递参数),这种写法虽然能运行,但其实标准的Sub调用应该是update_range "range1"(不带括号)。
修复方法
有两种简单的修复方式,推荐第一种更规范的写法:
- 直接去掉括号(最常用、符合VBA规范的写法):
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) update_all_ranges ' 去掉括号即可正常运行 End Sub
- 使用Call语句调用(如果习惯带括号的写法):
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) Call update_all_ranges() ' 用Call关键字包裹,带括号也能正常运行 End Sub
另外顺便提一句:调用带参数的Sub时,标准写法是不带括号的,比如update_range "range1",这样更符合VBA的语法规范,也能避免潜在的参数传递歧义。
内容的提问来源于stack exchange,提问作者Bear Bile Farming is Torture
相关产品推荐
相关产品推荐

