“错误转到0”和“错误转到-1”之间的区别 – VBA

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

On Error GoTo 0禁用当前在过程中出现的任何错误陷阱。

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

例如:On Error GoTo -1

第一个错误提出后,它将GoTo ErrorFound ,然后将清除例程的error handling,并设置一个新的,这将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 

例如:On Error GoTo 0

发生第一个错误后,您将收到错误,因为error handling已被禁用。

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

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

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

error handling程序通过使用On Error Goto <label>变成启用状态。 发生错误时变为活动状态。

当error handling程序处于活动状态时 ,您不能分配新的error handling程序。 On Error Goto <label>将不起作用。 VBA简单地忽略分配新error handling程序的尝试。

使用Err.Clear不会取消error handling程序。

使用Goto <label>到代码中的不同位置不会取消error handling程序。 在error handling块中使用Goto <label>可能会引起混淆,应该避免。 您可能会认为error handling程序在实际上仍处于活动状态时不再处于活动状态。

活动error handling程序的作用是不能分配新的error handling程序。 On Error Goto <label>将不起作用。 VBA简单地忽略分配新error handling程序的尝试。 error handling程序处于活动状态时,任何其他错误都将被处理。

退出活动error handling程序的唯一方法是:

  1. Resume
  2. Resume Next
  3. Resume <label>
  4. On error goto -1
  5. 退出程序

使用这些方法中的任何一种来退出error handling程序也将清除错误对象。

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

我故意没有包含On Error GoTo -1,因为它没有真正的用途,可以locking整个Excel应用程序,除非以完全正确的方式使用。 是的,On Error GoTo -1在句法上是有效的,但这就像给醉酒的less年枪。 没有什么好的来自它。

您也可以使用错误对象在不使用error handling程序的情况下内联处理错误: MSDN内联error handling

这是另一个

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

显示GoTo 0和GoTo -1之间的区别

意识到在VBA中发生错误时会发生两件不同的事情,这一点很重要。

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

  2. 下一行将被执行。
    执行哪一行是由执行的最后一个“On Error Goto”语句确定的(如果有的话)。

这些是独立的,但高度相关的主题,你会写有效的不同但交织在一起的代码来pipe理它们。

当任何错误发生或您使用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为非零值时,发生exception并且如果您尝试执行任何“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 

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

您也可以将错误对象设置为您喜欢使用的任何数字

Err.Raise数字:=,来源:=,说明:=

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

您可以使用类似的语句来控制接下来执行哪一行代码

在错误转到ALabelName在错误转到ANonZeroLineNumber和在错误转到0'这是一个特殊情况,因为它实际上说“当前范围内(通常是一个子或函数),如果发生错误的事件传递错误对象callback用当前子或函数的代码。

在VBA中处理错误是非常棘手的,尤其是MSDN页面并没有提供如何使用error handling的完整例子。