デバッグログ
うまくいかない時に「今どこまで動いてる?」「何が入ってる?」を見える化するのがデバッグログ。止めずに走らせながら、状況を素早く掴むための基本とテンプレをまとめます。
デバッグログの基本
- 目的: 変数の中身、処理の通過点、所要時間、エラー内容を即座に確認する
- 出力先の選択:
- Immediateウィンドウ(VBEの表示→イミディエイト)に出す:
Debug.Print - ステータスバーに出す:
Application.StatusBar - シートに出す: 画面上で共有しやすい
- ファイルに出す: 長期記録(運用向け)
- Immediateウィンドウ(VBEの表示→イミディエイト)に出す:
- 使い分け: 開発中は
Debug.Print、運用時はファイルやシートが便利
すぐ使える基本テンプレ
1) 通過点と変数の中身を出す(Immediateウィンドウ)
Sub DebugLog_Basic()
Debug.Print "開始:", Now
Dim total As Long
total = Worksheets("Data").Range("B2").Value
Debug.Print "total=", total
Debug.Print "終了:", Now
End Sub
VB- ポイント:
- 開始/終了で範囲を囲む
- 変数名=値の形式が読みやすい
2) 処理時間を測る(ストップウォッチ)
Sub DebugLog_Timing()
Dim t0 As Double: t0 = Timer
' 重たい処理
Application.CalculateFullRebuild
Debug.Print "Elapsed(sec)=", Round(Timer - t0, 3)
End Sub
VB- ポイント:
- Timerで秒計測、ボトルネック特定に役立つ
3) StatusBarに進捗を出す(ユーザー向け)
Sub DebugLog_StatusBar()
Application.StatusBar = "処理開始..."
' 何かの処理
Application.StatusBar = "50% 完了"
' さらに処理
Application.StatusBar = False ' 元に戻す
End Sub
VB- ポイント:
- 一時的に進捗表示、最後は必ず False で解除
シート&ファイルに残すテンプレ
4) シートにログ行を追加(簡易トレース)
Sub SheetLog(ByVal msg As String)
Dim ws As Worksheet: Set ws = Worksheets("Log")
Dim r As Long: r = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1
ws.Cells(r, 1).Value = Now
ws.Cells(r, 2).Value = msg
End Sub
Sub Example_SheetLog()
SheetLog "開始"
SheetLog "Data 読み込み"
SheetLog "終了"
End Sub
VB- ポイント:
- 日時+メッセージで最低限のトレースを残す
5) ファイルにデバッグログ(使い回し関数)
Sub FileLog(ByVal msg As String, Optional ByVal path As String = "C:\temp\debug.log")
Dim fso As Object, ts As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.OpenTextFile(path, 8, True) ' 8=追記
ts.WriteLine Now & " | " & msg
ts.Close
End Sub
Sub Example_FileLog()
FileLog "開始"
FileLog "処理A 実行"
FileLog "終了"
End Sub
VB- ポイント:
- 追記モードで履歴を積み上げる
レベル付きロガー(開発~運用の切替)
6) ログレベルと出力切替(Debug/Info/Warn/Error)
' 標準モジュール: Logger.bas
Public Enum LogLevel
LOG_DEBUG = 1
LOG_INFO = 2
LOG_WARN = 3
LOG_ERROR = 4
End Enum
Public CURRENT_LOG_LEVEL As LogLevel
Public OUTPUT_TO_FILE As Boolean
Public LOG_PATH As String
Public Sub LogInit(Optional lvl As LogLevel = LOG_INFO, _
Optional toFile As Boolean = False, _
Optional path As String = "C:\temp\debug.log")
CURRENT_LOG_LEVEL = lvl
OUTPUT_TO_FILE = toFile
LOG_PATH = path
End Sub
Public Sub LogWrite(ByVal lvl As LogLevel, ByVal msg As String)
If lvl < CURRENT_LOG_LEVEL Then Exit Sub
Dim prefix As String
Select Case lvl
Case LOG_DEBUG: prefix = "DEBUG"
Case LOG_INFO: prefix = "INFO "
Case LOG_WARN: prefix = "WARN "
Case LOG_ERROR: prefix = "ERROR"
End Select
Dim line As String
line = Format(Now, "yyyy-mm-dd HH:NN:SS") & " [" & prefix & "] " & msg
If OUTPUT_TO_FILE Then
Dim fso As Object, ts As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.OpenTextFile(LOG_PATH, 8, True)
ts.WriteLine line
ts.Close
Else
Debug.Print line
End If
End Sub
VBSub Example_Logger()
LogInit LOG_DEBUG, False ' レベル=DEBUG, 出力=Immediate
LogWrite LOG_INFO, "開始"
LogWrite LOG_DEBUG, "読み込み前: rowCount=0"
LogWrite LOG_WARN, "入力シートが見つかりません(Sheet2)"
LogWrite LOG_ERROR, "処理中断: 必須データ欠落"
End Sub
VB- ポイント:
- レベルで絞る(運用はINFO以上、開発はDEBUG)
- 出力先を切替(Immediate or ファイル)
エラー連携・関数トレース
7) エラー時に詳細ログ
Sub Example_ErrorLogging()
On Error GoTo ErrHandler
LogInit LOG_INFO, True, "C:\temp\run.log"
LogWrite LOG_INFO, "開始"
Worksheets("NoSheet").Activate ' 故意にエラー
LogWrite LOG_INFO, "正常終了"
Exit Sub
ErrHandler:
LogWrite LOG_ERROR, "Err " & Err.Number & " | " & Err.Description
End Sub
VB- ポイント:
- Err.Number/Descriptionを必ず記録
8) 関数の入口・出口(トレース)
Sub ProcessData()
LogWrite LOG_DEBUG, "Enter ProcessData"
' 何かの処理…
LogWrite LOG_DEBUG, "Exit ProcessData"
End Sub
VB- ポイント:
- Enter/Exitで「どこで止まったか」を追いやすくする
初心者がハマるところと対策
- 出力しっぱなしで見ない:
- 重要だけ残す(INFO以上)に絞る。必要時のみDEBUGを有効化
- 進捗が分からない:
- 区切りのログ+ステータスバーを併用
- 重くなる:
- ループの全件は避け、まとめて要点を出す。必要なら件数だけ
- 運用でImmediate不可:
- シート/ファイルに切替できるロガーを用意
- エラー内容が足りない:
- 番号/説明/手順名を最低限セットで残す
例題(練習用)
- 例1: Timerで所要時間を測り、最も時間がかかる処理に「開始/終了」ログを入れる
- 例2: ログレベルをDEBUGにして、読み込んだ件数と先頭3件のIDだけ出力
- 例3: エラー時に Err.Number/Description をファイルへ追記し、次回解析できるようにする
