実務で超使える 「列ごとに自由な計算式を設定できる汎用高速マクロ」 を作ります。
ポイントは次の通り:
- 範囲を自動検出して 配列で読み込み → 配列で処理 → 一括書き戻し(超高速)
- 列ごとに「モード」と「パラメータ」を設定でき、よく使う処理はプリセットで選べる
- より複雑なら ユーザー定義マクロ(Custom) を呼び出して拡張可能
- 実行前に画面更新・再計算をオフにして高速化、終了時に復元
下に「そのまま使えるテンプレコード」と「設定例」「カスタム関数の書き方」「使い方メモ」を付けます。コピペで使って、設定部分を書き換えれば OK です。
フルコード(コピペで動くテンプレ)
Option Explicit
' 汎用高速マクロ(列ごとにモードを指定して処理)
Sub FastColumnProcessor()
Dim ws As Worksheet
Set ws = ActiveSheet ' 必要なら Sheets("データ") 等に変える
Dim lastRow As Long, lastCol As Long
If Application.WorksheetFunction.CountA(ws.Cells) = 0 Then
MsgBox "シートにデータがありません。", vbExclamation
Exit Sub
End If
' --- 自動範囲検出(ヘッダー1行、データ2行目から最終行まで想定) ---
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
lastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
If lastRow < 2 Then
MsgBox "データ行がありません。(2行目以降をデータ行と想定)", vbExclamation
Exit Sub
End If
Dim data As Variant
data = ws.Range(ws.Cells(2, 1), ws.Cells(lastRow, lastCol)).Value ' 2次元配列 (1-based)
Dim r As Long, c As Long
' --- 高速化設定 ---
Dim oldCalc As XlCalculation, oldScreen As Boolean, oldEnableEvents As Boolean
oldCalc = Application.Calculation
oldScreen = Application.ScreenUpdating
oldEnableEvents = Application.EnableEvents
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
On Error GoTo CleanUp
' --- 列ごとの設定(ここを編集) ---
' 設定の書式: ModeConfig(col) = "モード|パラメータ"
' モード例:
' "Multiply|2" : 数値を2倍
' "FillIfEmpty|未入力" : 空白なら指定文字で埋める
' "CheckThreshold|100" : >=閾値なら "OK" それ以外 "NG"
' "Concat|1,2" : 同じ行の列1と列2を結合(列番号はカンマ区切り)
' "Formula|=A{r}+B{r}" : 文字列の式を評価してセルに代入({r} は1行目=データ配列の1に対応)
' "Custom|Module1.MyFunc": 自作プロシージャを呼ぶ(戻り値をセルに入れる)
' 空白 = その列は処理しない
Dim ModeConfig() As Variant
ReDim ModeConfig(1 To lastCol)
' --- ここを用途に合わせて書き換える --- (例)
' Col 1: 数値を2倍
ModeConfig(1) = "Multiply|2"
' Col 2: 空白なら「未入力」で埋める
ModeConfig(2) = "FillIfEmpty|未入力"
' Col 3: 閾値100で OK/NG
ModeConfig(3) = "CheckThreshold|100"
' Col 4: 列1と列2を結合(例)
ModeConfig(4) = "Concat|1,2"
' Col 5: 任意のExcel式を評価(例:A列 + B列、ただし {r} を行に置換)
ModeConfig(5) = "Formula|=RC[-4] & ""-"" & RC[-3]" ' R1C1 相対式の例(別方法あり)
' Col 6: カスタム関数呼び出しの例(Module1 の MyCustom(colValue, rowArray) を呼ぶ)
ModeConfig(6) = "Custom|Module1.MyCustom"
' --- メイン処理(配列内で完結) ---
Dim parts() As String, param As String, mode As String
Dim args() As String
Dim v As Variant
For r = 1 To UBound(data, 1) ' data の r は 1 = シート上の行2
For c = 1 To UBound(data, 2)
If IsEmpty(ModeConfig(c)) Then GoTo NextCol
parts = Split(CStr(ModeConfig(c)), "|")
mode = parts(0)
If UBound(parts) >= 1 Then
param = parts(1)
Else
param = ""
End If
v = data(r, c) ' 元の値
Select Case LCase(mode)
Case "multiply"
If IsNumeric(v) Then
data(r, c) = CDbl(v) * Val(param)
End If
Case "fillifempty"
If Trim(CStr(v)) = "" Then data(r, c) = param
Case "checkthreshold"
If IsNumeric(v) Then
If CDbl(v) >= Val(param) Then
data(r, c) = "OK"
Else
data(r, c) = "NG"
End If
Else
data(r, c) = "NG"
End If
Case "concat"
' param = "1,2" のように結合する列番号リスト
args = Split(param, ",")
Dim sb As String
sb = ""
Dim iCol As Long
For iCol = LBound(args) To UBound(args)
Dim srcCol As Long
srcCol = Val(Trim(args(iCol)))
If srcCol >= 1 And srcCol <= UBound(data, 2) Then
sb = sb & CStr(data(r, srcCol))
End If
Next iCol
data(r, c) = sb
Case "formula"
' param は文字列の式。プレースホルダ {r} を実際のシート行番号に置換して Evaluate
' 注意:Evaluate の参照はワークシート依存なので、簡単な式向け
Dim expr As String
' シート上の実行行番号を求める(ヘッダー1行のため)
Dim sheetRow As Long
sheetRow = r + 1
expr = Replace(param, "{r}", CStr(sheetRow))
' Evaluate 実行(ワークシートを基準にする)
On Error Resume Next
Dim evalRes As Variant
evalRes = ws.Evaluate(expr)
If Err.Number = 0 Then
data(r, c) = evalRes
End If
On Error GoTo 0
Case "custom"
' param = "Module1.MyFunc" 等。Application.Run で実行、戻り値を入れる
' 引数例: (セル値, 行配列 as Variant)
On Error Resume Next
Dim ret As Variant
' 行全体(この行の全列データ)を渡す場合:
ret = Application.Run(param, data(r, c), Application.Index(data, r, 0))
If Err.Number = 0 Then
data(r, c) = ret
Else
' エラー時は元の値を保持
Err.Clear
End If
On Error GoTo 0
Case Else
' 未定義モード → 何もしない
End Select
NextCol:
Next c
Next r
' --- 書き戻し ---
ws.Range(ws.Cells(2, 1), ws.Cells(lastRow, lastCol)).Value = data
CleanUp:
' --- 後処理(復元)---
Application.Calculation = oldCalc
Application.ScreenUpdating = oldScreen
Application.EnableEvents = oldEnableEvents
If Err.Number <> 0 Then
MsgBox "エラー発生: " & Err.Number & " - " & Err.Description, vbExclamation
End If
End Sub
VB使い方メモ(設定の仕方)
ModeConfig(列番号) = "モード|パラメータ"を編集します(列が多い場合はループで設定してもOK)。Modeの候補(コードで扱っているもの):Multiply|数値— 数値を掛ける(例:Multiply|2)FillIfEmpty|文字列— 空白なら埋める(例:FillIfEmpty|未入力)CheckThreshold|閾値— 数値 >=閾値 なら “OK”、それ以外は “NG”(例:CheckThreshold|100)Concat|1,2,3— 指定列を順に結合(例:Concat|1,2)Formula|式文字列—{r}をシート行に置換してEvaluate(注意点下記)Custom|ModuleName.ProcName—Application.Runでユーザ関数を呼ぶ(詳細下記)
カスタム関数の書き方(例)
Custom モードを使うと、より複雑な処理が可能です。呼ばれる側は Public なプロシージャ/関数で、Application.Run に対応したシグネチャにします。
' Module1 に置く例
Public Function MyCustom(cellValue As Variant, rowArray As Variant) As Variant
' 例:列1の値が "X" なら "特記事項" を返す
If UBound(rowArray) >= 1 Then
If CStr(rowArray(1)) = "X" Then
MyCustom = "特記事項"
Exit Function
End If
End If
' なければ元の値を返す
MyCustom = cellValue
End Function
VB- 呼び出しは
ModeConfig(6) = "Custom|Module1.MyCustom"のように指定します。 Application.Runはモジュール名を含めて呼ぶことを推奨します(シートのコードやクラスから呼ぶ場合は少し挙動が違います)。
注意点・実務Tips
FormulaモードはEvaluateを使うため、式の書き方に注意(参照方式によっては期待どおりに動かない)。可能なら R1C1 形式か、{r}プレースホルダで行番号を置換してから Evaluate する方法を使う。- データ内にエラー値(
#N/A等)があると Evaluate や数値判定で問題が発生することがあるので、必要なら事前にIsErrorでチェックを入れてください。 Application.Runは遅くはないが、呼び出し回数が多いとパフォーマンスに影響する。重いロジックは可能な限り配列内で完結させるのがベスト。- 大量データ(数十万行)を扱う場合はメモリに注意。64-bit Excel なら大きな配列でも扱いやすいです。
- 実行前に必ずバックアップ(元シートのコピー)を取っておくこと。
設定例(まとめ)
- A列(1):
Multiply|2→ 値を2倍 - B列(2):
FillIfEmpty|未入力→ 空白なら「未入力」 - C列(3):
CheckThreshold|100→ >=100 → OK / else NG - D列(4):
Concat|1,2→ 同行の A+B を結合して D に入れる - E列(5):
Formula|=A{r}+B{r}→ A列+B列の計算を評価({r} を行番号に置換) - F列(6):
Custom|Module1.MyCustom→ カスタム関数を呼ぶ


