分享

【VBA】on error

 忙个不停的闲人 2022-06-28 发布于四川

  VBA的错误监听和处理语句有四种

  • On Error GoTo line_handle :当错误发生时,会立刻跳转到line行去

  • On Error Resume Next:当错误发生时,顺序执行错误语句的下一行代码

  • On Error GoTo 0:停止行在出现错误的行并错误消息

  • On Error GoTo -1:清除当前错误

先来看第一种,这是使用最频繁的错误处理方式:

On Error GoTo line_handle

Sub errortest1()

    On Error GoTo error_handle    
    Debug.Print 1 / 0
  Debug.Print "no error happend"
    Exit Sub
    
error_handle:
    Debug.Print "Err.Number:"; Err.Number
    Debug.Print "Err.Description:"; Err.Description

End Sub

当错误发生时,跳转到“error_handle”标签定义的行,这种错误处理方式通常结合exit语句一起使用,注意:如果没有“Exit sub”语句,即使执行完全正确,也会执行“error_handle”代码块,感兴趣的朋友可以将”1/0“换成”1/2“试试

运行结果:

再看第二种,第二种常用于对象的空值判定

On Error Resume Next

Sub errortest2()

    Dim arr() As String
    On Error Resume Next
    Dim lb: lb = LBound(arr)
    Debug.Print "Err.Number:"; Err.Number
    Debug.Print "Err.Description:"; Err.Description
    
End Sub

当错误发生时,不终止代码,不弹出错误信息,顺序执行错误代码行的下一行。常用于空数组判定、空对象判定、对象是否存在判定,如:https://blog.csdn.net/taller_2000/article/details/123949335

运行结果:

接着看第三种

On Error GoTo 0

第三种是vba默认的错误处理方式:发生错误时,立即终止代码运行,并用对话框显示错误信息,不好理解的话看下面两个例子

Sub errortest7()

    Debug.Print 1 / 0
    Debug.Print "Err.Number:"; Err.Number
    Debug.Print "Err.Description:"; Err.Description

End Sub

Sub errortest6()

    On Error GoTo 0
    Debug.Print 1 / 0
    Debug.Print "Err.Number:"; Err.Number
    Debug.Print "Err.Description:"; Err.Description

End Sub

这两个过程的运行结果是一样的,如下图所示:

  更简单来说:”On Error GoTo 0“写不写都一样。

第四种

On Error GoTo -1

我们同样先上代码

Sub errortest8()

    On Error GoTo error_handle1
    Debug.Print 1 / 0
    Exit Sub
    
error_handle1:
    Debug.Print "error_handle1:"; "Err.Number:"; Err.Number
    Debug.Print "error_handle1:"; "Err.Description:"; Err.Description
    
    On Error GoTo error_handle2
    Debug.Print 1 / 0
    Exit Sub
    
error_handle2:
    Debug.Print "error_handle2:"; "Err.Number:"; Err.Number
    Debug.Print "error_handle2:"; "Err.Description:"; Err.Description
    
    On Error GoTo error_handle3
    Debug.Print 1 / 0
    Exit Sub
    
error_handle3:
    Debug.Print "error_handle3:"; "Err.Number:"; Err.Number
    Debug.Print "error_handle3:"; "Err.Description:"; Err.Description

End Sub


Sub errortest9()

    On Error GoTo error_handle1
    Debug.Print 1 / 0
    Exit Sub
    
error_handle1:
    Debug.Print "error_handle1:"; "Err.Number:"; Err.Number
    Debug.Print "error_handle1:"; "Err.Description:"; Err.Description
    
    On Error GoTo -1
    On Error GoTo error_handle2
    Debug.Print 1 / 0
    Exit Sub
    
error_handle2:
    Debug.Print "error_handle2:"; "Err.Number:"; Err.Number
    Debug.Print "error_handle2:"; "Err.Description:"; Err.Description
    
    On Error GoTo -1
    On Error GoTo error_handle3
    Debug.Print 1 / 0
    Exit Sub
    
error_handle3:
    Debug.Print "error_handle3:"; "Err.Number:"; Err.Number
    Debug.Print "error_handle3:"; "Err.Description:"; Err.Description

End Sub

过程8运行结果:

过程9运行结果:

这种区别是由vba的错误监听机制导致的,在vba中,如果连续发生两次错误,且第一次错误未清除,那么对第二次错误的监听无效。

这个机制导致了“Sub errortest8()”中的“On Error GoTo error_handle2”、“On Error GoTo error_handle3”这两语句无效,无效的情况下发生错误,执行的是vba的默认错误处理方法,即第三种,终止代码,弹出错误信息。

怎么解决呢?在后续的错误监听前添加代码“On Error GoTo -1”,清除当前的错误信息,参考“Sub errortest9()”

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多