ねらい:「設定シート方式」という“考え方そのもの”をテンプレ化する
ここまで、JOIN・集計・差分・変換…と、いろんな「ノーコード系ツール」を見てきましたよね。
実は全部、同じ“型”でできています。
共通しているのは、この発想です。
- ロジック(何をどうするか)は「設定シート」に書く
- VBAのコードは「設定を読んで実行する汎用エンジン」だけにする
これを、私は「設定シート方式」と呼んでいます。
今回は、この“方式そのもの”をテンプレとしてまとめます。
「新しいツールを作るとき、まず“設定シート方式”で考える」
ここまで行けると、あなたのVBAは一気に“現場で回る仕組み”になります。
設定シート方式の基本構造
3つの役割に分ける
設定シート方式は、いつもこの3つに分かれます。
- 設定を書くシート(Config系)
- データがあるシート(Source/Detail/Masterなど)
- 汎用エンジン(VBAモジュール)
大事なのは、「業務ごとに変わるもの」と「変わらないもの」を分けることです。
- 変わるもの → 設定シートの中身(どのシート・どの列・どの処理)
- 変わらないもの → エンジンのコード(設定を読んで動くだけ)
この分離ができると、「業務が変わってもコードは変えない」が現実になります。
1行=1ルールという“行指向”の設計
設定シートは、基本的に「1行=1ルール」です。
- 1行が「1つのJOIN」
- 1行が「1つの集計」
- 1行が「1つの変換」
これを徹底すると、VBA側は
- 設定シートを配列で読み込む
- 1行ずつ構造体に詰める
- その構造体を引数にして汎用処理を呼ぶ
という、きれいな形に落ち着きます。
設定シート方式テンプレのコード骨格
ここからは、「どんなツールにも流用できる“骨格”」として見てください。
中身(フィールド名や処理内容)を変えれば、JOINにも集計にも変換にもなります。
共通:列記号を列番号に変換する
設定シートでは「A」「B」「C」と書きたいことが多いので、
それを列番号に変換する関数は“共通部品”として必ず持っておきます。
' 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行分を表す「構造体」を定義する
例えば「汎用処理ルール」を抽象化すると、こんな感じになります。
' ModTemplateEngine.bas
Option Explicit
Private Type RuleTemplate
Enabled As Boolean
SourceSheet As String
TargetSheet As String
Param1 As String
Param2 As String
Param3 As String
End Type
VBここではあえて抽象的な名前にしています。
実際に使うときは、JOINなら JoinRule、集計なら AggRule、変換なら ConvRule のように、
中身に合わせてフィールド名を変えればOKです。
共通:設定シートを「配列→構造体配列」に変換する
設定シート(例:ConfigTemplate)を読み込む汎用パターンです。
Private Function LoadRulesTemplate() As Variant
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("ConfigTemplate")
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
If lastRow < 2 Then
LoadRulesTemplate = Empty
Exit Function
End If
Dim data As Variant
data = ws.Range(ws.Cells(2, 1), ws.Cells(lastRow, 6)).Value
Dim rules() As RuleTemplate
ReDim rules(1 To UBound(data, 1))
Dim i As Long
For i = 1 To UBound(data, 1)
rules(i).Enabled = (UCase$(CStr(data(i, 1))) = "Y")
rules(i).SourceSheet = CStr(data(i, 2))
rules(i).TargetSheet = CStr(data(i, 3))
rules(i).Param1 = CStr(data(i, 4))
rules(i).Param2 = CStr(data(i, 5))
rules(i).Param3 = CStr(data(i, 6))
Next
LoadRulesTemplate = rules
End Function
VBここでのポイントは、
- 設定シートは「2行目から下」をデータとして読む
- Variant配列で一気に読み込む(高速)
- 1行ずつ構造体に詰める
という“型”を毎回使い回すことです。
共通:高速化ラッパー
これはもう、お約束としてテンプレにしてしまってOKです。
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共通:メインエントリーポイント
どのツールでも、メインはほぼこの形になります。
Public Sub RunTemplate()
Dim rules As Variant
rules = LoadRulesTemplate()
If IsEmpty(rules) Then
MsgBox "ConfigTemplateに設定がありません。", vbInformation
Exit Sub
End If
SpeedOn
Dim i As Long
For i = LBound(rules) To UBound(rules)
If rules(i).Enabled Then
ApplyOneRuleTemplate rules(i)
End If
Next i
SpeedOff
MsgBox "処理が完了しました。", vbInformation
End Sub
VBそして、心臓部は「1ルールを適用する」プロシージャです。
Private Sub ApplyOneRuleTemplate(ByRef rule As RuleTemplate)
' ここに「ルール1件分の処理」を書く
' rule.SourceSheet, rule.TargetSheet, rule.Param1…を使って動く
End Sub
VBこの「Load → For Each Rule → ApplyOneRule」という流れが、
設定シート方式テンプレの“背骨”になります。
例題:設定シート方式で「簡易コピーエンジン」を作る
抽象的な話だけだとイメージしづらいので、
一番シンプルな「列コピーエンジン」を設定シート方式で作ってみます。
設定シートの設計(ConfigCopy)
ConfigCopy シートに、次の列を用意します。
- A列:Enabled(Y の行だけ処理)
- B列:SourceSheet
- C列:SourceCol
- D列:TargetSheet
- E列:TargetCol
例:
| A | B | C | D | E |
|---|---|---|---|---|
| Y | Sheet1 | A | Sheet2 | B |
| Y | Sheet1 | C | Sheet2 | D |
意味はこうです。
- 1行目:Sheet1!A列を Sheet2!B列にコピー
- 2行目:Sheet1!C列を Sheet2!D列にコピー
Rule構造体を「コピー用」に具体化する
Private Type CopyRule
Enabled As Boolean
SourceSheet As String
SourceCol As Long
TargetSheet As String
TargetCol As Long
End Type
VBConfigCopy を読み込む
Private Function LoadCopyRules() As Variant
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("ConfigCopy")
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
If lastRow < 2 Then
LoadCopyRules = Empty
Exit Function
End If
Dim data As Variant
data = ws.Range(ws.Cells(2, 1), ws.Cells(lastRow, 5)).Value
Dim rules() As CopyRule
ReDim rules(1 To UBound(data, 1))
Dim i As Long
For i = 1 To UBound(data, 1)
rules(i).Enabled = (UCase$(CStr(data(i, 1))) = "Y")
rules(i).SourceSheet = CStr(data(i, 2))
rules(i).SourceCol = ColToNumber(data(i, 3))
rules(i).TargetSheet = CStr(data(i, 4))
rules(i).TargetCol = ColToNumber(data(i, 5))
Next
LoadCopyRules = rules
End Function
VB1ルール分のコピー処理
Private Sub ApplyCopyRule(ByRef rule As CopyRule)
Dim wsS As Worksheet, wsT As Worksheet
Set wsS = ThisWorkbook.Worksheets(rule.SourceSheet)
On Error Resume Next
Set wsT = ThisWorkbook.Worksheets(rule.TargetSheet)
On Error GoTo 0
If wsT Is Nothing Then
Set wsT = ThisWorkbook.Worksheets.Add
wsT.Name = rule.TargetSheet
End If
Dim lastRow As Long
lastRow = wsS.Cells(wsS.Rows.Count, rule.SourceCol).End(xlUp).Row
If lastRow < 1 Then Exit Sub
wsT.Range(wsT.Cells(1, rule.TargetCol), wsT.Cells(lastRow, rule.TargetCol)).Value = _
wsS.Range(wsS.Cells(1, rule.SourceCol), wsS.Cells(lastRow, rule.SourceCol)).Value
End Sub
VBメイン
Public Sub RunCopyEngine()
Dim rules As Variant
rules = LoadCopyRules()
If IsEmpty(rules) Then
MsgBox "ConfigCopyに設定がありません。", vbInformation
Exit Sub
End If
SpeedOn
Dim i As Long
For i = LBound(rules) To UBound(rules)
If rules(i).Enabled Then
ApplyCopyRule rules(i)
End If
Next i
SpeedOff
MsgBox "コピー処理が完了しました。", vbInformation
End Sub
VBこれで、「設定シートに行を足すだけでコピー内容を増やせる」ツールができます。
この“型”を、JOIN・集計・変換・差分…にそのまま横展開していくイメージです。
重要ポイントの深掘り:設定シート方式を“武器”にするための考え方
1:まず「設定で表現できるか?」と自分に問いかける
新しいマクロを作るとき、いきなりコードを書き始めるのではなく、
一度立ち止まってこう考えてみてください。
- これは「ルールの組み合わせ」で表現できないか?
- そのルールを「1行=1ルール」の表に落とせないか?
もし「はい」と言えるなら、それは設定シート方式の出番です。
逆に、「ユーザーの操作に応じて分岐しまくるUI系マクロ」などは、設定シート方式には向きません。
2:構造体を“ちゃんと定義する”ことをサボらない
初心者ほど、配列やVariantのままゴリゴリ書きがちですが、
設定シート方式では「構造体(Type)」をきちんと定義することが、
読みやすさ・保守性の決定的な差になります。
- JoinRule
- AggRule
- ConvRule
- DiffRule
こういう“ルールの顔”をちゃんと作ってあげると、
コードを読むときに「何をやっているのか」が一瞬で分かるようになります。
3:検証(バリデーション)をテンプレに組み込む
設定シート方式の弱点は、「設定ミスがそのままバグになる」ことです。
だからこそ、テンプレの中に「検証フェーズ」を最初から組み込んでおくと強いです。
- シート名が存在するか
- 列番号が妥当か
- 関数名(TransformNameなど)が存在するか
- Mode や AggFunc が許可された値か
これをチェックする ValidateRules(rules) のようなプロシージャを用意して、
メインの最初で必ず呼ぶ——ここまでを“型”にしてしまうと、
現場での事故が一気に減ります。
まとめ:「設定シート方式テンプレ」は“全部のノーコード系ツールの土台”
あなたがここまで作ってきた(あるいはこれから作る)ツールたち——
- ノーコードJOINツール
- ノーコード集計ツール
- ノーコード差分ツール
- ノーコード変換ツール
これらは全部、「設定シート方式テンプレ」の上に乗っています。
- 設定シートで“何をしたいか”を表にする
- 構造体で“ルールの顔”を定義する
- 汎用エンジンで“ルールをなぞるだけ”のコードを書く
この3ステップを“癖”にしてしまえば、
新しい業務が来ても「また1からマクロを書く」のではなく、
「この業務を設定シートに落とすとしたら、どんな列が必要か?」という思考に変わります。
