【VBA】モジュール内のマクロ名一覧を正規表現で取得し、シートに書き出す方法

目次

はじめに

VBAプロジェクトが大規模になってくると、「このモジュールに、どんなマクロを書いたか忘れてしまった」「マクロの仕様書を作るために、プロシージャ名の一覧が欲しい」といった場面が出てきます。

VBAの VBProject オブジェクトと、正規表現VBScript.RegExp)を組み合わせることで、指定したモジュール内に記述されている全ての SubFunction の名前を抽出し、一覧としてワークシートに書き出すことが可能です。

この記事では、VBAコードをテキストとして読み込み、正規表現を使ってマクロ名の一覧を自動生成するという、高度で実用的なテクニックを解説します。


【重要】事前準備

このマクロを実行するには、以下の2つの事前設定が必要です。

  1. VBAプロジェクトへのアクセスの有効化: Excelの「ファイル」→「オプション」→「トラストセンター」→「マクロの設定」で、「VBAプロジェクト オブジェクト モデルへのアクセスを信頼する」をオンにします。
  2. 参照設定: VBEの「ツール」→「参照設定」で、「Microsoft VBScript Regular Expressions 5.5」にチェックを入れます。

モジュール内のマクロ一覧を作成するVBAサンプルコード

このマクロは、「MyMacros」という名前の標準モジュールを対象に、全ての SubFunction の名前と種類を抽出し、「MacroList」シートのA列とB列に書き出します。

完成コード

' 指定したモジュール内のプロシージャ(Sub/Function)一覧を作成する
Sub CreateProcedureList()
    Const TARGET_MODULE_NAME As String = "MyMacros" '対象のモジュール名
    
    Dim vbc As VBIDE.VBComponent
    Dim code As VBIDE.CodeModule
    Dim codeText As String
    Dim regex As VBScript_RegExp.RegExp
    Dim matches As VBScript_RegExp.MatchCollection
    Dim match As VBScript_RegExp.Match
    Dim outputSheet As Worksheet
    Dim rowNum As Long
    
    '--- 1. モジュールのコードをテキストとして取得 ---
    On Error Resume Next
    Set vbc = ThisWorkbook.VBProject.VBComponents(TARGET_MODULE_NAME)
    On Error GoTo 0
    If vbc Is Nothing Then
        MsgBox "モジュール「" & TARGET_MODULE_NAME & "」が見つかりません。", vbCritical
        Exit Sub
    End If
    Set code = vbc.CodeModule
    codeText = code.Lines(1, code.CountOfLines)
    
    '--- 2. 正規表現でSub/Functionの行を検索 ---
    Set regex = New VBScript_RegExp.RegExp
    With regex
        .Global = True      ' 文字列全体を検索
        .MultiLine = True   ' 複数行モード
        ' パターン: (Public/Private/Function/Sub)で始まり、プロシージャ名が続く行
        .Pattern = "^(Public |Private )?(Sub|Function)\s+([a-zA-Z0-9_]+)\("
    End With
    Set matches = regex.Execute(codeText)
    
    '--- 3. 結果を出力シートに書き出し ---
    Set outputSheet = ThisWorkbook.Worksheets("MacroList")
    outputSheet.Cells.ClearContents
    outputSheet.Range("A1:B1").Value = Array("種類", "プロシージャ名")
    rowNum = 2
    
    For Each match In matches
        ' SubMatches(1)が "Sub" or "Function"
        outputSheet.Cells(rowNum, "A").Value = match.SubMatches(1)
        ' SubMatches(2)が プロシージャ名
        outputSheet.Cells(rowNum, "B").Value = match.SubMatches(2)
        rowNum = rowNum + 1
    Next match
    
    MsgBox "マクロ一覧の作成が完了しました。"

End Sub

コードの解説

1. モジュールコードの取得

  • Set code = vbc.CodeModule: VBComponent(この場合はモジュール)の .CodeModule プロパティを通じて、そのモジュールに書かれているコード全体にアクセスします。
  • codeText = code.Lines(1, code.CountOfLines): .Lines プロパティを使って、指定した範囲の行(この場合は1行目から最終行まで)のコードを、一つの長い文字列として取得しています。

2. 正規表現による検索

  • Set regex = New VBScript_RegExp.RegExp: 正規表現オブジェクトを生成します。
  • .Pattern = "^(Public |Private )?(Sub|Function)\s+([a-zA-Z0-9_]+)\(": これが検索パターンです。
    • ^: 行の先頭
    • (Public |Private )?: PublicまたはPrivateが、あってもなくても良い
    • (Sub|Function): SubまたはFunctionという単語
    • \s+: 1つ以上のスペース
    • ([a-zA-Z0-9_]+): 英数字とアンダースコアからなるプロシージャ名(これが取得したい部分)
    • \(: 直後に続く開きカッコ
  • Set matches = regex.Execute(codeText): パターンに一致した全ての箇所が、matches コレクションに格納されます。

3. 結果の書き出し

  • match.SubMatches(1): SubMatches は、パターンの中で () で囲んだ部分(キャプチャグループ)に一致した文字列を返します。2番目の ()SubFunction に一致するため、SubMatches(1) で種類を取得できます。(SubMatchesのインデックスは0から始まります)
  • match.SubMatches(2): 同様に、3番目の () がプロシージャ名に一致するため、SubMatches(2) で名前を取得できます。

まとめ

今回は、VBAの CodeModule オブジェクトと正規表現を組み合わせて、モジュール内のマクロ定義を自動でリストアップするという、非常に高度なテクニックを解説しました。

  • VBProject.VBComponents("...").CodeModule で、モジュールのコードにアクセスできる。
  • 正規表現を使えば、コードの中から特定のパターン(Sub/Functionの定義行)を効率的に探し出せる。

この手法を応用すれば、マクロの仕様書を半自動で作成したり、コーディング規約に沿っているかをチェックしたりと、VBA開発の生産性を向上させるための様々なツールを自作することが可能になります。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次