'的差异在错误goto 0'和'在错误时goto -1'——VBA

  • 本文关键字:goto 错误 VBA excel vba msdn
  • 更新时间 :
  • 英文 :


谁能找到VBA中'On error goto -1'和'On error goto 0'之间的差异?我试过google和msdn,但都没有成功。

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

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

示例:出错时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

示例:在出错时GoTo 0

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

Sub OnErrorGotoZeroTest()
    On Error GoTo 0
    Err.Raise Number:=9999, Description:="Forced Error"
End Sub

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

错误对象可以使用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. 退出程序

使用以下任何一种方式退出错误处理程序也会清除错误对象。

优秀的来源:皮尔逊错误处理在VBA芯片皮尔逊没有提到On error goto -1在他的文章。引用他的话:

我故意没有包括On Error GoTo -1,因为它没有服务除非使用,否则会锁定整个Excel应用程序以完全正确的方式。是的,在错误上go -1是语法上的有道理,但这就像把枪给了一个醉酒的少年。没有什么好

你也可以内联处理错误而不使用错误处理程序,使用错误对象:MSDN内联错误处理

重要的是要认识到,当VBA中出现错误时,有两种不同的情况发生。

  1. 错误对象设置了它的属性(即err。数字,错误,描述,错误。源等)

  2. 下一行要执行的更改
    执行哪一行由最后执行的"On Error Goto"语句决定——如果有的话。

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

当出现任何错误或使用Err时。引发Err对象总是被设置。即使使用了"On Error restore next"或任何其他On Error语句。

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

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值为非零时,认识到这一点非常重要。如果你尝试执行任何"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

一旦出错。Number属性设置为非零,可以使用

将其重置为零
On Error Goto -1 

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

On Error Goto -1 
On Error Goto 0

ie犯错。清除删除一个"On Error Goto",目前在适当的地方。因此,最好使用:

On Error Goto -1   

表示使用Err。你经常需要写

Err.Clear
On Error Goto MyErrorHandlerLabel

值得注意的是Err。当VBA执行任何类型的Resume语句、Exit Sub语句、Exit Function语句、Exit Property语句或任何On Error语句时,都会隐式执行Clear。

你也可以使用

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

犯错。Raise Number:=, Source:=, Description:=

犯错。Raise非常重要,因为它允许您将错误传播给调用程序,并引发您自己的错误编号,称为"用户定义错误",它提供了一种告诉调用程序由于逻辑原因无法继续的方法。(如业务规则被打破)。

您可以使用像

这样的语句来控制接下来执行的代码行

On Error to ALabelName错误时,转到ANonZeroLineNumber和这是一种特殊情况,因为它实际上表示"在当前作用域中(通常是子对象或函数),如果发生错误,将错误对象传递回调用当前子对象或函数的代码。

VBA中的错误处理很棘手,特别是MSDN页面并没有真正给出如何使用错误处理的完整示例。

最新更新