VBAサンプル集
VBAコードの全プロシージャー・プロパティ一覧を取得

ExcelマクロVBAの実用サンプル、エクセルVBA集と解説
最終更新日:2020-05-05

VBAコードの全プロシージャー・プロパティ一覧を取得


VBAの開発規模がある程度大きくなってくると、VBAソース管理の必要性を感じることもあると思います。
モジュールの数も増えてきて、プロシージャー・プロパティが膨大になってきます。
以下は、指定ブックの全モジュールの全プロシージャー・プロパティを一覧にするVBAサンプルです。


SubまたはFunctionプロシージャ、Property Get,Let,Setの種別や、プロシージャ等の直前コメントも取得するようにしています。

セキュリティについて

VBAでVBAプロジェクトを扱う為には、以下の設定が必要になります。

「ファイル」→「オプション」→「セキュリティ センター」→「セキュリティ センターの設定」→「マクロの設定」

VBA マクロ VBProject VBComponents

この「VBA プロジェクト オブジェクト モデルへのアクセスを信頼する」にチェックを付けてください。
ただし、セキュリティを弱くするので、
このようなVBAを実行するとき以外は、チェックを外しておくことをお勧めします。
このチェックを付けずに今回のVBAを実行すると以下のエラーとなります。

VBA マクロ VBProject VBComponents

VBAコードの全プロシージャー・プロパティ一覧を取得するVBAコード

標準モジュール


'Dictionaryにプロシージャー・プロパティ情報を格納
Public Sub getCodeModule(ByRef dicProcInfo As Dictionary, _
             ByVal wb As Workbook, _
             ByVal sMod As String)
  Dim cProcInfo As clsProcInfo
  Dim sProcName As String
  Dim sProcKey As String
  Dim iProcKind As Long
  Dim i As Long
  Dim VVC As Object
  Set VVC = wb.VBProject.VBComponents(sMod).CodeModule
  i = 1
  Do While i <= VVC.CountOfLines
    sProcName = VVC.ProcOfLine(i, iProcKind)
    sProcKey = sMod & "." & sProcName
    If sProcName <> "" Then
      If isProcLine(VVC.Lines(i, 1), sProcName) Then
        If Not dicProcInfo.Exists(sProcKey) Then
          Set cProcInfo = New clsProcInfo
          cProcInfo.ModName = sMod
          cProcInfo.ProcName = sProcName
          cProcInfo.ProcKind = iProcKind
          cProcInfo.LineNo = i
          cProcInfo.Comment = getProcComment(i, VVC)
          cProcInfo.Source = getProcSource(i, VVC)
          dicProcInfo.Add sProcKey, cProcInfo
        End If
      End If
    End If
    i = i + 1
  Loop
End Sub

'プロシージャー・プロパティ定義行かの判定
Private Function isProcLine(ByVal strLine As String, _
              ByVal ProcName As String) As Boolean
  strLine = " " & Trim(strLine)
  Select Case True
    Case Left(strLine, 1) = " '"
      isProcLine = False
    Case strLine Like "* Sub " & ProcName & "(*"
      isProcLine = True
    Case strLine Like "* Sub " & ProcName & " _"
      isProcLine = True
    Case strLine Like "* Function " & ProcName & "(*"
      isProcLine = True
    Case strLine Like "* Function " & ProcName & " _"
      isProcLine = True
    Case strLine Like "* Property * " & ProcName & "(*"
      isProcLine = True
    Case strLine Like "* Property * " & ProcName & " _"
      isProcLine = True
    Case Else
      isProcLine = False
  End Select
End Function

'継続行( _)全てを連結した文字列で返す
Private Function getProcSource(ByRef i As Long, _
                ByVal aCodeModule As Object) As String
  getProcSource = ""
  Dim sTemp As String
  Do
    sTemp = Trim(aCodeModule.Lines(i, 1))
    If Right(aCodeModule.Lines(i, 1), 2) = " _" Then
      sTemp = Left(sTemp, Len(sTemp) - 1)
    End If
    getProcSource = getProcSource & sTemp
    If Right(aCodeModule.Lines(i, 1), 2) <> " _" Then Exit Do
    i = i + 1
  Loop
End Function

'プロシージャーの直前のコメントを取得
Private Function getProcComment(ByVal i As Long, _
                ByVal aCodeModule As Object) As String
  getProcComment = ""
  i = i - 1
  Do While Left(aCodeModule.Lines(i, 1), 1) = "'"
    If getProcComment <> "" Then getProcComment = vbLf & getProcComment
    getProcComment = aCodeModule.Lines(i, 1) & getProcComment
    i = i - 1
  Loop
End Function

クラスモジュール:clsProcInfo
Option Explicit

Public ModName As String
Public ProcName As String
Public ProcKind As String
Public LineNo As Long
Public Source As String
Public Comment As String

Public Property Get ProcKindName() As String
  Select Case ProcKind
    Case 0
      ProcKindName = "Sub Function"
    Case 1
      ProcKindName = "Property Let"
    Case 2
      ProcKindName = "Property Set"
    Case 3
      ProcKindName = "Property Get"
  End Select
End Property

Public Property Get Scope() As String
  Select Case True
    Case Trim(Source) Like "Private *"
      Scope = "Private"
    Case Trim(Source) Like "Friend *"
      Scope = "Friend"
    Case Trim(Source) Like "Static *"
      Scope = "Static"
    Case Else
      Scope = "Public"
  End Select
End Property

参照設定
「ツール」→「参照設定」で、
Microsoft Scripting Runtime
これを参照設定して下さい。

参照設定しない場合は、
dicProcInfo As Object
としてください。

概要
プロシージャー・プロパティの一覧はDictionaryに入れています。

「getCodeModule」がメインの関数で、他はその中で使用している関数になります。
「プロシージャー・プロパティ定義行かの判定」が面倒な記述になっていますが、
以下のような紛れをなるべく除くための記述になります。
・プロシージャー名直後の改行
・コメント内でのプロシージャー名
・プロシージャーのCall
・プロパテイへの値設定・取得
いろいろなパターンがあり、今回のコードでも漏れがあるかもしれません。
正規表現を使ったりしたより良い判定方法もあると思います。
必要に応じて、適宜修正して使用してください。

コメントは、
プロシージャー・プロパティ直前に連続記述されているもののみ対象としています。

Dictionaryにしているので、
シートに出力するだけではなく、その他の用途でも使いやすいと思います。
Dictionaryのキーは、「モジュール名.プロシージャー名」にしていますので、簡単に検索できるはずです。

クラス使用の理由
ユーザー定義型(Type)はDictionaryやCollectionに入れられません。
そこで、ユーザー定義型の代わりにクラスを使用することで独自データ型を定義しています。
クラスにすることで、プロパティでさらに情報の操作が可能となり融通が効くようになります。

使用する場合のVBAサンプル

シートに全プロシージャー・プロパティ一覧を出力します。
どこでも良いですが、基本としては標準モジュールで使用することを想定しています。



Private Sub sample()
  Dim dicProcInfo As New Dictionary
  Dim wb As Workbook
  Set wb = ThisWorkbook
  Dim i As Long
  
  'ブックの全モジュールを処理
  With wb.VBProject
    For i = 1 To .VBComponents.Count
      Call getCodeModule(dicProcInfo, wb, .VBComponents(i).Name)
    Next
  End With
  
  'Dictionaryよりシートに出力
  Dim ws As Worksheet
  Set ws = ThisWorkbook.Worksheets("プロシーシャー一覧")
  Dim v
  With ws
    .Cells.Clear
    .Range("A1:G1").Value = Array("モジュール", "プロシージャー", "スコープ", "種別", "行位置", "ソース", "コメント")
    i = 2
    For Each v In dicProcInfo.Items
      .Cells(i, 1) = v.ModName
      .Cells(i, 2) = v.ProcName
      .Cells(i, 3) = v.Scope
      .Cells(i, 4) = v.ProcKindName
      .Cells(i, 5) = v.LineNo
      .Cells(i, 6) = v.Source
      .Cells(i, 7) = "'" & v.Comment
      i = i + 1
    Next
  End With
  Set dicProcInfo = Nothing
End Sub

参照設定
「ツール」→「参照設定」で、
Microsoft Scripting Runtime
これを参照設定して下さい。

参照設定しない場合は、
Dim dicProcInfo As Object
Set dicProcInfo = CreateObject("Scripting.Dictionary")
として下さい。

シートへの出力結果は以下のようになります。

VBA マクロ VBProject VBComponents

これだけでも使えますが、
さらに独自の項目を追加して機能拡張してみると良いのではないでしょうか。



同じテーマ「マクロVBAサンプル集」の記事

ハイパーリンクからファイルのフルパスを取得する
ボタンのテキスト名のシートへ移動(Application.Caller)
Excelの表をPowerPointへ図として貼り付け
VBAで表やグラフをPowerPointへ貼り付ける
フォルダ(サブフォルダも全て)削除する、Optionでファイルのみ削除
Shift_JISのテキストファイルをUTF-8に一括変換
VBAコードの全プロシージャー・プロパティ一覧を取得
数式バーの高さを数式の行数で自動設定
図形オートシェイプ(Shape)の複数選択
GoogleスプレッドシートをExcelにインポートする
多階層フォルダ(ディレクトリ)の作成


新着記事NEW ・・・新着記事一覧を見る

多階層フォルダ(ディレクトリ)の作成|VBAサンプル集(7月31日)
VBAのインデントについて|VBA技術解説(7月16日)
「VBA Match関数の限界」についての誤解|エクセル雑感(7月15日)
省略可能なVariant引数の参照不可をラップ関数で利用|VBA技術解説(7月12日)
100桁の正の整数値の足し算|エクセル雑感(7月9日)
LSetとユーザー定義型のコピー(100桁の足し算)|VBA技術解説(7月9日)
Variant仮引数のByRefとByValの挙動違い|エクセル雑感(7月5日)
Variant仮引数にRange.Valueを配列で渡す方法|エクセル雑感(7月5日)
Variantの数値型と文字列型の比較|エクセル雑感(7月1日)
VBAのVariant型について|VBA技術解説(6月30日)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.マクロって何?VBAって何?|VBA入門
5.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
6.繰り返し処理(For Next)|VBA入門
7.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
8.セルに文字を入れるとは(Range,Value)|VBA入門
9.とにかく書いてみよう(Sub,End Sub)|VBA入門
10.マクロはどこに書くの(VBEの起動)|VBA入門




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。



このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ