いつものように、On Error Goto
ステートメントを使用してエラーハンドラーを作成し、そこにクリーニングコードを数行追加してエラーメッセージを表示しますが、デフォルトハンドラーの快適さを失いたくないエラーが発生した正確な行に私を。どうやってやるの?
前もって感謝します。
まず良いニュース。 このコードはあなたが望むことをします(「行番号」に注意してください)
Sub a()
10: On Error GoTo ErrorHandler
20: DivisionByZero = 1 / 0
30: Exit Sub
ErrorHandler:
41: If Err.Number <> 0 Then
42: Msg = "Error # " & Str(Err.Number) & " was generated by " _
& Err.Source & Chr(13) & "Error Line: " & Erl & Chr(13) & Err.Description
43: MsgBox Msg, , "Error", Err.HelpFile, Err.HelpContext
44: End If
50: Resume Next
60: End Sub
実行すると、予想されるMsgBoxが表示されます。
そして今、悪いニュース:
行番号は、Basicの古いバージョンの一部です。通常、プログラミング環境がそれらの挿入と更新を担当しました。 VBAおよびその他の「最新」バージョンでは、この機能は失われます。
ただし、 ここ 行番号を「自動的に」追加する代替方法がいくつかあり、それらを入力する面倒な作業を節約できます...しかし、それらはすべて多少面倒です...
HTH!
実行中のエラータイプと一致しない場合は、エラーハンドラーでエラーハンドラーを無効にするだけの簡単な方法があります。
以下のハンドラーは各エラータイプを再度チェックし、一致するものがない場合は、エラーを通常のVBA、つまりGoTo 0に戻し、コードを再開してコードを再実行し、通常のエラーブロックがポップアップします。
On Error GoTo ErrorHandler
x = 1/0
ErrorHandler:
if Err.Number = 13 then ' 13 is Type mismatch (only used as an example)
'error handling code for this
end if
If err.Number = 1004 then ' 1004 is Too Large (only used as an example)
'error handling code for this
end if
On Error GoTo 0
Resume
この答えは、[デバッグ]ボタンには対応していません(フォームを設計し、そのボタンを使用して 次の質問 のメソッドのようなことをする必要があります)。しかし、この部分には対処しています。
これで、エラーが発生した正確な行を指すデフォルトハンドラーの快適さを失いたくありません。
最初に、実稼働コードではこれが必要ないことを想定します。デバッグまたは個人的に使用するコードのいずれかで必要です。コンパイラフラグを使用してデバッグを示します。その後、プログラムのトラブルシューティングを行っている場合、問題の原因となっている行を簡単に見つけることができます。
# Const IsDebug = True
Sub ProcA()
On Error Goto ErrorHandler
' Main code of proc
ExitHere:
On Error Resume Next
' Close objects and stuff here
Exit Sub
ErrorHandler:
MsgBox Err.Number & ": " & Err.Description, , ThisWorkbook.Name & ": ProcA"
#If IsDebug Then
Stop ' Used for troubleshooting - Then press F8 to step thru code
Resume ' Resume will take you to the line that errored out
#Else
Resume ExitHere ' Exit procedure during normal running
#End If
End Sub
注:Resume
の例外は、エラー処理ルーチンのないサブプロシージャでエラーが発生した場合、Resume
はサブプロシージャを呼び出したこのプロシージャの行に移動しますエラー。ただし、サブプロシージャにステップインおよびステップスルーすることはできます。 F8 再びエラーが出るまで。サブプロシージャが長すぎて面倒な場合でも、サブプロシージャには独自のエラー処理ルーチンが必要です。
これを行うには複数の方法があります。トラブルシューティングのときにとにかく手順を実行することがわかっている小さなプログラムでは、MsgBoxステートメントの直後に次の行を追加することがあります。
Resume ExitHere ' Normally exits during production
Resume ' Never will get here
Exit Sub
次のステートメントポインターをその行にドラッグするか、キーを押して、ステップ実行して次の行として設定しない限り、Resumeステートメントに到達することはありません。 CtrlF9 その行にカーソルを置きます。
これらの概念を拡張した記事を次に示します。 VBAでエラーを処理するための5つのヒント 。最後に、VBAを使用していて、Chip Pearsonの素晴らしいサイトをまだ発見していない場合、彼は Error Handling In VBA を説明するページを持っています。
私にとっては、VBAアプリケーションでエラーを確認したかったため、関数で次のコードを作成しました。
Function Database_FileRpt
'-------------------------
On Error GoTo CleanFail
'-------------------------
'
' Create_DailyReport_Action and code
CleanFail:
'*************************************
MsgBox "********************" _
& vbCrLf & "Err.Number: " & Err.Number _
& vbCrLf & "Err.Description: " & Err.Description _
& vbCrLf & "Err.Source: " & Err.Source _
& vbCrLf & "********************" _
& vbCrLf & "...Exiting VBA Function: Database_FileRpt" _
& vbCrLf & "...Excel VBA Program Reset." _
, , "VBA Error Exception Raised!"
*************************************
' Note that the next line will reset the error object to 0, the variables
above are used to remember the values
' so that the same error can be re-raised
Err.Clear
' *************************************
Resume CleanExit
CleanExit:
'cleanup code , if any, goes here. runs regardless of error state.
Exit Function ' SUB or Function
End Function ' end of Database_FileRpt
' ------------------