Excel VBA 逆引き集 | デバッグログ

Excel VBA
スポンサーリンク

デバッグログ

うまくいかない時に「今どこまで動いてる?」「何が入ってる?」を見える化するのがデバッグログ。止めずに走らせながら、状況を素早く掴むための基本とテンプレをまとめます。


デバッグログの基本

  • 目的: 変数の中身、処理の通過点、所要時間、エラー内容を即座に確認する
  • 出力先の選択:
    • Immediateウィンドウ(VBEの表示→イミディエイト)に出す: Debug.Print
    • ステータスバーに出す: Application.StatusBar
    • シートに出す: 画面上で共有しやすい
    • ファイルに出す: 長期記録(運用向け)
  • 使い分け: 開発中は 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
VB
Sub 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 をファイルへ追記し、次回解析できるようにする

タイトルとURLをコピーしました