こんにちは! Access VBAの世界へようこそ。
マクロの記録ボタンを押すだけの世界から一歩踏み出し、「自分でシステムを自在に操りたい」と願うあなたへ、今日はちょっとワクワクする技術をお伝えしますね。
「昔作ったデータベース、あちこちのモジュールに同じようなコードが散らばっていて、どこを直したらいいか分からない…」
「あの関数、どのフォームのボタンから呼ばれているんだっけ?」
開発の規模が大きくなると、こんなモヤモヤに必ずぶつかります。
今回は、そんな迷子を解消するために、Access VBA自身を使ってプロジェクト内のコードをくまなく探し出し、解析する「リファクタリング支援ツール」の作り方を解説します。
ここをクリアすれば、Access VBAの基本はバッチリですよ。オブジェクトモデルの奥深さに触れながら、一緒にプロの第一歩を踏み出しましょう!
—
1. Access VBAオブジェクトモデルの核心:`CurrentProject` とは?
私たちが普段何気なく使っているAccess。実は、Accessの中には「今開いているファイル(プロジェクト)の中身はどうなっているか」を教えてくれる便利な道案内役がいます。それが `Application.CurrentProject` です。
この道案内役は、フォーム、レポート、そしてVBAが書かれたモジュールなど、データベースを構成するパーツ(オブジェクト)の全貌を把握しています。
その中でも今回主役になるのが `AllModules` コレクション です。
0からわかる!「コレクション」ってなに?
プログラミングの世界で「コレクション」と聞くと難しく聞こえますが、要するに「同じ種類のデータが詰まった箱(または引き出し)」のことです。
`AllModules` は、あなたのAccessファイルの中にあるすべてのVBAモジュールが入った引き出しだと思ってください。
この引き出しを開けて、中身を一つずつ取り出して調べる(=走査する)ことで、コードの動的解析が可能になります。
—
2. 実践!コードの検索・解析ツールの設計
では、実際に動くツールを作ってみましょう。
今回は、「指定したキーワードが、どのモジュールのどこに含まれているか」をイミディエイトウィンドウにリストアップするプログラムを作成します。
以下の手順で進めます。
1. 標準モジュールを新規作成する。
2. 以下のコードを貼り付ける。
3. 実行して結果を確認する。
リファクタリング支援ツールのサンプルコード
Option Compare Database
Option Explicit
‘ =========================================================================
‘ プロジェクト内の全モジュールから特定キーワードを検索するリファクタリング支援ツール
‘ =========================================================================
Public Sub SearchCodeInModules()
Dim mdp As AccessObject
Dim mdl As Module
Dim targetKeyword As String
Dim lineCount As Long
Dim i As Long
Dim foundCount As Long
‘ — 1. 検索したいキーワードを設定 —
‘ ここを調べたい変数名や関数名に変更してください
targetKeyword = “CurrentDb”
foundCount = 0
Debug.Print “==================================================”
Debug.Print ” 検索キーワード: [ ” & targetKeyword & ” ] の探索を開始します…”
Debug.Print “==================================================”
‘ — 2. AllModulesコレクションを使ってループを回す —
For Each mdp In Application.CurrentProject.AllModules
‘ モジュールがデザインビューで読み込まれていない場合は開く必要があるため、
‘ Application.ModuleFromComponentName または DoCmd を使いますが、
‘ AllModulesの対象はVBAプロジェクト内の標準/クラスモジュールです。
‘ モジュールを開いてコード操作オブジェクトを取得します
DoCmd.OpenModule mdp.Name
Set mdl = Modules(mdp.Name)
‘ — 3. モジュール内の全行を走査する —
lineCount = mdl.CountOfLines
For i = 1 To lineCount
‘ 指定したキーワードが含まれているか判定 (大文字小文字を区別しない)
If InStr(1, mdl.Lines(i, 1), targetKeyword, vbTextCompare) > 0 Then
foundCount = foundCount + 1
‘ 発見場所を綺麗にフォーマットして出力
Debug.Print “発見 [” & foundCount & “] ————————”
Debug.Print ” モジュール名 : ” & mdp.Name
Debug.Print ” 行番号 : ” & i & “行目”
Debug.Print ” 該当コード : ” & Trim(mdl.Lines(i, 1))
End If
Next i
‘ 開いたモジュールを閉じる(メモリの解放配慮)
DoCmd.Close acModule, mdp.Name, acSaveNo
Next mdp
Debug.Print “==================================================”
Debug.Print ” 探索終了。 合計 ” & foundCount & ” 件ヒットしました。”
Debug.Print “==================================================”
End Sub
—
3. コードの解説:ここがエンジニアの急所!
初心者の方が「おっ」とつまずきやすいポイントと、実務で絶対に知っておくべき技術的背景を解説します。
① `DoCmd.OpenModule` の重要性
Accessのモジュールは、ただ存在しているだけではVBAからコードの行を読み取れません。「一度画面上に開く(メモリ上にロードする)」というプロセスが必要です。コード内で `DoCmd.OpenModule` を挟んでいるのはそのためです。
処理が終わったら `DoCmd.Close` で忘れずに閉じる。この「使ったら片付ける」というリソース管理の意識が、プログラミングの上達において非常に大切です。
② `InStr` 関数のスマートな活用
`InStr(1, 探される文字列, 探す文字列, 比較方法)` は、「文字列の中に特定の文字が含まれているか」を数字(何文字目にあるか)で返す関数です。
第4引数に `vbTextCompare` を指定しているのがポイント。これにより、大文字と小文字(例: `CurrentDb` と `currentdb`)を区別せずにヒットさせることができます。人間はうっかり大文字小文字を間違えて書く生き物ですから、ここを寛容にしておくのがツールの優しさです。
—
4. 陥りやすいエラーと回避のテクニック
このツールや、モジュールを操作するコードを書く際によく遭遇するエラーと、その対策をご紹介します。
⚠️ エラーその1: 「実行時エラー 2493: このアクションにはモジュール名が必要です」
- 原因: `Modules` コレクションからモジュールオブジェクトを取得する際、対象のモジュールが正しく開かれていない、あるいは存在しない名前を指定している場合に発生します。
- 対策: `AllModules` で取得した `mdp.Name` を確実に渡しているか確認し、ループ処理の前に `DoCmd.OpenModule` が実行されているかを必ず確認してください。
⚠️ エラーその2: フォームやレポート内のコードがヒットしない?
- 注意点: 今回使用した `Application.CurrentProject.AllModules` は、標準モジュールとクラスモジュールを対象としています。フォームやレポートの「クラスモジュール(フォームの裏に書くコード)」は、`AllForms` や `AllReports` コレクションの `HasModule` プロパティなどを組み合わせる必要があります。
- 応用として、フォームの裏のコードまで探したい場合は、`CurrentProject.AllForms` も同様にループさせてみてくださいね。
—
おわりに
今回は、`Application.CurrentProject.AllModules` を駆使したVBAコードの動的解析ツールを作成しました。
「VBAでVBAのコードを読み解く」なんて、少しハッカーっぽくてカッコいいですよね。この手法をマスターすれば、巨大化したAccessデータベースの保守や、不要なコードの掃除(リファクタリング)が一気に爆速化します。
Access VBAは、ただの「自動化ツール」の枠を超えて、あなたのアイデア次第で強力な開発環境に化けます。ぜひ自分の手でコードを動かし、イミディエイトウィンドウに結果が表示されたときの快感を味わってみてください。
あなたのAccessライフが、よりスマートで快適なものになりますように!
