ねらい:Excel業務マクロを「設計図のある仕組み」にする全体構造テンプレ
ここまで、JOIN・集計・差分・変換・ログ・バッチ・処理時間計測…と、たくさんの“部品”を見てきましたよね。
全体構造テンプレのゴールは、それらをバラバラのマクロの寄せ集めではなく、「一つの設計思想を持った仕組み」として整理することです。
どのブックにも共通する“骨組み”を決めておくと、新しい機能を足すときも、既存の処理を直すときも、「どこに何を書けばいいか」が迷わなくなります。
ここでは、実務で本当に使える「標準構成」と、そのコードテンプレを、初心者向けにかみ砕いてまとめます。
全体構造の基本レイヤー
レイヤーの考え方
全体構造テンプレでは、Excel VBAの世界をざっくり次のレイヤーに分けて考えます。
一番上に「エントリーポイント(ユーザーが押すボタンやメインマクロ)」。
その下に「業務ごとのバッチ処理(ConfigBatch+RunBatch)」。
さらに下に「ノーコード系エンジン群(JOIN・集計・差分・変換など)」。
横に「共通基盤(設定シートユーティリティ、ログ、処理時間計測、エラー処理)」。
大事なのは、「上のレイヤーほど業務に近く、下のレイヤーほど汎用的」という構造にすることです。
これにより、「業務が変わっても下のレイヤーはほとんど触らない」という状態を目指します。
モジュールの役割分担
標準的なモジュール構成のイメージはこうです。
ModEntry(メインメニューやボタンから呼ばれる入口)
ModBatchEngine(ConfigBatchを読んでジョブを流す)
ModJoinEngine / ModAggEngine / ModDiffEngine / ModConvEngine(ノーコード系エンジン)
ModLogger(処理ログ共通部品)
ModStopWatch(処理時間計測共通部品)
ModConfigUtil(設定シート読み込み・列変換などの共通ユーティリティ)
名前は変えても構いませんが、「役割ごとにモジュールを分ける」ことが重要です。
一つのモジュールに全部詰め込むと、必ず後で迷子になります。
エントリーポイントテンプレ:ユーザーが触るのはここだけにする
メインメニュー用のSub
ユーザーが押すボタンや、ショートカットキーに割り当てるのは、できるだけ「1本のメインSub」に寄せます。
例えば、こんな感じです。
' ModEntry.bas
Option Explicit
Public Sub RunDailyJobs()
Const MODULE_NAME As String = "RunDailyJobs"
On Error GoTo ErrHandler
LogStart MODULE_NAME, "日次バッチ開始"
RunBatch
LogEnd MODULE_NAME, "日次バッチ終了"
Exit Sub
ErrHandler:
LogError MODULE_NAME, "MAIN", Err
MsgBox "日次処理中にエラーが発生しました。ログを確認してください。", vbExclamation
End Sub
VBここでのポイントは、エントリーポイントは「バッチを呼ぶ」「ログを書く」「エラーを受け止める」だけにしておくことです。
具体的な業務ロジックは、すべて下のレイヤー(バッチエンジンやノーコードエンジン)に任せます。
バッチレイヤー:ConfigBatch × RunBatch × 個別マクロ
ConfigBatch と RunBatch の位置づけ
バッチレイヤーは、「どの業務マクロを、どの順番で、どういう条件で実行するか」を決める層です。
ここでは、前に作ったバッチ処理テンプレをそのまま“全体構造の中核”として使います。
ConfigBatch シートに、ジョブ一覧を書きます。
ModBatchEngine に、LoadBatchJobs・RunBatch・RunOneJob を持たせます。
個々の業務マクロ(ImportCustomer など)は、バッチから Application.Run で呼ばれるだけにします。
例えば、ConfigBatch にこう書いておけば、
顧客取込(ImportCustomer)
顧客整形(ConvCustomer)
顧客JOIN(JoinCustomer)
顧客集計(AggCustomer)
という一連の流れが、RunBatch から一気に流れます。
全体構造としては、「業務フローの制御はバッチレイヤーに集約する」というイメージです。
ノーコードエンジンレイヤー:JOIN・集計・差分・変換を“部品化”する
各エンジンの共通パターン
ノーコード系エンジン(JOIN・集計・差分・変換)は、どれも同じ構造を持っています。
Config○○ シート(ConfigJoin, ConfigAgg, ConfigDiff, ConfigConv など)
ルール構造体(JoinRule, AggRule, DiffRule, ConvRule)
ルール読み込み関数(LoadJoinRules など)
メインSub(RunJoinTool など)
ルール1件分の適用処理(ApplyJoinRule など)
例えば、ノーコード変換ツールならこうです。
' ModConvEngine.bas
Option Explicit
Private Type ConvRule
Enabled As Boolean
SourceSheet As String
SourceCol As Long
TargetSheet As String
TargetCol As Long
TransformName As String
Options As String
End Type
Public Sub RunConvTool()
Dim rules As Variant
rules = LoadConvRules()
If IsEmpty(rules) Then Exit Sub
SpeedOn
Dim i As Long
For i = LBound(rules) To UBound(rules)
If rules(i).Enabled Then
ApplyConvRule rules(i)
End If
Next i
SpeedOff
End Sub
VB全体構造テンプレとして大事なのは、「どのエンジンも同じ型で作る」ことです。
そうすると、新しいエンジン(例えばノーコードフィルタツール)を作るときも、
既存のテンプレをほぼコピペで流用できます。
業務マクロからエンジンを呼ぶ形
個別の業務マクロは、「設定シートを用意して、エンジンを呼ぶだけ」にします。
例えば、顧客整形マクロはこうなります。
Sub ConvCustomer()
Const MODULE_NAME As String = "ConvCustomer"
On Error GoTo ErrHandler
LogStart MODULE_NAME, "顧客データ整形開始"
RunConvTool
LogEnd MODULE_NAME, "顧客データ整形終了"
Exit Sub
ErrHandler:
LogError MODULE_NAME, "MAIN", Err
End Sub
VBここでも、「業務マクロはエンジンを呼ぶだけ」「ロジックは設定シートに書く」という全体構造のルールを守ります。
共通基盤レイヤー:ログ・時間計測・設定ユーティリティ
ログモジュール(ModLogger)
全体構造の“土台”として、処理ログはほぼ必須です。
前に作った LogWrite / LogStart / LogEnd / LogError を、ModLogger にまとめておきます。
' ModLogger.bas
Option Explicit
Public Sub LogWrite( _
ByVal level As String, _
ByVal moduleName As String, _
ByVal eventName As String, _
Optional ByVal message As String = "")
' Log シートに1行書く処理(前回のテンプレそのまま)
End Sub
Public Sub LogStart(ByVal moduleName As String, Optional ByVal message As String = "")
LogWrite "INFO", moduleName, "START", message
End Sub
Public Sub LogEnd(ByVal moduleName As String, Optional ByVal message As String = "")
LogWrite "INFO", moduleName, "END", message
End Sub
Public Sub LogError(ByVal moduleName As String, ByVal eventName As String, ByVal errObj As ErrObject)
Dim msg As String
msg = "ErrNumber=" & errObj.Number & ", Description=" & errObj.Description
LogWrite "ERROR", moduleName, eventName, msg
End Sub
VB全体構造として、「どのモジュールからも同じログ関数を呼ぶ」という統一感が生まれます。
処理時間計測(ModStopWatch+クラス)
処理時間計測テンプレも、全体構造の“共通基盤”として置いておきます。
StopWatch クラスと、それを補助する関数を ModStopWatch にまとめます。
業務マクロ側は、「必要なときだけ StopWatch を生成して使う」という形にすれば、
全体構造を壊さずに“重いところだけ見える化”できます。
設定ユーティリティ(ModConfigUtil)
設定シート方式テンプレで作った ColToNumber や、
設定シート読み込み時の共通処理(例えば空行スキップなど)は、ModConfigUtil に集約します。
' ModConfigUtil.bas
Option Explicit
Public Function ColToNumber(ByVal colRef As Variant) As Long
If IsNumeric(colRef) Then
ColToNumber = CLng(colRef)
Else
ColToNumber = Range(CStr(colRef) & "1").Column
End If
End Function
VBこうしておくと、どのエンジンからも同じ関数を使えるので、
「列指定の解釈がエンジンごとに微妙に違う」といった事故を防げます。
例題:全体構造テンプレを使った“1冊の業務ブック”のイメージ
想定する業務
例えば、「日次で顧客データを取り込み、整形し、マスタとJOINし、集計してレポートを出す」というブックを考えます。
このブックは、次のような構造になります。
ConfigBatch シートに「日次ジョブ一覧」。
ConfigConv シートに「顧客整形ルール」。
ConfigJoin シートに「顧客×マスタJOINルール」。
ConfigAgg シートに「顧客集計ルール」。
Log シートに「処理ログ」。
必要に応じて ConfigDiff や Config○○ を追加。
VBA側は、
ModEntry に RunDailyJobs。
ModBatchEngine に RunBatch。
ModConvEngine / ModJoinEngine / ModAggEngine に各エンジン。
ModLogger / ModStopWatch / ModConfigUtil に共通基盤。
ImportCustomer / ConvCustomer / JoinCustomer / AggCustomer などの業務マクロは、
それぞれ「エンジン呼び出し+ログ+エラー処理」だけを書く。
この構造を一度作ってしまえば、
「新しいマスタJOINを追加したい」「別の集計パターンを増やしたい」といった要望は、
ほとんど「設定シートに行を足す」「Config○○を増やす」だけで対応できます。
まとめ:全体構造テンプレは「迷わないための“VBAの地図”」
ここまでを一言でまとめると、全体構造テンプレはこういうものです。
エントリーポイントは少数に絞り、バッチレイヤーに業務フローを集約する。
業務ロジックは、できる限りノーコードエンジン+設定シートに落とし込む。
ログ・時間計測・設定ユーティリティは共通基盤としてモジュールを分け、どの処理からも同じ形で使う。
この“地図”が頭の中にあると、新しいマクロを書くときに
「このコードはどのレイヤーに置くべきか?」
「これは設定シートで表現できないか?」
と自然に考えるようになります。

