【入門編】Applicationオブジェクトのイベントハンドラで実現する「プロジェクト操作のログ記録」自動化 – Project VBA解析バイブル

スポンサーリンク

こんにちは!Microsoft Projectの自動化の世界へようこそ。
普段、ExcelやAccessのVBAは触っているけれど、「ProjectのVBAってなんだか勝手が違うぞ…」「イベント駆動でスマートにログを取りたいのに、どう書けばいいの?」と悩んでいませんか?

大丈夫、安心してください。今日は、私と一緒に「Applicationオブジェクトのイベントハンドラ」を完全攻略し、プロジェクトの変更履歴を自動で記録する『監査ツール』を作ってみましょう。

ここをクリアすれば、あなたも脱「マクロの記録」!現場で一目置かれるProject VBAエンジニアへの第一歩です。さあ、いってみましょう!

—

1. なぜ「イベントハンドラ」なのか?

私たちが普段作るマクロは、「ボタンを押したら動く」というものが多いですよね。これを「ユーザー主導の実行」と呼びます。

しかし、プロジェクト管理の世界では、「うっかり保存し忘れた」「誰がいつスケジュールをいじったのか後から追えない」というヒヤリハットがつきものです。これを人間の記憶や手作業に頼るのをやめ、「MS Projectが裏で勝手に(自動で)見張っていてくれる仕組み」を作るのが、イベントハンドラの役割です。

MS Projectのイベントの全体像

Excel VBAでおなじみの `Workbook_Open` や `Workbook_BeforeClose` と同じように、Projectにもプロジェクトのライフサイクル(開く、閉じる、保存するなど)に合わせて発火するイベントが存在します。

これらを統括するのが、最上位に君臨する `Application` オブジェクト です。

—

2. 実装のキモ:クラスモジュールを使う理由

ここがProject VBAで最もつまずきやすいポイントであり、最大の肝です。

Excelであれば、`ThisWorkbook` モジュールにそのまま `Private Sub Workbook_Open()` と書けば動きます。しかし、MS ProjectのApplicationイベントをキャッチするには、「クラスモジュール」という専用の入れ物を用意し、イベントを有効化する初期設定(WithEvents)を行う必要があります。

ちょっと難しそうに聞こえるかもしれませんが、手順通りにやれば一撃です。以下のステップで進めましょう。

—

3. 実践!自動ログ記録ツールの構築

今回は、以下の仕様のツールを作ります。

  • やりたいこと: プロジェクトが開かれた時、および閉じられる(または保存される)時に、操作したユーザー名、日時、プロジェクト名を自動的に別ファイルのCSV(ログ)に書き出す。

ステップ1:クラスモジュールの作成(イベントを受け取るアンテナ)

1. VBAエディタ(`Alt + F11`)を開きます。
2. メニューの [挿入] > [クラス モジュール] をクリックします。
3. プロパティウィンドウで、このクラスの名前を `C_AppEvents` に変更します。
4. 以下のコードを貼り付けます。

‘ =================================フォーマット=================================
‘ クラスモジュール名: C_AppEvents
‘ 役割: Applicationオブジェクトのイベントをフックし、ログ出力処理をキックする
‘ ==============================================================================
Option Explicit

‘ WithEventsキーワードを使い、Applicationのイベントを受け取れるように宣言します
Public WithEvents App As MSProject.Application

‘ ① プロジェクトが開いた瞬間のイベント
Private Sub App_ProjectOpen(ByVal Sv As Project)
Call WriteLog(“プロジェクトオープン”, Sv.Name)
End Sub

‘ ② プロジェクトが閉じられる直前のイベント
Private Sub App_ProjectBeforeClose(ByVal Sv As Project, ByRef Cancel As Boolean)
Call WriteLog(“プロジェクトクローズ”, Sv.Name)
End Sub

‘ — 共通のログ書き出しプロシージャ —
Private Sub WriteLog(ActionType As String, ProjectName As String)
Dim LogFile As String
Dim FSO As Object
Dim TextStream As Object

‘ ログファイルの保存先(ここではPCのCドライブ直下を指定。適宜変更してください)
LogFile = “C:\ProjectAuditLog.csv”

‘ FileSystemObjectを使って、ファイルを安全に追記モードで開く
Set FSO = CreateObject(“Scripting.FileSystemObject”)

‘ ファイルが存在しない場合は新規作成しつつ開く(第2引数: 8 = ForAppending / 追記)
On Error Resume Next
Set TextStream = FSO.OpenTextFile(LogFile, 8, True)
On Error GoTo 0

If Not TextStream Is Nothing Then
‘ 「日時, ユーザー名, アクション, プロジェクト名」の形式でCSVに書き込む
TextStream.WriteLine Now() & “,” & Environ(“USERNAME”) & “,” & ActionType & “,” & ProjectName
TextStream.Close
End If

Set TextStream = Nothing
Set FSO = Nothing
End Sub

ステップ2:標準モジュールでのイベントの「有効化」(スイッチを入れる)

クラスを作っただけでは、まだアンテナは機能していません。「このクラスを起動してくれ!」という命令を、プロジェクト起動時(あるいは手動)に走らせる必要があります。

1. メニューの [挿入] > [標準モジュール] をクリックします。
2. 以下のコードを貼り付けます。

‘ ==============================================================================
‘ 標準モジュール名: M_Initialize
‘ 役割: クラスをメモリ上に常駐させ、イベント監視を開始する
‘ ==============================================================================
Option Explicit

‘ グローバル変数としてクラスのインスタンスを保持し続ける(消滅させないため)
Public EventWatcher As C_AppEvents

Sub StartEventListener()
‘ インスタンスを生成
Set EventWatcher = New C_AppEvents

‘ Applicationオブジェクトを紐付ける(これで監視スタート!)
Set EventWatcher.App = Application

MsgBox “プロジェクト監査ツールの稼働を開始しました。”, vbInformation, “監視中”
End Sub

ステップ3:自動起動の設定(Project_Openの利用)

せっかくなので、このプロジェクトファイル自体を開いた瞬間に、自動で `StartEventListener` が走るようにしましょう。

1. VBAエディタのプロジェクトエクスプローラから `ThisProject` をダブルクリックします。
2. 以下のコードを貼り付けます。

‘ ==============================================================================
‘ ThisProject モジュール
‘ 役割: このファイルが開かれたときに、自動的にイベント監視を有効化する
‘ ==============================================================================
Private Sub Project_Open(ByVal Sv As Project)
‘ 標準モジュールの初期化マクロを自動実行
StartEventListener
End Sub

—

4. 陥りやすいエラーと知っておくべき「落とし穴」

ここで、Project VBAの現場でよくある「ハマりポイント」をいくつかシェアしておきます。これを覚えておくだけで、無駄なデバッグ時間を何時間も節約できます。

⚠️ トラップ1:イベントが突然動かなくなる(変数のスコープ切れ)

「最初は動いていたのに、別のコードを実行したらイベントが反応しなくなった…」
これはVBA初学者が100%通る道です。標準モジュールで宣言した `Public EventWatcher As C_AppEvents` が、何らかのエラーやコードのリセットによって「消滅(リセット)」してしまうことが原因です。

  • 対策: 本格的な運用ツールを作る場合は、アドイン(`.ppa` または `.xlam` 等)として組み込み、リボンやグローバルなライフサイクルで管理するのが定石です。今回は入門編として標準モジュールでの保持に留めていますが、実務ではこの「変数の消滅」に注意してください。

⚠️ トラップ2:セキュリティ警告でマクロがブロックされる

Projectを開いたときに、「マクロが無効にされました」と黄色いバーが出てイベントが動かないことがあります。

  • 対策: [ファイル] > [オプション] > [トラストセンター] > [トラストセンターの設定] から、マクロの設定を「警告を表示してすべてのマクロを有効にする」等に正しく設定してください。

—

5. まとめ

お疲れ様でした!ここまでで、以下のスキルがあなたのものになりました。
1. Applicationオブジェクトをフックして全体を監視する方法
2. `WithEvents` を使ったクラスモジュールによるイベントハンドリングの仕組み
3. FileSystemObject を用いた安全なファイルへのログ出力手法

Project VBAは、Excelに比べるとネット上の情報が少ないですが、オブジェクトモデルの基本原則(`Application` > `Project` > `Task`)さえ掴んでしまえば、あなたのプロジェクト管理業務を劇的に効率化する最強の武器になります。

「ここをクリアすれば、Project VBAの基本はバッチリですよ!」
ぜひ今回のコードをご自身の環境で試して、カスタマイズしてみてください。あなたのエンジニアライフのブレイクスルーになれば嬉しいです。それでは、また次の極限知見でお会いしましょう!

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