Excel VBA 逆引き集 | 実務テンプレ完全版(超再利用部品) – ノーコード変換ツール

Excel VBA
スポンサーリンク

ねらい:「置換・整形・コード変換」を“設定だけ”で回すノーコード変換エンジン

「この列の全角を半角にしたい」
「このコードを名称に変えたい」
「この文字列の一部を置き換えたい」
「日付の書式を統一したい」

こういう“変換作業”って、現場だと本当に多いですよね。
毎回、関数を組んだり、マクロを書き換えたりしていると、
同じような処理が量産されて、どれが最新か分からなくなります。

ノーコード変換ツールのゴールはシンプルです。

  • どのシートの
  • どの列を
  • どの列に
  • どんな変換をかけるか

これを全部「設定シート」に書くだけで、VBAのコードは一切触らずに変換が走るようにすること。
コードは「汎用変換エンジン」として一度だけ作り、
変換内容は「設定シート」で差し替える——この分離を徹底します。


全体設計:変換設定シート+変換関数群+汎用エンジン

シート構成のイメージ

基本はこの三つです。

  • Source シート: 元データを貼る場所(CSV貼り付けなど)
  • Target シート: 変換後のデータを出す場所
  • ConfigConv シート: 「どの列にどんな変換をかけるか」を書く設定シート

VBA側は、

  • ConfigConv を読み込む
  • Source から値を読み、指定された変換関数を通す
  • Target に書き出す

という“エンジン”だけを持ちます。
「どの列に何をするか」は、すべて ConfigConv に書きます。


変換設定シートの設計:1行=1つの変換ルール

ConfigConv の列構成

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

  • A列:Enabled(Y の行だけ処理)
  • B列:SourceSheet(元シート名)
  • C列:SourceCol(元列。番号でも A,B,C…でもOK)
  • D列:TargetSheet(出力シート名)
  • E列:TargetCol(出力列)
  • F列:TransformName(使う変換関数名)
  • G列:Options(変換オプション文字列。必要な場合だけ)

イメージはこんな感じです。

ABCDEFG
YSourceATargetATrimText
YSourceBTargetBToNarrow
YSourceCTargetCMapCodeAreaMaster
YSourceDTargetDReplaceText/-/→/~/

それぞれの意味をかみ砕くとこうです。

  • 1行目: Source!A列を TrimText して Target!A列へ
  • 2行目: Source!B列を ToNarrow(全角→半角)して Target!B列へ
  • 3行目: Source!C列を MapCode(コード→名称)で変換し、AreaMaster というマスタを使って Target!C列へ
  • 4行目: Source!D列を ReplaceText で「- を ~ に置換」して Target!D列へ

重要なのは、「変換の中身は一切コードに書かない」ことです。
どの列にどの関数を使うかは、全部ここに書きます。


変換関数群:1セルを受けて1セル返す“小さな部品”を揃える

共通ルール:全部「Function(値, オプション) As Variant」に揃える

汎用エンジンから呼びやすくするために、変換関数はすべて

Public Function XxxTransform(ByVal v As Variant, Optional ByVal opt As String = "") As Variant
    ' …
End Function
VB

という形に揃えます。
つまり、

  • 引数1: 変換前の値(Variant)
  • 引数2: オプション文字列(必要なら使う)
  • 戻り値: 変換後の値(Variant)

この“インターフェースを揃える”のが、ノーコード化の超重要ポイントです。

前後スペース削除(TrimText)

' ModTransforms.bas
Option Explicit

Public Function TrimText(ByVal v As Variant, Optional ByVal opt As String = "") As Variant
    If IsError(v) Then
        TrimText = v
    ElseIf IsNull(v) Or v = "" Then
        TrimText = v
    Else
        TrimText = Trim$(CStr(v))
    End If
End Function
VB

初心者向けポイント:

  • IsError: セルにエラー(#N/A など)が入っている場合は、そのまま返す
  • Null や空文字: 何もしない
  • それ以外は文字列にして Trim$

これで、「余計なスペースだけ消す安全な関数」になります。

全角英数字→半角(ToNarrow)

Public Function ToNarrow(ByVal v As Variant, Optional ByVal opt As String = "") As Variant
    If IsError(v) Then
        ToNarrow = v
    ElseIf IsNull(v) Or v = "" Then
        ToNarrow = v
    Else
        ToNarrow = StrConv(CStr(v), vbNarrow)
    End If
End Function
VB

ポイント:

  • StrConv(vbNarrow) で全角英数字を半角に
  • ひらがな・カタカナはそのまま(必要なら別関数を作る)

文字列置換(ReplaceText)

Options に「検索文字→置換文字」を書く形にします。
例: /-/→/~/ なら、「- を ~ に置換」。

Public Function ReplaceText(ByVal v As Variant, Optional ByVal opt As String = "") As Variant
    If IsError(v) Then
        ReplaceText = v
        Exit Function
    End If
    
    If opt = "" Then
        ReplaceText = v
        Exit Function
    End If
    
    Dim parts As Variant
    parts = Split(opt, "→")
    If UBound(parts) <> 1 Then
        ReplaceText = v
        Exit Function
    End If
    
    Dim fromStr As String, toStr As String
    fromStr = Mid$(parts(0), 2, Len(parts(0)) - 2) ' /-/ の中身を取り出すイメージ
    toStr = Mid$(parts(1), 2, Len(parts(1)) - 2)
    
    ReplaceText = Replace(CStr(v), fromStr, toStr)
End Function
VB

ここは好みでシンプルにしてもOKです。
大事なのは、「オプション文字列で置換内容を変えられる」こと。

コード→名称(MapCode)

ここが実務で一番“効く”変換です。
Options に「マスタシート名」を渡し、そのマスタを使ってコードを名称に変えます。

マスタシート(例:AreaMaster)はこういう構成を想定します。

  • A列: コード
  • B列: 名称

まず、マスタを Dictionary に載せる関数を作ります。

Private Function LoadMasterDict(ByVal sheetName As String) As Object
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets(sheetName)
    
    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
    
    Dim dict As Object
    Set dict = CreateObject("Scripting.Dictionary")
    dict.CompareMode = 1
    
    Dim r As Long
    Dim key As String
    For r = 2 To lastRow
        key = CStr(ws.Cells(r, 1).Value)
        If key <> "" Then
            If Not dict.Exists(key) Then
                dict.Add key, ws.Cells(r, 2).Value
            End If
        End If
    Next
    
    Set LoadMasterDict = dict
End Function
VB

次に、MapCode 本体です。

Public Function MapCode(ByVal v As Variant, Optional ByVal opt As String = "") As Variant
    If IsError(v) Then
        MapCode = v
        Exit Function
    End If
    
    If opt = "" Then
        MapCode = v
        Exit Function
    End If
    
    Static cache As Object
    Static cacheName As String
    
    If cache Is Nothing Or cacheName <> opt Then
        Set cache = LoadMasterDict(opt)
        cacheName = opt
    End If
    
    Dim key As String
    key = CStr(v)
    
    If cache.Exists(key) Then
        MapCode = cache(key)
    Else
        MapCode = "#未定義:" & key
    End If
End Function
VB

ここが重要な“プロっぽいポイント”です。

  • Static cache: 一度読み込んだマスタをキャッシュして、何度も読み直さない
  • opt でマスタ名を切り替え: AreaMaster でも DeptMaster でも、同じ MapCode で対応できる
  • 未定義コードの扱い: 「#未定義:コード」で後からフィルタしやすくする

汎用変換エンジン:ConfigConv を読んで一括変換

列記号を列番号に変換する関数

ConfigConv では C列に「A」「B」「3」など、列記号でも番号でも書けるようにしておきます。

' ModConvEngine.bas
Option Explicit

Private 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行分の型

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
VB

ConfigConv からルール配列を読み込む

Private Function LoadConvRules() As Variant
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("ConfigConv")
    
    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
    If lastRow < 2 Then
        LoadConvRules = Empty
        Exit Function
    End If
    
    Dim data As Variant
    data = ws.Range(ws.Cells(2, 1), ws.Cells(lastRow, 7)).Value
    
    Dim rules() As ConvRule
    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))
        rules(i).TransformName = CStr(data(i, 6))
        rules(i).Options = CStr(data(i, 7))
    Next
    
    LoadConvRules = rules
End Function
VB

高速化用の“お作法”

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 RunConvTool()
    Dim rules As Variant
    rules = LoadConvRules()
    If IsEmpty(rules) Then
        MsgBox "ConfigConvに変換設定がありません。", vbInformation
        Exit Sub
    End If
    
    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
    MsgBox "ノーコード変換ツールの処理が完了しました。", vbInformation
End Sub
VB

1つの変換ルールを適用する処理

ここが心臓部です。

Private Sub ApplyConvRule(ByRef rule As ConvRule)
    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 < 2 Then Exit Sub
    
    Dim r As Long
    Dim srcVal As Variant
    Dim outVal As Variant
    
    For r = 2 To lastRow
        srcVal = wsS.Cells(r, rule.SourceCol).Value
        
        If rule.TransformName <> "" Then
            outVal = Application.Run(rule.TransformName, srcVal, rule.Options)
        Else
            outVal = srcVal
        End If
        
        wsT.Cells(r, rule.TargetCol).Value = outVal
    Next
End Sub
VB

重要ポイントを整理します。

  • どの関数を呼ぶかrule.TransformName に書いてある
  • オプションrule.Options で渡す
  • エンジン側は「Application.Run で呼ぶだけ」で、中身は一切知らない
  • Source と Target の行番号を揃えているので、「同じ行構造の変換」に向いている

例題:顧客CSVを「整形済み顧客マスタ」に変換する

元データ(Source)

システムから出力された顧客CSVを Source シートに貼るとします。

  • A列:顧客コード(前後スペースあり)
  • B列:顧客名(全角・半角混在)
  • C列:地域コード(01,02,03…)
  • D列:備考(「-」を「~」に変えたい)

変換後(Target)で欲しい形

  • A列:顧客コード(Trim済み)
  • B列:顧客名(全角→半角)
  • C列:地域名(コード→名称)
  • D列:備考(「-」→「~」置換済み)

ConfigConv の設定例

ABCDEFG
YSourceATargetATrimText
YSourceBTargetBToNarrow
YSourceCTargetCMapCodeAreaMaster
YSourceDTargetDReplaceText/-/→/~/

AreaMaster シートはこういう感じです。

  • A列:地域コード(01,02,03…)
  • B列:地域名(東京、大阪、名古屋…)

あとは、Source にCSVを貼って RunConvTool を実行するだけ。
VBAのコードは一切触りません。


重要ポイントの深掘り:「ノーコード変換」を本当に現場で回すための工夫

変換関数を“増やしやすい形”にしておく

現場で使っていると、必ずこういう要望が出てきます。

  • 日付を「yyyy/mm/dd」に統一したい
  • 空欄なら「未設定」と入れたい
  • 数値を千円単位に丸めたい

そのたびに新しい変換関数を追加することになりますが、
インターフェースを揃えておけば、やることはシンプルです。

  • Public Function Xxx(ByVal v As Variant, Optional ByVal opt As String = "") As Variant で作る
  • ConfigConv の TransformName にその名前を書く
  • 必要なら Options で細かい指定を渡す

エンジン側は一切変更不要——ここが“再利用部品”としての強さです。

ConfigConv の「検証」を入れておく

ノーコードにすると、設定ミスも起こりやすくなります。

  • 存在しないシート名を書いてしまう
  • 列記号を間違える
  • TransformName をタイプミスする

実務で使うなら、RunConvTool の最初に

  • SourceSheet/TargetSheet が存在するか
  • SourceCol/TargetCol が有効な列か
  • TransformName が実在する関数か

をチェックして、問題があれば処理を止めてメッセージを出す“安全装置”を付けておくと安心です。

「変換」と「JOIN」「集計」「差分」を組み合わせる

ここまで来ると、あなたが作ってきた他のノーコード系テンプレと組み合わせたくなります。

  • まずノーコード変換ツールで「生データを整形」
  • その結果をノーコードJOINツールでマスタと結合
  • さらにノーコード集計ツールで集計
  • 最後にノーコード差分ツールで前回との違いを確認

全部「設定シート」で制御できるようにしておけば、
現場の担当者は「設定を変える」だけで、かなり高度な処理フローを回せるようになります。


まとめ:ノーコード変換ツールは「Config × Transform × Engine」の三位一体

このテンプレの核は、たった三つです。

  • ConfigConv: どのシートのどの列に、どの変換関数を、どんなオプションでかけるかを全部“表”に書く
  • Transform モジュール: 1セルを受けて1セル返す“小さな変換関数”を並べる(Trim, ToNarrow, MapCode, ReplaceText…)
  • Engine モジュール: ConfigConv を読み、Transform を呼びながら Source → Target に書き出すだけの汎用エンジン

この型さえ一度作ってしまえば、
「また似たような整形マクロを書いている…」という時間はほぼゼロにできます。

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