web-dev-qa-db-ja.com

VBA:「デバッグ」ボタンがある標準エラーメッセージのようにエラーメッセージを表示する方法

いつものように、On Error Gotoステートメントを使用してエラーハンドラーを作成し、そこにクリーニングコードを数行追加してエラーメッセージを表示しますが、デフォルトハンドラーの快適さを失いたくないエラーが発生した正確な行に私を。どうやってやるの?

前もって感謝します。

22
Vantomex

まず良いニュース。 このコードはあなたが望むことをします(「行番号」に注意してください)

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が表示されます。

alt text

そして今、悪いニュース:
行番号は、Basicの古いバージョンの一部です。通常、プログラミング環境がそれらの挿入と更新を担当しました。 VBAおよびその他の「最新」バージョンでは、この機能は失われます。

ただし、 ここ 行番号を「自動的に」追加する代替方法がいくつかあり、それらを入力する面倒な作業を節約できます...しかし、それらはすべて多少面倒です...

HTH!

44
Dr. belisarius

実行中のエラータイプと一致しない場合は、エラーハンドラーでエラーハンドラーを無効にするだけの簡単な方法があります。

以下のハンドラーは各エラータイプを再度チェックし、一致するものがない場合は、エラーを通常の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
1
Paul Haines

この答えは、[デバッグ]ボタンには対応していません(フォームを設計し、そのボタンを使用して 次の質問 のメソッドのようなことをする必要があります)。しかし、この部分には対処しています。

これで、エラーが発生した正確な行を指すデフォルトハンドラーの快適さを失いたくありません。

最初に、実稼働コードではこれが必要ないことを想定します。デバッグまたは個人的に使用するコードのいずれかで必要です。コンパイラフラグを使用してデバッグを示します。その後、プログラムのトラブルシューティングを行っている場合、問題の原因となっている行を簡単に見つけることができます。

# 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 を説明するページを持っています。

0
GlennFromIowa

私にとっては、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

' ------------------
0
Hank Freeman