Resume跳转标签异常求助:为何触发Error 20错误?
你碰到的Error 20(Resume without error)其实是个典型的VBA错误处理规则误用问题,核心原因是Resume语句的使用场景不对——Resume只能配合On Error GoTo [标签]的错误处理例程使用,绝对不能在On Error Resume Next的“忽略错误继续执行”模式下直接调用。
为什么你的代码会触发Error 20?
看你的测试代码,你用On Error Resume Next捕获重命名工作表的错误,当Err.Number等于1004(工作表名称重复)时,你调用了Resume NameAgain。但VBA里,Resume是专门用于从错误处理块(也就是On Error GoTo跳转过去的代码块)中恢复执行的语句,而你的代码并没有进入这种错误处理上下文——你只是用了On Error Resume Next让程序跳过错误继续跑,此时调用Resume就相当于告诉VBA“从错误中恢复”,但VBA认为当前根本没有在处理错误(因为没进入错误处理块),所以直接抛出Error 20。
哪怕此时Err.Number显示有1004错误,也改变不了这个规则:Resume的使用必须在On Error GoTo触发的错误处理块里,否则就是非法调用。
你的解决方案为什么有效?
你调整后的方案(把On Error Resume Next移到标签行,用GoTo替代Resume)刚好避开了这个坑:
- 把
On Error Resume Next放到NameAgain标签下,每次重试前都会重新启用错误捕获,确保每次重命名操作的错误都能被正确捕获; - 用
GoTo NameAgain替代Resume,GoTo只是单纯的代码跳转,不涉及VBA的错误处理上下文恢复逻辑,自然不会触发Error 20。
这里还可以优化一下,加上Err.Clear手动清除错误状态,避免上次的错误残留影响后续判断:
'激活CheckBook以使用ActiveWindow CheckBook.Activate Set DestSheet = CheckBook.Worksheets.Add(After:=CheckBook.Sheets(1)) v = 1 NameAgain: On Error Resume Next DestSheet.Name = ExpBookName & "_" & v If Err.Number = 1004 Then v = v + 1 Err.Clear ' 重置Err对象,避免残留错误干扰 GoTo NameAgain End If On Error GoTo 0 ActiveWindow.DisplayGridlines = False Set DestCell = DestSheet.Range("A2")
另一种更规范的写法(用On Error GoTo)
如果你想遵循VBA错误处理的标准规范,也可以用On Error GoTo的模式,这种写法逻辑更清晰,Resume的使用也完全合法:
'激活CheckBook以使用ActiveWindow CheckBook.Activate Set DestSheet = CheckBook.Worksheets.Add(After:=CheckBook.Sheets(1)) v = 1 NameAgain: On Error GoTo NameErrorHandler ' 启用错误捕获,跳转到处理块 DestSheet.Name = ExpBookName & "_" & v On Error GoTo 0 ' 关闭错误捕获,恢复正常错误提示 ' 后续正常执行的代码 ActiveWindow.DisplayGridlines = False Set DestCell = DestSheet.Range("A2") Exit Sub ' 必须退出,不然会跑到错误处理块里 ' 错误处理块 NameErrorHandler: If Err.Number = 1004 Then v = v + 1 Resume NameAgain ' 这里用Resume合法,因为处于错误处理上下文 Else ' 处理其他未知错误 MsgBox "发生未预期错误:" & Err.Description Err.Clear Exit Sub End If
这种写法里,Resume是在错误处理块NameErrorHandler中调用的,完全符合VBA的规则,不会出现Error 20的问题。
内容的提问来源于stack exchange,提问作者Mackanachi




