AcesssVBAやExcelVBAでエラーが出たとき、どの行でエラーが出ているかをある程度知る方法(AcesssVBAとExcelVBAでは、少しコードが異なります。Wordでもそうなのかも?)
※まだ書きかけです。すみません。
※間違ってたらすみません。
※メモ書きなので、自分でも意味不明な箇所も多いです。ごめんなさい。
このコードは、「必ず」「新しいmdbかaccdbファイル」にて、実行してください。
既存のファイルでやると、本コードは不完全なので、そのファイルを破壊する可能性が高いです。
ご注意ください。
(完璧に付加の分岐をするのは無理か、かなり面倒な気がします。
正規表現とかが得意な人ならできるのかも?
また、バージョンによって?なのかわかりませんが、オプション設定にて、
ファイル
→オプション
→トラストセンター
→トラストセンターの設定
→マクロの設定
にて、
「すべてのマクロを有効にする」
にしてOKしておかないと動かないかもしれません。
Excelのような設定は不要かも?です。
当方の365のAccessでは、そこにExcelのような設定項目が無かったので
そのまま何もせずとも動いてしまったのですが・・・。)
●Access用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
' ' Option Compare Database Option Explicit '特定の文字列の付加 'ここでは行番号?を全行の先頭に付加している。 '行番号付加の対象はすべてのモジュールのすべてのプロシージャ。 Sub AllModuleWordPlus01() Dim mdl As Module Dim i As Integer Dim MdlNm As Integer Dim AllGyousuu As Long Dim l_CrrentGyou As Long Dim txtstr As String MdlNm = Modules.Count - 1 '↑モジュールの指定は「Modules(0)」がスタートなので、 ' 最後のモジュールの指定は総数から1引いておく。 For i = 0 To MdlNm '↑各モジュールの中で1行ずつ処理 Set mdl = Modules(i) AllGyousuu = mdl.CountOfLines '↑すべての行数 ' l_CrrentGyou = 1 For l_CrrentGyou = 1 To AllGyousuu ' Debug.Print mdl.Lines(l_CrrentGyou, 1) '↑1行分をイミディエイト表示 txtstr = mdl.Lines(l_CrrentGyou, 1) If 1 <= InStr(1, txtstr, "Sub", vbBinaryCompare) Then ElseIf 1 <= InStr(1, txtstr, "Function ", vbBinaryCompare) Then ElseIf 1 <= InStr(1, txtstr, "Option ", vbBinaryCompare) Then ElseIf 1 <= InStr(1, txtstr, "'", vbBinaryCompare) Then ElseIf 1 <= InStr(1, txtstr, " ", vbBinaryCompare) Then ElseIf 1 <= InStr(1, txtstr, ":", vbBinaryCompare) Then ElseIf txtstr = "" Then Else Call mdl.ReplaceLine(l_CrrentGyou, l_CrrentGyou & txtstr) End If If 1 <= InStr(1, txtstr, "Call", vbBinaryCompare) Then mdl.ReplaceLine l_CrrentGyou, l_CrrentGyou & "" & txtstr Next Next i End Sub ' ' |
「必ず」「新しいmdbかaccdbファイル」にて、
上記と以下のコードを標準モジュールに貼り付けてから、上記コードを実行します。
そうすると、上記と以下のコードの両方に、「行番号」が「あらかた」付加されます。
で、以下のコードでわざとエラーを起こして試してみます。
イミディエイトウィンドウに、
「Error 6: オーバーフローしました。 in Module1, Line 11」
みたいな感じで、エラーの起こった行番号が表示されます。
これを、イミディエイト表示をやめて、
「エラーログなどに追加すればOK」、、、みたいな感じです。
まお、繰り返しますが、
既存のファイルでやると、上記コードは不完全なので、そのファイルを破壊する可能性が高いです。
本当にご注意ください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
' ' Sub SampleProcedure() On Error GoTo ErrHandler ' ここに通常の処理を記述 Dim aaa As Integer aaa = 11 aaa = 50000 Exit Sub ErrHandler: Dim errMsg As String errMsg = "Error " & Err.Number & ": " & Err.Description & " in " & Application.VBE.ActiveCodePane.CodeModule.Name & ", Line " & Erl Debug.Print errMsg ' エラーメッセージを Immediate Window に出力 ' ここにログファイルへの書き込み処理を追加 Resume Next End Sub ' ' |
行番号を振ってもイミディエイトに
「・・・・Line 0」
と出てしまう場合は、
Dim aaaa As Integer
と
aaaa = 50000
のあいだに、
コメントとか、空白行?、何かのコードを適当に挟むと
・・・・Line ××
と行番号が表示されるかもしれません。
なお、エラーが出ている行の、直前の行の番号が表示されてしまうこともあるようで、正常に動かないかもしれません。
ExcelでもExcel用に書きかえて試してみましたが、
同じように少し挙動がおかしかったです。
「カンペキはできない」のかもしれません。
まあでも、それでも、「だいたいの目星」は付けられます。
なお、行番号は、「実際の行番号ではなくて」「付加した数字」が表示されます。
なので、この本プログラムを使わずに、
「気になるプロシージャ」の「気になる行」の先頭に
「適当な数字」を「手動でつける」だけでも、
どの行(or どの行付近)でエラーになったかを知ることができます。
以下は、Excel版です。
オプション設定は今のところ、必ず必要だと思います。
Acessと設定内容が少し異なります。
オプション設定の、
「トラストセンターの設定」→「マクロの設定」にて、
「VBA プロジェクト オブジェクト モデルへのアクセスを信頼する」、
にチェックマークを入れてOKします。
イミディエイトで試すコードは、上記の短いコードと同じです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
' ' Option Explicit '特定の文字列の付加 'ここでは行番号?を全行の先頭に付加している。 '行番号付加の対象はすべてのモジュールのすべてのプロシージャ。 Sub ExcelAllModuleWordPlus01() Dim o_mdl As Object Dim i As Integer Dim i_mdlNum As Integer Dim l_AllGyousuu As Long Dim l_CrrentGyou As Long Dim s_txtstr As String i_mdlNum = ThisWorkbook.VBProject.VBComponents.Count '↑モジュールの指定は「Modules(0)」がスタートなので、 ' 最後のモジュールの指定は総数から1引いておく。 For i = 1 To i_mdlNum '↑各モジュールの中で1行ずつ処理 Set o_mdl = ThisWorkbook.VBProject.VBComponents(i).CodeModule l_AllGyousuu = o_mdl.CountOfLines '↑すべての行数 ' l_CrrentGyou = 1 For l_CrrentGyou = 1 To l_AllGyousuu ' Debug.Print o_mdl.Lines(l_CrrentGyou, 1) '↑1行分をイミディエイト表示 s_txtstr = o_mdl.Lines(l_CrrentGyou, 1) ' Stop If 1 <= InStr(1, s_txtstr, "Sub", vbBinaryCompare) Then ElseIf 1 <= InStr(1, s_txtstr, "Function ", vbBinaryCompare) Then ElseIf 1 <= InStr(1, s_txtstr, "Option ", vbBinaryCompare) Then ElseIf 1 <= InStr(1, s_txtstr, "'", vbBinaryCompare) Then ElseIf 1 <= InStr(1, s_txtstr, " ", vbBinaryCompare) Then ElseIf 1 <= InStr(1, s_txtstr, ":", vbBinaryCompare) Then ElseIf s_txtstr = "" Then Else Call o_mdl.ReplaceLine(l_CrrentGyou, l_CrrentGyou & "" & s_txtstr) ' ’★★' End If If 1 <= InStr(1, s_txtstr, "Call", vbBinaryCompare) Then o_mdl.ReplaceLine l_CrrentGyou, l_CrrentGyou & "" & s_txtstr Next Next i End Sub ' ' |
1 2 3 4 5 6 |
' ' ' ' |