誰かがVBAの「エラー時goto-1」と「エラー時goto0」の違いを見つけることができますか?私はグーグルとmsdnを試しましたが、運がありませんでした。
3 に答える
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アプリケーション全体をロックする可能性があるため、意図的に含めませんでした。はい、エラー時GoTo -1は構文的に有効ですが、酔っ払った10代の若者に銃を与えるようなものです。それから良いものは何も生まれません。
エラーオブジェクトを使用して、エラーハンドラを使用せずにインラインでエラーを処理することもできます。MSDNインラインエラー処理
VBAでエラーが発生すると、2つの異なることが発生することを理解することが重要です。
エラーオブジェクトには、プロパティが設定されています(つまり、err.number、err.desciption、err.sourceなど)。
次に実行される行が変更されます。
どの行が実行されるかは、最後に実行された「OnErrorGoto」ステートメントによって決定されます(存在する場合)。
これらは別々ですが、関連性の高いトピックであり、両方を管理するために、実際には別個であるが織り交ぜられたコードを記述します。
エラーが発生した場合、またはErr.Raiseを使用した場合、Errオブジェクトは常に設定されます。「OnErrorResmuenext」またはその他のOnerrorステートメントが使用されている場合でも。
したがって、このようなコードは常に使用できます。
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は、現在配置されている「OnErrorGoto」を削除します。したがって、ほとんどの場合、以下を使用するのが最適です。
On Error Goto -1
Err.clearを使用するようにあなたはしばしば書く必要があるでしょう
Err.Clear
On Error Goto MyErrorHandlerLabel
Err.Clearは、任意のタイプのResumeステートメント、Exit Sub、Exit Function、Exit Property、またはOn Errorステートメントを実行するたびに、VBAによって暗黙的に実行されることに注意してください。
エラーオブジェクトを任意の数に設定することもできます
Err.Raise番号:=、ソース:=、説明:=
Err.Raiseは、エラーを呼び出し側プログラムに伝播し、論理的な理由で続行できなかったことを呼び出し側プログラムに通知する手段を提供する「ユーザー定義エラー」と呼ばれる独自のエラー番号を上げることができるため、非常に重要です。(例えば、ビジネスルールが破られた)。
次のようなステートメントを使用して、次に実行されるコード行を制御できます。
On Error Goto ALabelName On ErrorGotoANonZeroLineNumberおよびOnErrorGoto 0'これは、「現在のスコープ(通常はサブまたは関数)内で、エラーが発生した場合にエラーオブジェクトをに戻す」という特殊なケースです。現在のサブまたは関数を呼び出したコード。
特にMSDNページには、エラー処理の使用方法の完全な例が記載されていないため、VBAでのエラー処理には注意が必要です。