为什么你会使用“On Error Goto 0”?

时间:2012-04-02 20:37:20

标签: vb6 error-handling

为什么要在VB6应用中使用"On Error Goto 0"

此语句将关闭错误处理程序,并表示任何错误都会导致应用程序崩溃。为什么这会成为可取的?

5 个答案:

答案 0 :(得分:48)

在VB6中,您可以指定您希望稍后在例程中由特定代码处理错误:

Sub Bar()
    On Error Goto MyHandler
    ...
    ...some code that throws an error...
    ...
    Exit Sub
MyHandler:
    ...some error handler code (maybe pops up a dialog)
End Sub
但是,可能是这样的情况,抛出错误的代码是本地化的,并且您不希望对例程中的所有其余代码使用相同的处理程序。在这种情况下,您将使用“On Error Goto 0”,如下所示:

Sub Bar()
    ...
    On Error Goto MyHandler
    ...some code that throws an error...
    On Error Goto 0
    ...
    ...
    Exit Sub
MyHandler:
    ...some error handler code (maybe pops up a dialog)
End Sub

现在,只有在特定代码行失败时,您才能有效地确定错误处理的范围。

通过调用“On Error Goto 0”,您并不是说您希望应用立即崩溃。您只是说要取消注册您在例程中先前设置的任何错误处理程序;错误将在调用堆栈中传递给调用例程,就像正常情况一样。

答案 1 :(得分:8)

由于用文字描述似乎很笨拙,这里有一些例子说明你可以使用On Error GoTo 0进行本地化的结构化错误处理。

第一个是类(“MicroDOM”)中的Property Get,它基于子类集合的层次结构实现轻量级DOM。在这种情况下,我们希望尝试通过名称而不是索引来引用缺少的Child来创建一个空(没有attrbutes或子)Child:

Public Property Get Child(ByVal Key As Variant) As MicroDOM
    If mChildren Is Nothing Then
        Set mChildren = New Collection
    End If
    On Error Resume Next
    Set Child = mChildren(Key)
    If Err Then
        On Error GoTo 0
        If VarType(Key) = vbString Then
            Key = Trim$(Key)
            Set Child = New MicroDOM
            Child.Key = Key
            mChildren.Add Child, Key
        Else
            Err.Raise 9 'Subscript error as thrown by the Collection.
        End If
    End If
End Property

第二个是内联代码,如果文件存在,则删除文件:

On Error Resume Next
Kill strFilePath
On Error GoTo 0

第三个是内联代码,仅在文件恰好存在时才执行操作:

On Error Resume Next
GetAttr strFilePath
If Err Then
    On Error GoTo 0
    ProcessTheData strFilePath
End If
On Error GoTo 0

虽然对于没有经验的人(在两个地方执行On Error GoTo 0)可能看起来很尴尬,但结果不如笨拙且结构更健全,而是On Error GoTo Label的筏子来回跳来处理各种异常。< / p>

奖励是你也可以获得VBScript的可移植性,因为On Error GoTo Label根本不是一个有效的构造。

答案 2 :(得分:5)

它仅关闭CURRENT过程中的错误处理。如果调用过程中有错误处理程序,它将捕获任何未处理的异常。 VB继续向上调用堆栈,直到找到错误处理程序。如果它没有找到任何那么它将导致运行时错误。

所以举个例子 - 也许你有一个包装器函数可以调用一些可能引发异常的第三方实用程序。而不是在包装函数中处理异常,而是在其中放置On Error Goto 0。那么包装器函数的调用者将获得传递给它的异常,并希望以适当的方式处理它。

答案 3 :(得分:1)

您可能会发现此链接有用:http://answers.microsoft.com/en-us/office/forum/office_2010-excel/why-on-error-resume-next-and-on-error-goto-0-have/a110548f-95c9-44ac-89bc-19697641804a?auth=1

基本上它解释了On Error Resume Next告诉VB跳过发现的任何错误并转到代码中的下一个过程或行,而On Error GoTo 0恢复默认错误处理。

答案 4 :(得分:0)

On Error GoTo 0禁用当前过程中的所有启用的错误处理程序,并清除Err对象,该对象不能通过退出发生错误的过程来清除。您通常在可能导致错误的语句之后直接插入此语句。

示例:

Function ShowError() As String
  Dim i As Long
  ShowError = "No error occurred!"
  On Error Resume Next
  ActiveDocument.Styles("codechar1").LanguageID = wdEnglishUS
  If (Not (Err Is Nothing)) Then ShowError = Err.Description 
  'On Error GoTo 0
End Function

Sub ApplyShowError()
  MsgBox ShowError & vbNewLine & Err.Description
 End Sub

现在假设ActiveDocument对象不包含称为codechar1的样式。然后发生错误,函数ShowError返回“集合中所请求的成员不存在。”如果注释了On Error GoTo 0行,则不会清除Err对象,并且该对象仍然存在。函数ShowError退出,因此此错误消息将再次由调用过程输出。