web-dev-qa-db-ja.com

「On Error Goto 0」を使用するのはなぜですか?

なぜ"On Error Goto 0" VB6アプリで?

このステートメントはエラーハンドラーをオフにし、エラーが発生するとアプリがクラッシュすることを意味します。なぜこれが望ましいのでしょうか?

27
CJ7

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」を呼び出すことで、アプリをすぐにクラッシュさせたいと言っているわけではありません。ルーチンの前半で設定した可能性のあるエラーハンドラーの登録を解除することを単に言っているだけです。エラーは、通常のように、呼び出しスタックから呼び出しルーチンに渡されます。

48
Matt Dillard

言葉で説明するのは面倒だと思われるので、On Error GoTo 0ローカライズされた、構造化されたエラー処理。

最初はProperty Getサブクラス化されたコレクションの階層に基づいた軽量DOMを実装するクラス(「MicroDOM」)内。この場合、空の(属性または子なしの)子を作成するために、インデックスの代わりに名前で欠落している子を参照する試みが必要です。

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

2番目は、ファイルが存在する場合にそれを削除するインラインコードです。

On Error Resume Next
Kill strFilePath
On Error GoTo 0

3番目は、ファイルが存在する場合にのみアクションを実行するインラインコードです。

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 2か所)結果は、On Error GoTo Labelさまざまな例外を処理するために前後にジャンプします。

ボーナスは、VBScriptへの移植性も得られることです。なぜならOn Error GoTo Labelは、有効な構造ではありません。

8
Bob77

CURRENTプロシージャのエラー処理のみをオフにします。呼び出し元のプロシージャにエラーハンドラがある場合、処理されなかった例外をキャッチします。 VBは、エラーハンドラを見つけるまでコールスタックを上げ続けます。THENが見つからない場合、ランタイムエラーが発生します。

そのため、たとえば、例外をスローする可能性のあるサードパーティのユーティリティを呼び出すラッパー関数があるかもしれません。ラッパー関数で例外を処理する代わりに、On Error Goto 0 そこで。そのため、ラッパー関数の呼び出し元は、それに渡された例外を取得し、うまくいけば適切な方法でそれを処理します。

5
DJ.

このリンクは役に立つかもしれません: 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はデフォルトのエラー処理を復元します。

1
David