谁能找到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只是忽略分配新的错误处理程序的尝试。当错误处理程序处于活动状态时,任何其他错误将被取消处理。
退出活动错误处理程序的唯一方法是:
-
Resume
-
Resume Next
-
Resume <label>
-
On error goto -1
- 退出程序
使用以下任何一种方式退出错误处理程序也会清除错误对象。
优秀的来源:皮尔逊错误处理在VBA芯片皮尔逊没有提到On error goto -1
在他的文章。引用他的话:
我故意没有包括On Error GoTo -1,因为它没有服务除非使用,否则会锁定整个Excel应用程序以完全正确的方式。是的,在错误上go -1是语法上的有道理,但这就像把枪给了一个醉酒的少年。没有什么好
你也可以内联处理错误而不使用错误处理程序,使用错误对象:MSDN内联错误处理
重要的是要认识到,当VBA中出现错误时,有两种不同的情况发生。
-
错误对象设置了它的属性(即err。数字,错误,描述,错误。源等)
-
下一行要执行的更改
执行哪一行由最后执行的"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页面并没有真正给出如何使用错误处理的完整示例。