こんにちは!Access VBAの奥深い世界へようこそ。チーフアーキテクトの私です。
これまでマクロの記録を使ったり、フォームにボタンを置いてちまちまコードを書いたりして、「Accessって便利だな」と感じてきた頃だと思います。でも、ふとこんな風に思ったことはありませんか?
「なあ、この何百個もあるクエリ名や古いテーブル名を、全モジュールから一括で書き換える方法ってないのか……?」
手作業で一つずつVBE(Visual Basic Editor)を開いて、Ctrl+Fで探して置換して……なんてやっていたら、日が暮れてしまいますし、何よりヒューマンエラーの元です。
今回は、そんな絶望的な大規模改修を一瞬で終わらせるための禁断の奥義、『Application.VBEオブジェクトを使ったコードの動的生成・リファクタリング支援』を伝授します。ここをクリアすれば、あなたはもうただの「Access使い」ではありません。VBAの神髄を理解した真のエンジニアです。
さあ、背筋を伸ばして、知的でエキサイティングな自動化の世界へ飛び込みましょう!
—
1. なぜ「VBEオブジェクト」を操作するのか?
通常、私たちが書くVBAは「人間がVBEを開いてコードを書く」ものです。しかし、`Application.VBE`オブジェクトを使えば、「プログラムがプログラム自身のコードを読む、書き換える、新しく作る」という神様のような離れ業が可能になります。
⚠️ 【重要】大前提:トラストセンターの設定
このコードを実行する前に、Accessのセキュリティ設定を変更しておく必要があります。
これをしていないと、Accessのセキュリティ機能が「外部からVBAをいじるな!」と怒ってエラーになります。
1. Accessのオプションを開く。
2. 「トラスト センター」>「トラスト センターの設定」を開く。
3. 「VBA プロジェクト オブジェクト モデルへのアクセスを信頼する」にチェックを入れる。
さあ、準備はいいですか? 次に進みましょう。
—
2. VBEオブジェクトの構造を覗いてみよう
VBEの世界は、階層構造(オブジェクトモデル)でできています。イメージとしては、会社組織のようなものです。
- `Application.VBE` (VBEの社長室)
- `VBProjects` (プロジェクト=Accessファイルごとのまとまり)
- `VBComponents` (部品=標準モジュールやフォーム、クラスなど)
- `CodeModule` (中身のコードそのもの!)
今回は、一番末端にある `CodeModule` を自由自在に操る方法を学びます。
—
3. 実践:全モジュールから特定のキーワードを検索・置換するマクロ
それでは、現場で即戦力として使える「リファクタリング支援ツール」のコードをお見せします。
適当な標準モジュールを一つ新しく作り、以下のコードを貼り付けてみてください。
Option Compare Database
Option Explicit
‘ =========================================================================
‘ 処理名 : Refactor_ReplaceCode
‘ 概要 : データベース内の全標準モジュールを走査し、指定した文字列を一括置換する
‘ =========================================================================
Public Sub Refactor_ReplaceCode()
Dim vbProj As Object ‘ VBProject
Dim vbComp As Object ‘ VBComponent
Dim cModule As Object ‘ CodeModule
Dim targetStr As String
Dim replaceStr As String
Dim i As Long
Dim startLine As Long, startCol As Long, endLine As Long, endCol As Long
Dim isFound As Boolean
‘ 検索する文字列と置換後の文字列(例:古いテーブル名から新しいテーブル名へ)
targetStr = “T_OldCustomer”
replaceStr = “T_NewCustomer”
‘ 現在のAccessデータベースのVBProjectを取得
Set vbProj = Application.VBE.ActiveVBProject
‘ プロジェクト内のすべてのコンポーネント(モジュールやフォーム)をループ
For Each vbComp In vbProj.VBComponents
‘ 標準モジュール(VBMS_Standard = 1)またはクラス・フォームを対象とする
‘ 今回は標準モジュール(1)とクラス(2)、フォーム(100)を対象にする
If vbComp.Type = 1 Or vbComp.Type = 2 Or vbComp.Type = 100 Then
Set cModule = vbComp.CodeModule
‘ モジュール内に目的の文字列が存在するかチェック
startLine = 1
startCol = 1
endLine = cModule.CountOfLines
endCol = 255
‘ Findメソッドでコード内を検索
isFound = cModule.Find(targetStr, startLine, startCol, endLine, endCol, True, False, False)
If isFound Then
Debug.Print “【発見】モジュール名: ” & vbComp.Name
‘ 該当モジュールのコードを丸ごと取得して置換してしまうアプローチ
Dim codeText As String
Dim newCodeText As String
If cModule.CountOfLines > 0 Then
codeText = cModule.Lines(1, cModule.CountOfLines)
‘ 文字列置換
newCodeText = Replace(codeText, targetStr, replaceStr, , , vbTextCompare)
‘ 一旦コードを全削除して、置き換えたコードを流し込む(超強力な手法)
cModule.DeleteLines 1, cModule.CountOfLines
cModule.AddFromString newCodeText
Debug.Print ” -> 置換完了しました。”
End If
End If
End If
Next vbComp
MsgBox “リファクタリングが完了しました!イミディエイトウィンドウを確認してください。”, vbInformation
End Sub
このコードの何がスゴいのか?
初心者のうちは、「フォームのボタンをクリックしたら文字が変わる」という世界に感動しますが、このコードは「VBA自身が、自分の仲間(他のモジュール)のソースコードを書き換えている」という点に本質があります。
`cModule.Lines` でコードを丸ごと文字列として吸い出し、VBAの `Replace` 関数で一網打尽にしてから、`DeleteLines` と `AddFromString` で書き戻す。このダイナミックなアプローチこそ、プロの自動化エンジニアが使う手口です。
—
4. 陥りやすい罠とエンジニアの心得
このVBE操作、諸刃の剣です。強力すぎるゆえに、一歩間違えるとシステム全体を破壊しかねません。現場でよくある失敗を防ぐための知見を授けましょう。
⚠️ 罠1:バックアップなしで実行する愚行
プログラムがプログラムを書き換えるわけですから、正規表現や置換のミスで「全モジュールのコードが消滅した」なんてことが起こり得ます。
絶対に、実行する前にはAccessファイル(.accdb)のバックアップをコピーして別場所に退避させてください。 これ、絶対の約束です。
⚠️ 罠2:コンパイルエラーを埋め込んでしまう
文字列置換で変数名やプロパティ名を間違えて置き換えてしまうと、次回VBEを開いたときに「コンパイルエラー: 変数が定義されていません」の嵐になります。
置換を行うときは、「確実に一意に決まる文字列(テーブル名や特定のプレフィックスがついた関数名など)」に限定するようにしてください。
—
まとめ
今回は、Access VBAの奥の院である `Application.VBE` オブジェクト を使った、コードの動的リファクタリング支援について解説しました。
- `Application.VBE.ActiveVBProject` でプロジェクトを掴む。
- `VBComponents` でモジュールを巡回する。
- `CodeModule` の `Lines` と `AddFromString` でコードを自在に書き換える。
ここをクリアしたあなたなら、もはやAccess VBAで恐いものはありません。数千行、数万行規模のレガシーシステム改修も、あなたの手にかかれば一瞬で自動化できるはずです。
「ここをこう変えたらもっと面白いことができるのでは?」という知的な好奇心を大切に、日々の業務ハックを楽しんでくださいね。それでは、次のステージでお会いしましょう!
