【テクニカル・上級編】【上級】Application.CurrentProject.AllModulesを活用した、VBAコードの動的解析と保守ツール開発 – Access VBA解析バイブル

スポンサーリンク

泥沼のレガシーを掌握せよ:VBAコードの動的解析で「見えない依存関係」を可視化する

大規模なAccessシステムを長年運用していると、誰も触りたくない「暗黒のコードベース」が肥大化する。仕様書は化石化し、誰がどの関数を呼び出しているのか、修正がどこに波及するのかを誰も把握していない。

多くのエンジニアは、この状況で「検索」機能に頼るが、それは場当たり的な対処に過ぎない。真のプロフェッショナルは、Application.CurrentProject.AllModulesを軸としたメタプログラミングの手法を用い、システムを俯瞰する。

今日は、Accessの全コードを走査し、依存関係を抽出する「保守エンジン」の心臓部を公開する。

1. 舞台裏:VBA Extensibility ライブラリの制約と可能性

コードを解析するためには、`Microsoft Visual Basic for Applications Extensibility 5.3`を参照設定する必要がある。しかし、これをプロダクト環境で不用意に動かすのは危険だ。

まず心に刻んでほしいのは、「VBE(Visual Basic Editor)のオブジェクトモデルは、ランタイム環境では極めて不安定である」という事実だ。メモリリークを避けるため、解析後はオブジェクトを即座に破棄し、VBEへのアクセスを最小限に抑える構造が必須となる。

2. コード走査エンジンの実装

以下のコードは、データベース内の全標準モジュールを走査し、特定のキーワードが含まれる行を抽出するスキャナーの核となるものだ。

‘ 参照設定: Microsoft Visual Basic for Applications Extensibility 5.3
Public Sub AnalyzeCodebase(ByVal searchPattern As String)
Dim vbProj As VBIDE.VBProject
Dim vbComp As VBIDE.VBComponent
Dim vbMod As VBIDE.CodeModule
Dim i As Long, lineText As String

Set vbProj = Application.VBE.ActiveVBProject

‘ メモリの断片化を避けるため、オブジェクトの参照を明確に制御する
For Each vbComp In vbProj.VBComponents
‘ Standard Module かつ CodeModule を持つもののみを対象
If vbComp.Type = vbext_ct_StdModule Then
Set vbMod = vbComp.CodeModule

For i = 1 To vbMod.CountOfLines
lineText = vbMod.Lines(i, 1)
‘ 特定のキーワード検索(正規表現エンジンを別途積むと尚良し)
If InStr(1, lineText, searchPattern, vbTextCompare) > 0 Then
Debug.Print “Found in [” & vbComp.Name & “] line ” & i & “: ” & Trim(lineText)
End If
Next i
End If
Next vbComp

‘ 明示的な解放
Set vbMod = Nothing
Set vbProj = Nothing
End Sub

3. 深層解析:Windows APIによるパフォーマンスチューニング

数万行を超えるコードベースを解析する場合、VBA標準のループは遅い。さらに、メモリ管理が甘いとAccess自体がクラッシュする。

解析ツールを「ツール」として完成させるなら、解析結果を一旦メモリ上の配列(`Variant Array`)に格納し、最後に一度だけシートやテーブルへ出力する手法を徹底せよ。I/O操作の回数を最小限に抑えるのが、高負荷環境における鉄則だ。

また、大規模な解析中にVBEがフリーズした時のために、`DoEvents`を適切に配置し、APIを用いてプロセス優先度を一時的に管理する工夫も、シニアエンジニアなら検討すべき領域である。

4. 依存関係の可視化:次のステップ

単なるキーワード検索を超え、「どのプロシージャがどこで使われているか」という依存関係を抽出するには、以下のロジックを実装する。

1. 定義リストの生成: `vbComp.CodeModule.ProcBodyLine`を用いて全プロシージャ名のインデックスを作成。
2. クロスリファレンス: 全モジュールを走査し、ステップ1で作成したプロシージャ名が出現する箇所を特定。
3. グラフ化: 抽出した依存データを `Dictionary` オブジェクトで保持し、CSVへ出力。これをGraphviz等に流し込めば、システム構造が一目瞭然となる。

伝説のアーキテクトからの忠告

「動的解析ツール」を自作する最大のメリットは、コードの内容そのものよりも、「システムに何が含まれているか、何が含まれていないかを断言できる自信」が手に入ることにある。

レガシーシステムを恐れるな。Accessは、APIの深淵とオブジェクトモデルの構造を理解した者に対しては、驚くほど従順で強力な武器となる。

保守ツールを構築し、システムを管理下に置け。それが、真に「システムを操る」ということだ。


次回の講義では、`Access.Application` インスタンスをバックグラウンドで隠蔽し、COM接続経由で外部ツールから解析を自動実行する「CI/CDパイプラインへの統合術」について解説する。

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