“on error goto 0”和“on error goto -1”之间的区别——VBA

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14158901/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 14:40:51  来源:igfitidea点击:

Difference between 'on error goto 0' and 'on error goto -1' -- VBA

excelvbamsdn

提问by sterlingalston

Can anyone find the difference between 'On error goto -1' and 'on error goto 0' in VBA? I've tried google and msdn, but I've had no luck.

任何人都可以在 VBA 中找到“错误转到 -1”和“错误转到 0”之间的区别吗?我试过谷歌和 msdn,但我没有运气。

回答by Francis Dean

On Error GoTo 0disables any error trapping currently present in the procedure.

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

On Error GoTo -1clears the error handling and sets it to nothing which allows you to create another error trap.

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

Example: On Error GoTo -1

示例:出错时转到 -1

After the first error is raised, it will GoTo ErrorFoundwhich will then clear the routine's error handling and set a new one, which will GoTo AnotherErrorFoundwhen an error is found.

在出现第一个错误后,它将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

Example: On Error GoTo 0

示例:出错时转到 0

After the first error is raised, you will receive the error as error handling has been disabled.

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

Sub OnErrorGotoZeroTest()

    On Error GoTo 0

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

End Sub

回答by D_Bester

This answer addresses the confusion between the error object and the error handler.

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

The error objectcan be cleared using Err.Clear. This does not affect the error handler.

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

The error handlerbecomes enabled by using On Error Goto <label>. It becomes active when an error occurs.

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

While the error handler is active, you can not assign a new error handler. On Error Goto <label>will have no effect. VBA simply ignores the attempt to assign a new error handler.

当错误处理程序处于活动状态时,您不能分配新的错误处理程序。On Error Goto <label>不会有任何影响。VBA 只是忽略分配新错误处理程序的尝试。

Using Err.Cleardoes not cancel the error handler.

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

Jumping to a different place in the code using Goto <label>does not cancel the error handler. Using Goto <label>in an error handling block can cause confusion and should be avoided. You might think the error handler is no longer active when in fact it is still active.

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

The effect of an active error handler is that you can not assign a new error handler. On Error Goto <label>will have no effect. VBA simply ignores the attempt to assign a new error handler. Any additional errors will be unhandled while the error handler is active.

活动错误处理程序的效果是您不能分配新的错误处理程序。On Error Goto <label>不会有任何影响。VBA 只是忽略分配新错误处理程序的尝试。当错误处理程序处于活动状态时,将不会处理任何其他错误。

The only way to exit an active error handler is:

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

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

Using any one of these ways to exit the error handler will also clear the error object.

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

Excellent source: Pearson Error Handling In VBAChip Pearson doesn't mention On error goto -1in his article. To quote him:

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

I deliberately did not include On Error GoTo -1 because it serves no real purpose and can lock up the entire Excel application unless used in exactly the right way. Yes, On Error GoTo -1 is syntactically valid, but it is like giving a gun to drunk teenager. Nothing good will come from it.

我故意不包括 On Error GoTo -1 因为它没有真正的用途并且可以锁定整个 Excel 应用程序,除非以完全正确的方式使用。是的, On Error GoTo -1 在语法上是有效的,但这就像给醉酒的少年一把枪。它不会带来任何好处。

You can also handle errors inline without using an error handler using the error object: MSDN Inline Error Handling

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

回答by HarveyFrench

It is important to realise there are two distinct things that happen when an error occurs in VBA.

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

  1. The error object has it's properties set (ie err.number, err.desciption, err.source etc)

  2. The next line to be executed changes.
    Which line is executed is determined by the last "On Error Goto" statement that was executed - if any.

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

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

These are separate but highly related topics and you will write what is in effect distinct but interwoven code to manage them both.

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

When ANY error occurs or you use Err.Raise the Err object is ALWAYS set up. Even if "On Error Resmue next" or any other On error statement has been used.

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

So code like this could ALWAYS be used:

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

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

It is really important to realise that when the error object has a non zero value for err.number an exception has been raised AND that if you then try and execute any "On Error Goto " statement doing so will raise an error and execution will be passed to any code that called the current procedure. (or where not called by any code the usual VBA error dialogue is given). Note that in this scenario "On Error Goto ALabel1" would NOT change the next line to be the line with Label1: on it.

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

eg

例如

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

Once the err.number property is set to non zero, you can reset it to zero by using

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

On Error Goto -1 

Note that Err.Clear also resets it to zero but it is actually equivalent to:

请注意, Err.Clear 也将其重置为零,但实际上等效于:

On Error Goto -1 
On Error Goto 0

ie Err.Clear removes an "On Error Goto" that is currently in place. So therefore it is mostly best to use:

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

On Error Goto -1   

as using Err.clear You would often need to write

使用 Err.clear 你经常需要写

Err.Clear
On Error Goto MyErrorHandlerLabel

It is worth noting that Err.Clear is implicitly carried out by VBA whenever it executes any type of Resume statement, Exit Sub, Exit Function, Exit Property, or any On Error statement.

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

You can also set the error object it to whatever number you like using

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

Err.Raise Number:=, Source:=, Description:=

Err.Raise Number:=, Source:=, Description:=

Err.Raise is very important as it allows you to propagate an error to the calling program AND raise your own error numbers known as "user defined errors" that provide a means of telling the calling program that it could not continue for a logical reason. (eg a business rule was broken).

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

You can control which line of code is executed next using statements like

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

On Error Goto ALabelName On Error Goto ANonZeroLineNumber and On Error Goto 0 ' This is a special case as it in effect says "within the current scope (typically a sub or function), in the event that an error happens pass the error object back to the code that called the current sub or function.

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

Error handling in VBA is tricky, especially as the MSDN pages do not really give complete examples of how error handling can be used.

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