ねらい:どの業務でも「壊れず速く保守しやすい」最強テンプレ構造を手に入れる
最強テンプレ構造とは、VBAをどの業務にも安全に載せ替えられる「設計の型」です。開始・終了の共通枠、設定の外出し、配列I/O、ロジック純粋化、進捗・ログ・エラー復帰、そして入口統一。この型に沿えば、初心者でも貼って動かしながら拡張できます。ここでは、実務で即使えるテンプレをH2〜H4の見出しで体系的に示し、重要箇所は理由まで深掘り解説します。
重要ポイントの深掘り
最強テンプレでは「枠が先、ロジックは後」が鉄則です。最初に環境復帰・設定読み取り・進捗・ログの枠を用意し、そこに業務ロジックを載せます。こうすることで、失敗しても復帰でき、運用差異にも強く、拡張時の修正範囲が明確になります。配列I/Oとロジック純粋化は速度とテスト容易性の核です。
全体構造のゴール像
役割分割で見えるコードにする
モジュールは役割別に分けます。基盤(開始・終了)、設定(Config)、入出力(IO)、業務ロジック(Logic)、業務フロー(Service)、進捗(Progress)、ログ(Log)、ファイル関連(File)。入口はServiceのRun_XXXXに集約し、UIボタンはそこだけを呼びます。
依存の向きを固定して壊れにくくする
UI(ボタン)→Service(業務フロー)→Logic(純粋関数)/IO(配列I/O)/Config(設定読み取り)/Progress/Log。逆流(Logicがセルを触る、Serviceが直接UserForm制御)は禁止します。依存が綺麗だと、列変更やルール変更に強くなります。
共通基盤(開始・終了・例外復帰)
開始・終了の枠を必ず通す
' ModApp
Option Explicit
Public Sub AppEnter(Optional ByVal status As String = "")
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
If Len(status) > 0 Then Application.StatusBar = status
End Sub
Public Sub AppLeave()
Application.StatusBar = False
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
VB重要ポイントの深掘り
この枠は「Finally」です。どこでエラーが起きても必ず復帰します。描画・イベント・再計算を止めるだけでも体感速度が上がりますが、最も重要なのは「失敗時に環境が戻る安心感」。業務で怖さが消えます。
設定外出し(Config)
キーで読み、型を検証する
' ModConfig
Option Explicit
Private Function ConfigSheet() As Worksheet
Set ConfigSheet = ThisWorkbook.Worksheets("Config")
End Function
Public Function GetConfigString(ByVal key As String) As String
Dim ws As Worksheet: Set ws = ConfigSheet()
Dim last As Long: last = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Dim r As Long
For r = 2 To last
If StrComp(CStr(ws.Cells(r, "A").Value), key, vbTextCompare) = 0 Then
GetConfigString = Trim$(CStr(ws.Cells(r, "B").Value))
Exit Function
End If
Next
Err.Raise 900, , "Configキーが見つかりません: " & key
End Function
Public Function GetConfigNumber(ByVal key As String) As Double
Dim s As String: s = GetConfigString(key)
If Not IsNumeric(s) Then Err.Raise 901, , "数値ではありません: " & key & "=" & s
GetConfigNumber = CDbl(s)
End Function
VB重要ポイントの深掘り
定数直書きを捨て、Configを唯一の真実にします。運用差異はConfigだけで吸収でき、配布し直す必要がなくなります。型検証を入口で行い、誤設定は即停止(Fail Fast)すると調査コストが激減します。
入出力(IO)と業務ロジック(Logic)
Range→配列→一括書き戻しで速度と安定性を得る
' ModIO
Option Explicit
Public Function ReadRegion(ByVal topLeft As Range) As Variant
ReadRegion = topLeft.CurrentRegion.Value
End Function
Public Sub WriteArray(ByVal ws As Worksheet, ByVal topLeft As String, ByVal arr As Variant)
ws.Range(topLeft).Resize(UBound(arr, 1), UBound(arr, 2)).Value = arr
End Sub
VBロジックは純粋関数にしてテスト可能にする
' ModLogic
Option Explicit
Public Function NormalizeAndFlag(ByVal data As Variant, ByVal th As Double, ByVal scoreCol As Long) As Variant
Dim rows As Long: rows = UBound(data, 1)
Dim cols As Long: cols = UBound(data, 2)
Dim out() As Variant: ReDim out(1 To rows, 1 To cols + 1)
Dim c As Long: For c = 1 To cols: out(1, c) = data(1, c): Next
out(1, cols + 1) = "合格"
Dim r As Long
For r = 2 To rows
For c = 1 To cols
out(r, c) = Trim$(CStr(data(r, c)))
Next
out(r, cols + 1) = IIf(Val(out(r, scoreCol)) >= th, "○", "×")
Next
NormalizeAndFlag = out
End Function
VB重要ポイントの深掘り
配列I/Oは「遅さの根源(セル往復)」を断ちます。ロジックを純粋関数にすると、テストが容易になり、列順変更にも強くなります。業務ルールの変更はLogicだけ、列変更はIOだけ直す構造が最強です。
進捗・ログ・エラー復帰
進捗は1〜5%刻みでUI応答を保つ
' ModProgress
Option Explicit
Public Sub ProgressThrottled(ByVal cur As Long, ByVal total As Long, Optional ByVal label As String = "進捗")
If total <= 0 Then Exit Sub
Dim stepN As Long: stepN = Application.WorksheetFunction.Max(1, total \ 100)
If cur Mod stepN = 0 Then
Application.StatusBar = label & " " & Format(cur / total, "0%") & " (" & cur & "/" & total & ")"
DoEvents
End If
End Sub
VBログはStart・Finish・Errorの三点を必ず記録する
' ModLog
Option Explicit
Public Sub LogInfo(ByVal action As String, ByVal detail As String)
WriteLog "INFO", action, detail
End Sub
Public Sub LogError(ByVal action As String, ByVal detail As String)
WriteLog "ERROR", action, detail
End Sub
Private Sub WriteLog(ByVal level As String, ByVal action As String, ByVal detail As String)
Dim ws As Worksheet
On Error Resume Next
Set ws = ThisWorkbook.Worksheets("Log")
If ws Is Nothing Then Set ws = ThisWorkbook.Worksheets.Add: ws.Name = "Log"
On Error GoTo 0
Dim r As Long: r = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row + 1
ws.Cells(r, 1).Value = Format(Now, "yyyy-mm-dd HH:NN:SS")
ws.Cells(r, 2).Value = level
ws.Cells(r, 3).Value = action
ws.Cells(r, 4).Value = detail
End Sub
VB重要ポイントの深掘り
進捗は「体感の安心」、ログは「事実の記録」。この二つがあるだけで運用の不安が消え、障害調査が速くなります。エラー時は、AppLeave→LogError→通知の順番で必ず実行する「型」を入口に仕込んでおくのが肝です。
ファイル命名と出力の標準化
安全なファイル名とタイムスタンプで世代管理する
' ModFile
Option Explicit
Public Function SafeFileName(ByVal raw As String) As String
Dim s As String: s = Trim$(raw)
Dim bad: bad = Array("\","/",":","*","?","""","<",">","|")
Dim i As Long: For i = LBound(bad) To UBound(bad): s = Replace(s, bad(i), "_"): Next
SafeFileName = IIf(Len(s) = 0, "untitled", s)
End Function
Public Function BuildExportPath(ByVal folder As String, ByVal base As String, ByVal ext As String) As String
BuildExportPath = folder & SafeFileName(base) & "_" & Format(Now, "yyyy-mm-dd_HHNNSS") & "." & ext
End Function
Public Sub EnsureFolder(ByVal folderPath As String)
Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FolderExists(folderPath) Then fso.CreateFolder folderPath
End Sub
VB重要ポイントの深掘り
命名と出力場所が標準化されると、次工程への引き渡しがスムーズになります。禁則文字の除去と時刻付き命名は、上書き事故と探索コストを確実に減らします。フォルダ保証までセットで「失敗しない出力」を実現します。
入口統一(Service)とフルフローの例
Run_XXXXで開始し、枠・Config・IO・Logic・出力・ログまでを一気通貫にする
' ModService
Option Explicit
Public Sub Run_DailyScoreFlag()
On Error GoTo EH
AppEnter "日次合格判定"
LogInfo "Start", "DailyScoreFlag"
Dim inSheet As String: inSheet = GetConfigString("INPUT_SHEET")
Dim outSheet As String: outSheet = GetConfigString("OUTPUT_SHEET")
Dim th As Double: th = GetConfigNumber("THRESHOLD")
Dim scoreCol As Long: scoreCol = CLng(GetConfigNumber("SCORE_COL"))
Dim data As Variant: data = ReadRegion(Worksheets(inSheet).Range("A1"))
Dim out As Variant: out = NormalizeAndFlag(data, th, scoreCol)
WriteArray Worksheets(outSheet), "A1", out
LogInfo "Finish", outSheet
AppLeave
MsgBox "完了: 出力先 " & outSheet
Exit Sub
EH:
LogError "DailyScoreFlag", Err.Number & " - " & Err.Description
AppLeave
MsgBox "失敗: " & Err.Description, vbExclamation
End Sub
VB重要ポイントの深掘り
入口統一で「操作が一箇所に集約」され、手順書・教育・障害対応が圧倒的に楽になります。Configのキーで運用差異に対応しつつ、配列I/Oと純粋ロジックで速度と安定性を担保。ログで結果が記録されるため、後から辿れる仕組みになります。
CSV出力の標準部品(UTF-8・エスケープ)
文字化けと引用符問題を部品で解決する
' ModCsv
Option Explicit
Public Sub WriteCsv(ByVal path As String, ByVal arr As Variant)
Dim st As Object: Set st = CreateObject("ADODB.Stream")
st.Type = 2: st.Charset = "UTF-8": st.Open
Dim r As Long, c As Long
For r = 1 To UBound(arr, 1)
Dim line As String: line = ""
For c = 1 To UBound(arr, 2)
Dim s As String: s = Replace(CStr(arr(r, c)), """", """""")
line = line & IIf(c > 1, ",", "") & """" & s & """"
Next
st.WriteText line & vbCrLf
Next
st.SaveToFile path, 2
st.Close
Set st = Nothing
End Sub
VB重要ポイントの深掘り
CSVは現場で最も使われる交換形式です。UTF-8固定とダブルクォートのエスケープを部品化しておけば、毎回悩まず品質を一定にできます。I/Oが安定すると、フロー全体の信頼度が上がります。
テストと計測の最小セット
ロジック単体テストで「動作不変」を確認する
' ModTest
Option Explicit
Public Sub Test_NormalizeAndFlag()
Dim data(1 To 3, 1 To 5) As Variant
data(1, 1) = "EmpNo": data(1, 5) = "Score"
data(2, 1) = "0001": data(2, 5) = 80
data(3, 1) = "0002": data(3, 5) = 60
Dim out As Variant: out = NormalizeAndFlag(data, 70, 5)
Debug.Print out(2, 6) ' ○
Debug.Print out(3, 6) ' ×
End Sub
VB区間計測で効果を数値で見る
Public Sub Measure_Run()
Dim t As Double: t = Timer
Run_DailyScoreFlag
Debug.Print "Run_DailyScoreFlag:", Format(Timer - t, "0.000"), "s"
End Sub
VB重要ポイントの深掘り
「直して速くなった」「壊していない」の確認は、テストと計測が最短です。小さく回して積み上げると、初心者でも安心して改良できます。数値で効果が見えると、現場への説得力が上がります。
導入手順の道筋
先に枠を入れてからロジックを載せる
最初にModApp・ModConfig・ModIO・ModProgress・ModLogを作り、入口をRun_XXXXに統一します。その上で、配列I/Oと純粋ロジックへ差し替え、必要ならCSVやファイル命名の部品を追加します。テストと計測を用意して、変更のたびに確認します。
小さく導入して確実に前進する
長い処理を一気に置き換えず、重いループを配列化、次に前提検証、次にロジック純粋化と段階的に進めます。各段で動作不変を確かめ、ログに記録を残すと、後戻りがなくなります。
まとめ:枠が最強、ロジックは載せ換え自由
この最強テンプレ構造は「枠」の力で運用を守り、「配列I/O+純粋関数」で速度と保守性を両立します。入口統一・設定外出し・進捗・ログ・復帰が揃えば、どの業務でも安心してVBAを組み込めます。
