You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动