任何人都可以在VBA中找到'On error goto -1'和'on error goto 0'之间的区别?我试过谷歌和msdn,但我没有运气。
答案 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只是忽略了分配新错误处理程序的尝试。错误处理程序处于活动状态时,任何其他错误都将无法处理。
退出活动错误处理程序的唯一方法是:
Resume
Resume Next
Resume <label>
On error goto -1
使用这些方法中的任何一种来退出错误处理程序也将清除错误对象。
优秀来源: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)
答案 3 :(得分:-1)
重要的是要意识到在VBA中发生错误时会发生两种截然不同的事情。
错误对象设置了它的属性(即err.number,err.desciption,err.source等)
要执行的下一行发生变化 执行哪一行取决于最后执行的“On Error Goto”语句 - 如果有的话。
这些是独立但高度相关的主题,您将编写实际上不同但交织在一起的代码来管理它们。
当发生任何错误或您使用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页面并没有提供有关如何使用错误处理的完整示例。