Excel VBA 逆引き集 | 実務テンプレ完全版(超再利用部品) – バッチ処理テンプレ

Excel VBA
スポンサーリンク

ねらい:複数の処理を「一括で・安全に・同じ型で」流すバッチ処理テンプレ

「このマクロを実行して、そのあとにあのマクロを実行して…」
「毎朝、同じ順番で“取り込み→変換→JOIN→集計→出力”をやっている」

こういう“決まった一連の処理”は、1本ずつ手で実行していると、
順番を間違えたり、途中で止まっても気づかなかったりします。

バッチ処理テンプレのゴールは、ここをこう変えることです。

一連の処理を「ジョブ」として一覧にする(設定シート)。
VBAは、その一覧を上から順に実行する“バッチエンジン”になる。
開始・終了・エラーを処理ログに残しながら、安全に流す。

つまり、「朝になったらボタン1つで全部流れる」「どこで止まったかログで分かる」状態を、
テンプレとして再利用できる形にします。


全体設計:ジョブ設定シート+バッチエンジン+処理ログ

3つの役者を決める

バッチ処理テンプレは、次の3つで構成します。

ジョブ設定シート(ConfigBatch)
どの処理を、どの順番で、どういう条件で実行するかを書く表です。

バッチエンジン(ModBatchEngine)
ConfigBatch を読み、書かれた順に処理を呼び出す“司令塔”です。

処理ログ(前回作った LogWrite 系)
各ジョブの開始・終了・エラーを記録します。

ここで大事なのは、「個々の業務マクロの中身には手を入れない」ことです。
既にある ImportCustomerJoinMaster などのマクロを、“バッチから呼び出せるように並べる”だけにします。


ジョブ設定シートの設計:1行=1ジョブ

ConfigBatch の列構成

ConfigBatch シートに、次の列を用意します。

A列:Enabled(Y の行だけ実行)
B列:JobName(ジョブ名。ログに出す用)
C列:MacroName(実行するマクロ名)
D列:StopOnError(Yならエラーでバッチ全体を止める)
E列:Comment(説明やメモ)

イメージはこうです。

ABCDE
Y顧客CSV取込ImportCustomerY顧客マスタの元データ取込
Y顧客マスタ整形ConvCustomerYノーコード変換ツール呼び出し
Y顧客マスタJOINJoinCustomerY顧客×エリアマスタJOIN
Y顧客集計AggCustomerN集計だけなのでエラーでも続行

ポイントをかみ砕くとこうです。

Enabled が Y の行だけが“有効なジョブ”。
JobName は人間が見て分かりやすい名前。ログにも出します。
MacroName は実際に呼び出す Sub の名前(Application.Run で呼ぶ)。
StopOnError が Y のジョブでエラーが出たら、そこでバッチ全体を止める。

この表を変えるだけで、「どの処理を流すか」「順番」「エラー時の振る舞い」を差し替えられます。


コア部品:ジョブルールを表す構造体と読み込み処理

ジョブルールの構造体

' ModBatchEngine.bas
Option Explicit

Private Type BatchJob
    Enabled As Boolean
    JobName As String
    MacroName As String
    StopOnError As Boolean
    Comment As String
End Type
VB

初心者向けに言うと、「ConfigBatch の1行分を1つの“箱”にしたもの」です。
この箱を配列にして、上から順に処理していきます。

ConfigBatch を読み込んで BatchJob 配列にする

Private Function LoadBatchJobs() As Variant
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("ConfigBatch")
    
    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
    If lastRow < 2 Then
        LoadBatchJobs = Empty
        Exit Function
    End If
    
    Dim data As Variant
    data = ws.Range(ws.Cells(2, 1), ws.Cells(lastRow, 5)).Value
    
    Dim jobs() As BatchJob
    ReDim jobs(1 To UBound(data, 1))
    
    Dim i As Long
    For i = 1 To UBound(data, 1)
        jobs(i).Enabled = (UCase$(CStr(data(i, 1))) = "Y")
        jobs(i).JobName = CStr(data(i, 2))
        jobs(i).MacroName = CStr(data(i, 3))
        jobs(i).StopOnError = (UCase$(CStr(data(i, 4))) = "Y")
        jobs(i).Comment = CStr(data(i, 5))
    Next
    
    LoadBatchJobs = jobs
End Function
VB

ここでの重要ポイントは、「設定シートは配列で一気に読み込む」ことです。
1セルずつ読むより圧倒的に速く、コードもスッキリします。


バッチエンジン本体:ジョブを順番に実行する

高速化ラッパー(お約束)

バッチは複数のマクロを連続で動かすので、画面更新などは切っておきます。

Private Sub SpeedOn()
    Application.ScreenUpdating = False
    Application.EnableEvents = False
    Application.Calculation = xlCalculationManual
End Sub

Private Sub SpeedOff()
    Application.Calculation = xlCalculationAutomatic
    Application.EnableEvents = True
    Application.ScreenUpdating = True
End Sub
VB

メインエントリーポイント:RunBatch

Public Sub RunBatch()
    Const MODULE_NAME As String = "BatchRunner"
    
    Dim jobs As Variant
    jobs = LoadBatchJobs()
    If IsEmpty(jobs) Then
        MsgBox "ConfigBatchにジョブがありません。", vbInformation
        Exit Sub
    End If
    
    SpeedOn
    
    LogStart MODULE_NAME, "バッチ処理開始"
    
    Dim i As Long
    For i = LBound(jobs) To UBound(jobs)
        If jobs(i).Enabled Then
            If Not RunOneJob(jobs(i), MODULE_NAME) Then
                If jobs(i).StopOnError Then
                    LogWrite "WARN", MODULE_NAME, "BATCH_STOP", _
                             "ジョブ[" & jobs(i).JobName & "]でエラー。StopOnError=Yのため中断。"
                    Exit For
                End If
            End If
        End If
    Next i
    
    LogEnd MODULE_NAME, "バッチ処理終了"
    
    SpeedOff
    MsgBox "バッチ処理が終了しました。ログを確認してください。", vbInformation
End Sub
VB

ここでやっていることを、ゆっくり分解します。

バッチ全体の開始ログを1行書く。
LoadBatchJobs でジョブ一覧を読み込む。
Enabled=Y のジョブだけを、上から順に RunOneJob で実行する。
RunOneJob が False(=エラー終了)を返したら、StopOnError を見て、Yならそこで For を抜ける。
最後に、バッチ全体の終了ログを書き、画面更新などを元に戻す。

つまり、RunBatch は「ConfigBatch をなぞりながら、ジョブを順番に呼び出す司令塔」です。


1ジョブを実行する心臓部:RunOneJob

Application.Run でマクロを名前指定で呼ぶ

Private Function RunOneJob(ByRef job As BatchJob, ByVal batchModuleName As String) As Boolean
    On Error GoTo ErrHandler
    
    Dim msg As String
    msg = "ジョブ開始: " & job.JobName & " (" & job.MacroName & ")"
    If job.Comment <> "" Then
        msg = msg & " - " & job.Comment
    End If
    
    LogWrite "INFO", batchModuleName, "JOB_START", msg
    
    Application.Run job.MacroName
    
    LogWrite "INFO", batchModuleName, "JOB_END", "ジョブ終了: " & job.JobName
    RunOneJob = True
    Exit Function
    
ErrHandler:
    LogWrite "ERROR", batchModuleName, "JOB_ERROR", _
             "ジョブ[" & job.JobName & "]でエラー発生。Err=" & Err.Number & ", " & Err.Description
    RunOneJob = False
End Function
VB

ここがバッチ処理テンプレの一番おいしいところです。

ジョブの開始時に「JOB_START」ログを書き、
MacroName に書かれたマクロを Application.Run で呼び出し、
終わったら「JOB_END」ログを書く。
途中でエラーが出たら、JOB_ERROR としてログに残し、False を返す。

つまり、個々のマクロの中身は一切知らずに、「名前だけで呼び出して、結果だけ見る」仕組みになっています。


例題:既存のマクロを“バッチ対応”させる

既にあるマクロたち

例えば、あなたがこんなマクロを持っているとします。

Sub ImportCustomer()
    ' 顧客CSV取込処理
End Sub

Sub ConvCustomer()
    ' 顧客データ整形(ノーコード変換ツール呼び出し)
End Sub

Sub JoinCustomer()
    ' 顧客×エリアマスタJOIN
End Sub

Sub AggCustomer()
    ' 顧客集計(ノーコード集計ツール呼び出し)
End Sub
VB

これらは、今までは手で順番に実行していたとします。

ConfigBatch に並べるだけで“バッチ化”できる

ConfigBatch に、次のように書きます。

A列:Y / B列:顧客CSV取込 / C列:ImportCustomer / D列:Y / E列:顧客マスタの元データ取込
A列:Y / B列:顧客マスタ整形 / C列:ConvCustomer / D列:Y / E列:ノーコード変換ツール呼び出し
A列:Y / B列:顧客マスタJOIN / C列:JoinCustomer / D列:Y / E列:顧客×エリアマスタJOIN
A列:Y / B列:顧客集計 / C列:AggCustomer / D列:N / E列:集計だけなのでエラーでも続行

あとは、RunBatch を実行するだけで、

ImportCustomer → ConvCustomer → JoinCustomer → AggCustomer

が、設定された順番で流れます。
どこでエラーが出たか、どこまで終わったかは、Log シートを見れば一目で分かります。


重要ポイントの深掘り:バッチ処理テンプレを“現場で回る”形にするコツ

個々のマクロにも「処理ログテンプレ」を組み込んでおく

バッチ側では「ジョブ単位」の開始・終了・エラーをログに書いていますが、
個々のマクロの中でも、前回作った LogStart / LogEnd / LogError を使っておくと、
「どのジョブの中の、どのステップで止まったか」まで追えるようになります。

バッチログ(外側)

各マクロの処理ログ(内側)

この二重構造にしておくと、トラブルシュートがかなり楽になります。

StopOnError の設計をちゃんと考える

全部のジョブで StopOnError=Y にしてしまうと、
「集計だけ失敗しても、取り込みやJOINは終わっているのに、バッチ全体が失敗扱い」になります。

例えば、

データ取り込み系・変換系・JOIN系 → StopOnError=Y(止める)
集計系・レポート出力系 → StopOnError=N(続行)

のように、「ここで止まると困る」「ここは失敗しても致命的ではない」を分けておくと、
運用上のストレスが減ります。

ジョブの“前提条件”をコメントに書いておく

ConfigBatch の Comment 列は、単なるメモではなく、
「このジョブを動かす前に満たしておくべき条件」を書いておくと実務的です。

例:

顧客CSV取込 → 「最新の顧客CSVが \server\share に置かれていること」
JOIN → 「AreaMaster シートが最新であること」

こうしておくと、バッチを回す人が「何を確認してからボタンを押せばいいか」が分かります。


まとめ:バッチ処理テンプレは「ConfigBatch × RunBatch × RunOneJob」の3点セット

今回のテンプレの核は、たったこれだけです。

ConfigBatch という“ジョブ一覧表”に、実行したいマクロ名と順番を書く。
LoadBatchJobs でその表を BatchJob 配列に読み込む。
RunBatch が配列を上からなぞり、RunOneJob が Application.Run でマクロを呼び出しつつ、ログとエラー制御を行う。

この型さえ一度作ってしまえば、
「この業務フローもバッチに乗せたいな」と思ったときにやることは、

ConfigBatch に行を足す
必要なら個々のマクロに処理ログテンプレを組み込む

だけになります。

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