目次
はじめに
VBAプロジェクトが大規模になってくると、「このモジュールに、どんなマクロを書いたか忘れてしまった」「マクロの仕様書を作るために、プロシージャ名の一覧が欲しい」といった場面が出てきます。
VBAの VBProject
オブジェクトと、正規表現(VBScript.RegExp
)を組み合わせることで、指定したモジュール内に記述されている全ての Sub
と Function
の名前を抽出し、一覧としてワークシートに書き出すことが可能です。
この記事では、VBAコードをテキストとして読み込み、正規表現を使ってマクロ名の一覧を自動生成するという、高度で実用的なテクニックを解説します。
【重要】事前準備
このマクロを実行するには、以下の2つの事前設定が必要です。
- VBAプロジェクトへのアクセスの有効化: Excelの「ファイル」→「オプション」→「トラストセンター」→「マクロの設定」で、「VBAプロジェクト オブジェクト モデルへのアクセスを信頼する」をオンにします。
- 参照設定: VBEの「ツール」→「参照設定」で、「Microsoft VBScript Regular Expressions 5.5」にチェックを入れます。
モジュール内のマクロ一覧を作成するVBAサンプルコード
このマクロは、「MyMacros
」という名前の標準モジュールを対象に、全ての Sub
と Function
の名前と種類を抽出し、「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番目の()
はSub
かFunction
に一致するため、SubMatches(1)
で種類を取得できます。(SubMatches
のインデックスは0から始まります)match.SubMatches(2)
: 同様に、3番目の()
がプロシージャ名に一致するため、SubMatches(2)
で名前を取得できます。
まとめ
今回は、VBAの CodeModule
オブジェクトと正規表現を組み合わせて、モジュール内のマクロ定義を自動でリストアップするという、非常に高度なテクニックを解説しました。
VBProject.VBComponents("...").CodeModule
で、モジュールのコードにアクセスできる。- 正規表現を使えば、コードの中から特定のパターン(
Sub
/Function
の定義行)を効率的に探し出せる。
この手法を応用すれば、マクロの仕様書を半自動で作成したり、コーディング規約に沿っているかをチェックしたりと、VBA開発の生産性を向上させるための様々なツールを自作することが可能になります。