'on error goto 0'和'on error goto -1'之间的区别 - VBA

时间:2013-01-04 14:22:26

标签: excel vba msdn

任何人都可以在VBA中找到'On error goto -1'和'on error goto 0'之间的区别?我试过谷歌和msdn,但我没有运气。

4 个答案:

答案 0 :(得分:52)

On Error GoTo 0禁用过程中当前存在的任何错误捕获。

On Error GoTo -1清除错误处理并将其设置为空,允许您创建另一个错误陷阱。

示例:On Go GoTo -1

引发第一个错误后,GoTo ErrorFound将清除例程的错误处理并设置一个新错误,当发现错误时GoTo AnotherErrorFound

Sub OnErrorGotoMinusOneTest()

    On Error GoTo ErrorFound

    Err.Raise Number:=9999, Description:="Forced Error"

    Exit Sub

ErrorFound:

    On Error GoTo -1 'Clear the current error handling
    On Error GoTo AnotherErrorFound 'Set a new one
    Err.Raise Number:=10000, Description:="Another Forced Error"

AnotherErrorFound:

    'Code here

End Sub

示例:错误转到0

引发第一个错误后,您将收到错误,因为错误处理已被禁用。

Sub OnErrorGotoZeroTest()

    On Error GoTo 0

    Err.Raise Number:=9999, Description:="Forced Error"

End Sub

答案 1 :(得分:12)

这个答案解决了错误对象和错误处理程序之间的混淆。

可以使用Err.Clear清除错误对象。这不会影响错误处理程序。

使用On Error Goto <label>启用错误处理程序。它在发生错误时变为活动状态。

错误处理程序活动时,您无法分配新的错误处理程序。 On Error Goto <label>无效。 VBA只是忽略了分配新错误处理程序的尝试。

使用Err.Clear不会取消错误处理程序。

使用Goto <label>跳转到代码中的其他位置不会取消错误处理程序。在错误处理块中使用Goto <label>会导致混淆,应该避免。您可能认为错误处理程序不再处于活动状态,实际上它仍处于活动状态。

主动错误处理程序的作用是您无法分配新的错误处理程序。 On Error Goto <label>无效。 VBA只是忽略了分配新错误处理程序的尝试。错误处理程序处于活动状态时,任何其他错误都将无法处理。

退出活动错误处理程序的唯一方法是:

  1. Resume
  2. Resume Next
  3. Resume <label>
  4. On error goto -1
  5. 退出程序
  6. 使用这些方法中的任何一种来退出错误处理程序也将清除错误对象。

    优秀来源:Pearson Error Handling In VBA Chip Pearson在他的文章中没有提到On error goto -1。引用他:

      

    我故意不包括On Error GoTo -1,因为它没有   除非使用,否则可以锁定整个Excel应用程序   以完全正确的方式。是的,On Error GoTo -1是语法上的   有效,但这就像给醉酒的少年枪。没什么好的   将来自它。

    您还可以使用错误对象而不使用错误处理程序来处理内联错误:MSDN Inline Error Handling

答案 2 :(得分:2)

这是另一个

http://www.excelfox.com/forum/f23/error-goto-1-a-894/

更多地了解GoTo 0和GoTo -1

之间的区别

答案 3 :(得分:-1)

重要的是要意识到在VBA中发生错误时会发生两种截然不同的事情。

  1. 错误对象设置了它的属性(即err.number,err.desciption,err.source等)

  2. 要执行的下一行发生变化 执行哪一行取决于最后执行的“On Error Goto”语句 - 如果有的话。

  3. 这些是独立但高度相关的主题,您将编写实际上不同但交织在一起的代码来管理它们。

    当发生任何错误或您使用Err.Raise时,始终设置Err对象。即使已使用“On Error Resmue next”或任何其他On错误语句。

    所以这样的代码总是可以使用:

    Dim i as integer 
    On error resume next 
    i = 100/0  ' raises error
    if err.number <> 0 then 
       ' respond to the error
    end if
    

    非常重要的是要意识到当错误对象的err.number值为非零时,会引发异常,如果您尝试执行任何“On Error Goto”语句,则会引发错误,执行将传递给任何调用当前过程的代码。 (或者任何代码都没有调用通常的VBA错误对话)。请注意,在这种情况下,“On Error Goto ALabel1”不会将下一行更改为Label1:就行。

    例如

    Sub ErrorTest()
    
        Dim dblValue        As Double
    
        On Error GoTo ErrHandler1
        dblValue = 1 / 0
    
    ErrHandler1:
        debug.print "Exception Caught"
        debug.print Err.Number
    
        On Error GoTo ALabel1
        dblValue = 1 / 0
    
    Exit sub
    ALabel1:
        debug.print "Again caught it."
    
    End Sub
    

    一旦err.number属性设置为非零,您可以使用

    将其重置为零
    On Error Goto -1 
    

    请注意,Err.Clear也会将其重置为零,但它实际上相当于:

    On Error Goto -1 
    On Error Goto 0
    

    即Err.Clear删除当前存在的“On Error Goto”。所以最好最好使用:

    On Error Goto -1   
    

    使用Err.clear你经常需要写

    Err.Clear
    On Error Goto MyErrorHandlerLabel
    

    值得注意的是,只要执行任何类型的Resume语句,Exit Sub,Exit Function,Exit Property或任何On Error语句,Err.Clear就会由VBA隐式执行。

    您还可以使用

    将错误对象设置为您喜欢的任何数字

    Err.Raise Number:=,来源:=,说明:=

    Err.Raise非常重要,因为它允许您将错误传播到调用程序并提出您自己的错误编号,称为“用户定义的错误”,它提供了一种方法来告诉调用程序它无法继续执行逻辑原因。 (例如,商业规则被打破)。

    您可以使用

    之类的语句控制接下来要执行的代码行

    On Error Goto ALabelName 出错时转到ANonZeroLineNumber 和 On Error Goto 0'这是一种特殊情况,因为它实际上表示“在当前范围内(通常是子或函数),如果发生错误,则将错误对象传递回调用当前子函数或函数的代码

    VBA中的错误处理很棘手,尤其是因为MSDN页面并没有提供有关如何使用错误处理的完整示例。