Project VBAを掌握せよ:Applicationイベント監視による「究極のプロジェクト・オーディット」の実装
多くのVBAエンジニアは、プロジェクトの「操作」を記録しようとして、各モジュールに場当たり的なコードを散りばめるという過ちを犯す。それでは保守性は死に、イベントの取りこぼしが頻発する。
真のアーキテクトは、`Application`オブジェクトを掌握する。プロジェクトのライフサイクルを単一のクラスに集約し、グローバルな監視体制を敷くのだ。本稿では、堅牢で拡張性の高い「プロジェクト常駐監視システム」の設計思想を伝授する。
—
1. なぜ「イベントハンドラ」の設計が重要なのか
MS Projectのイベントを扱う際、個々のプロジェクトファイルにコードを書いてはならない。それは「密結合」の極みであり、コードの散逸を招く。
我々が目指すべきは「イベントの集中管理」だ。`WithEvents`キーワードを冠したクラスモジュールを一つ用意し、そこにすべてのトリガーを集約させる。これにより、ログの記録形式を変更したい場合や、データベース連携を追加したい場合、修正は「たった1つのクラス」で完結するようになる。
2. 堅牢な監視クラスの設計(Production Code)
まずは、イベントを統括するクラスモジュールを定義する。クラス名を `ProjectMonitor` とせよ。
‘ クラスモジュール: ProjectMonitor
Option Explicit
‘ MS ProjectのApplicationオブジェクトをイベント付きで定義
Public WithEvents AppEvents As MSProject.Application
‘ プロジェクトが開かれた瞬間の監視
Private Sub AppEvents_ProjectOpen(ByVal pj As Project)
On Error Resume Next ‘ ログ書き込みエラーでメインプロセスを止めない
LogOperation “OPEN”, pj.Name
End Sub
‘ プロジェクト保存時の監視
Private Sub AppEvents_ProjectBeforeSave(ByVal pj As Project, ByRef SaveAsUi As Boolean, ByRef Cancel As Boolean)
‘ 保存直前に何が起きたか?ここでベースラインの整合性をチェックするのも手だ
LogOperation “SAVE_PRE”, pj.Name
End Sub
‘ ログ記録の汎用プライベートメソッド
Private Sub LogOperation(ByVal action As String, ByVal pjName As String)
Dim logPath As String
logPath = “C:\Logs\ProjectAudit.log” ‘ 実務では環境変数から取得すること
Dim fileNum As Integer
fileNum = FreeFile
Open logPath For Append As #fileNum
Print #fileNum, Now & ” | ” & action & ” | ” & pjName
Close #fileNum
End Sub
3. インスタンスの寿命を管理せよ
初心者が最も陥る罠は、クラスのインスタンスを生成する場所を間違えることだ。ローカル変数のスコープでインスタンス化すれば、VBAのガベージコレクションによって、数秒後に監視機能は沈黙する。
監視システムを常駐させるには、「標準モジュール」でグローバル変数として保持し、初期化時に明示的に参照を繋ぐ必要がある。
‘ 標準モジュール: MonitorEntry
Option Explicit
Public Monitor As ProjectMonitor
‘ マクロ実行時、あるいはProject起動時にこのプロシージャを呼ぶ
Public Sub InitializeMonitoring()
If Monitor Is Nothing Then
Set Monitor = New ProjectMonitor
‘ MS Projectのアプリケーション本体とクラスを紐付ける
Set Monitor.AppEvents = Application
End If
End Sub
—
4. プロダクション環境における「3つの鉄則」
現場でこのコードを動かす際、以下の制約を考慮していないエンジニアは即刻設計を見直すべきだ。
① ログ出力のボトルネックを排除する
ファイルI/Oは低速だ。もし数百のプロジェクトを連続で開閉する運用があるなら、ファイルへの直接書き込みではなく、一度メモリ上のコレクションに蓄積し、`WorkbookBeforeClose`等のタイミングで一括フラッシュする「バッファリング戦略」を検討せよ。
② エラーハンドリングの極意
`On Error Resume Next` は多用すべきではないが、監視システムにおいては「監視失敗が業務を止めること」を最も防がねばならない。ログ書き込み処理は、メインのプロジェクト動作から完全にデカップリング(疎結合化)させること。
③ データベース連携の注意点
ログを直接SQL Server等へ投げる場合、コネクションの再利用を意識しろ。毎回 `Open/Close` を繰り返すと、ネットワークオーバーヘッドでProjectの動作が重くなる。接続オブジェクトは静的に保持し、再接続ロジックをクラス内に隠蔽するのがプロの仕事だ。
—
結びに:アーキテクトとしての矜持
この監視システムは、単なる「ログ取りツール」ではない。組織のプロジェクトマネジメントの健全性を可視化するための「インフラ」だ。
コードをコピペして動かすことは誰にでもできる。しかし、「なぜこの設計がシステム全体の安定性に寄与するのか」を理解し、現場の運用フローに合わせて微調整を加えられる者だけが、真の自動化エンジニアとして尊敬を集める。
君たちのプロジェクトが、この堅牢なアーキテクチャによって、より強固な管理下に置かれることを期待する。何か不明点があれば、またいつでも問うがいい。
