Visio VBAを極める:`Document.VBProject`による「自己拡張型ツール」の動的生成アーキテクチャ
こんにちは。開発プロジェクトの現場で数々の業務自動化システムを率いてきたチーフアーキテクトの私だ。
Visioを使った図面自動生成やデータ連携ツールを開発する際、こんな壁にぶつかったことはないだろうか?
「マスターとなるVisioファイルから、機能(マクロ)を組み込んだ配布用ファイルをプログラム側でワンクリックで生成したい」
「定型的な処理を行うためのVBAモジュールを、動的にドキュメントへ流し込み、完全なスタンドアロンのツールとして納品したい」
一般的なリファレンスサイトを見ると、「VBEの信頼設定を有効にしてください」と書いておしまいだ。しかし、実務の現場ではそんな安易な前提は通用しない。セキュリティポリシー、オブジェクトのライフサイクル、COMの参照設定の破壊、そしてコンパイルエラーの罠――これらをすべてクリアして初めて「プロダクション品質」と言える。
今回は、Visioの心臓部である `Document.VBProject` を完全に掌握し、「コードが自らコードを生成・実装する自己拡張型ツール」を構築するための極限の知見を授けよう。
—
1. 現場の現実:なぜ「モジュールの動的インポート」が必要なのか?
大規模なVisio運用において、すべての定型作業用マクロをユーザーの個人用マクロ有効ブック(`Visio.vsl` や `Visio.mst`)に依存させるのは悪手だ。環境が変わればパスが切れ、バージョン管理も破綻する。
理想的なアーキテクチャはこうだ:
1. ジェネレーター(親):マスターとなるVBAプロジェクトを持つ管理用Visioファイル。
2. ターゲット(子):ユーザーに配布する、空の(あるいは図面のみの)Visioファイル。
3. 動的インポート:親から子の `VBProject` へ、必要な標準モジュールやクラスモジュールをプログラム経由でインポートし、完全な機能を持つツールとしてローカルに保存・配備する。
これを実現するためには、Visioのオブジェクトモデルだけでなく、VBE(Visual Basic for Applications Extensibility)の挙動を完全に手なずける必要がある。
—
2. 実装上の重大な罠と堅牢な設計の要件
`Document.VBProject` を操作する際、プログラマーが必ず踏む地雷がいくつかある。設計を誤ると、ツールは一瞬でクラッシュする。
罠①:セキュリティ設定による「Programmatic access to Visual Basic Project」の拒否
デフォルトのExcelやVisioでは、信頼されたVBAプロジェクトへのプログラムからのアクセスが無効化されている。これをコード側で回避することはセキュリティ上不可能であるため、インストールの前提条件(グループポリシーやレジストリ設定)としてのドキュメント化が必須となる。
罠②:COMオブジェクトの解放漏れとメモリリーク
`VBProject` や `VBComponents` を操作する際、適切な変数解放を行わないと、Visioプロセスがバックグラウンドに残留し、ファイルがロックされる。
罠③:同名モジュールの衝突
すでにターゲット側に同名のモジュールが存在する場合、インポート処理はエラーになるか、意図しない上書きを引き起こす。必ず「既存モジュールの事前削除(パージ)」をロジックに組み込まなければならない。
—
3. プロダクションコード:自己拡張型ツール生成エンジン
それでは、実際に動的インポートを安全に行うための実装コードを公開しよう。
このコードは、管理用Visioファイルの標準モジュールに配置し、任意の外部エクスポート済みモジュール(`.bas` や `.cls`)を指定されたターゲットVisioドキュメントに流し込むものだ。
Option Explicit
‘ =========================================================================
‘ 処理名: 動的モジュールインポート・エンジン
‘ 概要: 指定されたVisioドキュメントのVBProjectに、外部のbas/clsファイルを動的に注入する
‘ =========================================================================
Public Sub InjectModuleToDocument(ByVal targetDoc As Visio.Document, ByVal sourceFilePath As String)
Dim vbp As Object ‘ VBProject
Dim vbc As Object ‘ VBComponent
Dim moduleName As String
Dim fso As Object
‘ 1. ファイル存在チェック
Set fso = CreateObject(“Scripting.FileSystemObject”)
If Not fso.FileExists(sourceFilePath) Then
MsgBox “指定されたソースファイルが見つかりません: ” & sourceFilePath, vbCritical, “インポートエラー”
Exit Sub
End If
‘ 2. モジュール名の抽出 (ファイル名から拡張子を除いたもの)
moduleName = fso.GetBaseName(sourceFilePath)
On Error GoTo ErrorHandler
‘ 3. ターゲットドキュメントのVBProjectを取得
‘ ※注意: 「VBAプロジェクト オブジェクトモデルへのアクセスを信頼する」が有効である必要あり
Set vbp = targetDoc.VBProject
‘ 4. 同名モジュールが既に存在する場合は事前に削除(クリーンアップ)
On Error Resume Next
Set vbc = vbp.VBComponents(moduleName)
If Not vbc Is Nothing Then
vbp.VBComponents.Remove vbc
End If
On Error GoTo ErrorHandler
‘ 5. モジュールのインポート実行
vbp.VBComponents.Import sourceFilePath
Debug.Print “Successfully injected: ” & moduleName & ” into ” & targetDoc.Name
‘ クリーンアップ
GoTo Finally
ErrorHandler:
MsgBox “VBAプロジェクトへのモジュール注入中に致命的なエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“エラー内容: ” & Err.Description, vbCritical, “アーキテクチャ例外”
Finally:
Set vbc = Nothing
Set vbp = Nothing
Set fso = Nothing
End Sub
—
4. 実戦的応用:ツール全体のライフサイクル管理
単にモジュールを突っ込むだけでは、プロの仕事とは言えない。実務では、このエンジンを使って「テンプレートから新規図面を作成し、マクロを焼き込んで名前を付けて保存する」一連のワークフローを自動化する。
以下のコードは、親ツールから「配備用の完全なマクロ付きVisioファイル(.vsdm)」を自動生成する司令塔プロシージャだ。
Public Sub GenerateDeploymentTool()
Dim appVisio As Visio.Application
Dim newDoc As Visio.Document
Dim savePath As String
Dim modulePath As String
Set appVisio = Visio.Application
‘ 1. マクロ有効形式(.vsdm)で新規ドキュメントを作成
‘ ※通常の.vsdxではマクロを保持できないため、必ず.vsdmを指定する
Set newDoc = appVisio.Documents.Add(“”)
‘ 2. 注入するモジュールファイルのパス(事前にエクスポートしておいたファイル)
modulePath = “C:\VisioTools\Modules\AutoLayoutEngine.bas”
‘ 3. エンジンを呼び出してモジュールを動的挿入
InjectModuleToDocument newDoc, modulePath
‘ 4. 配布用ファイルとして保存
savePath = “C:\VisioTools\Distribute\AutoLayoutTool_v1.0.vsdm”
‘ 既存ファイルがある場合は上書きのために削除
If Dir(savePath) <> “” Then
Kill savePath
End If
‘ ドキュメントの保存(Visioフォーマット: vsdm = 25)
newDoc.SaveAsEx savePath, visSaveAsMacroEnabled
MsgBox “配布用ツールの生成が完了しました。” & vbCrLf & savePath, vbInformation, “ビルド成功”
Set newDoc = Nothing
End Sub
—
5. チーフアーキテクトからの提言:保守性とセキュリティの担保
この手法は強力無比であるがゆえに、運用フェーズで厳格なルールが必要だ。
1. ファイル形式の厳守:
現代のVisioにおいて、VBAコードを保持できるのはマクロ有効図面(`.vsdm`)およびマクロ有効ステンシル(`.vssm`)のみだ。通常の `.vsdx` に対してコードをインポートしようとすると、Visioの仕様によりコードがサイレントに破棄されるか保存エラーになる。必ず保存形式を意識しろ。
2. ソースのバージョン管理:
VBAのコードをVisioファイルの中に閉じ込めたまま修正するのは保守の悪夢である。必ずGit等のバージョン管理システム上でモジュール単体(`.bas`, `.cls`)で管理し、ビルドスクリプト(今回紹介したようなVBAルーチン)によって流し込む「外部ソース・マスター主義」を徹底すること。
この設計を取り入れることで、あなたのチームのVisio開発力は次元の違うレベルへと引き上げられるはずだ。泥臭い手作業のデプロイとは今日で決別し、コードによる自動化の極みを堪能してほしい。
