こんにちは!Project VBAの深淵へようこそ。
今回は、多くの人がMS Projectの自動化で頭を悩ませる「タスク削除や移動に伴うリンク(依存関係)の破綻」をテーマに、イベントハンドラを使って監視・自動修復する仕組みを解説していきます。
「マクロの記録」から一歩進んで、Project VBAの真骨頂であるイベント駆動型のプログラミングをマスターすれば、あなたのWBS管理は劇的に堅牢になります。難しく聞こえるかもしれませんが、一歩ずつ噛み砕いて解説しますので、安心してついてきてくださいね。ここをクリアすれば、Project VBAの基本はバッチリですよ!
—
なぜ、タスク操作で「リンクの切断」が起きるのか?
MS ProjectでWBS(Work Breakdown Structure)を組むとき、タスク同士を「先行タスク」「後続タスク」の依存関係(FS、SSなど)で結びますよね。
しかし、現場でこんな悲劇が起きたことはありませんか?
- 「不要になった中間タスクを削除したら、後続のスケジュールが宙ぶらりんになった…」
- 「新しいタスクを間に挿入したが、前提条件のリンク付けを忘れてスケジュールが狂った…」
Excelとは異なり、Projectのスケジュールエンジンは複雑なガントチャートのロジックで動いています。人間がうっかりタスクを消したり動かしたりしたとき、依存関係のチェーンが切れてしまう(=リンクの切断)のは、プロジェクト遅延の最大の原因の一つです。
これを「VBAのイベント機能」を使って、タスクが変更された瞬間に自動で検知し、必要に応じて修復・警告できたら……最高だと思いませんか?
—
Project VBAにおけるイベントの仕組み
Excel VBAには `Worksheet_Change` などのイベントがありますが、MS Projectにも強力なイベント機構が備わっています。
特に今回主役となるのは、`Project_TaskChange` イベントです。
これは、プロジェクト内のタスクに対して「名前の変更」「日付けの変更」「進捗の変更」、そして「タスクの追加・削除」が行われた瞬間に、Projectが裏側で自動的に呼び出してくれる特別なプロシージャです。
⚠️ ここで注意!Project VBAの極限の知見
多くの初心者がハマる罠として、「イベントの中でタスクを操作すると、またイベントが発火して無限ループ(クラッシュ)する」という現象があります。
これを防ぐために、イベント内では `Application.EnableEvents = False`(※厳密にはProjectの仕様に合わせてフラグ制御を行います)を意識し、変更の検知と修復を安全に行う設計が不可欠です。
—
実装コード:リンク切断を監視・自動修復するガーディアン
では、実際に動くコードを見てみましょう。
このコードは、MS Projectのプロジェクトファイルに組み込むことで、タスクが削除・変更された際に「依存関係の整合性」をチェックする監視ツールとして機能します。
1. クラスモジュールまたはイベント用モジュールの準備
MS Projectでイベントを受け取るには、通常 `ThisProject` モジュールを使用します。VBAエディタを開き、左側のツリーから `ThisProject` をダブルクリックして開いてください。
以下のコードをそのまま貼り付けます。
‘ ==============================================================================
‘ モジュール名: ThisProject
‘ 概要: タスクの変更・削除を監視し、依存関係の破綻を検知・修復するイベントハンドラ
‘ ==============================================================================
‘ 監視フラグ(無限ループ防止用)
Private isProcessing As Boolean
‘ タスクが変更された時に自動発火するイベント
Private Sub Project_TaskChange(ByVal Asg As Task)
‘ すでに処理中の場合は二重起動を防止
If isProcessing Then Exit Sub
On Error GoTo ErrorHandler
isProcessing = True
‘ デバッグ用:変更されたタスクのIDと名前を出力
‘ Debug.Print “検知: タスクID ” & Asg.ID & ” (” & Asg.Name & “) が変更されました。”
‘ 【検証ロジックの実行】
‘ プレデセッサ(先行タスク)が正しく存在しているかチェックする
Call CheckAndRepairDependencies(Asg)
ErrorHandler:
‘ エラーの有無に関わらず、必ずフラグを戻す(ここ超重要!)
isProcessing = False
Exit Sub
End Sub
‘ ——————————————————————————
‘ 依存関係の整合性をチェックし、破綻している場合に修復・警告するプロシージャ
‘ ——————————————————————————
Private Sub CheckAndRepairDependencies(ByVal t As Task)
Dim predTask As Task
Dim dep As Dependency
‘ タスクが既に削除されている(有効ではない)場合は処理しない
If t Is Nothing Then Exit Sub
On Error Resume Next
If t.IsNull Then Exit Sub
On Error GoTo 0
‘ このタスクが持っているすべての先行タスク(Predecessors)をループ
For Each dep In t.Predecessors
Set predTask = dep.FromTask
‘ 先行タスクが存在しない、または何らかの理由でリンクが無効な場合
If predTask Is Nothing Then
MsgBox “【警告】タスク ID: ” & t.ID & ” (” & t.Name & “) の先行タスクリンクが切断されています!” & vbCrLf & _
“自動的にリンクをクリーンアップします。”, vbExclamation, “WBS 依存関係監視ツール”
‘ 切断された依存関係を削除して破綻を防ぐ
dep.Delete
End If
For Next dep
End Sub
—
コードの解説:ここがエンジニアのこだわりポイント!
1. `Private Sub Project_TaskChange(ByVal Asg As Task)`
- ユーザーが画面上でタスクをいじった瞬間、Projectがこのサブルーチンを自動で呼び出します。引数 `Asg` には、操作された対象のタスクオブジェクトが格納されます。
2. 無限ループを防ぐガード(`isProcessing` フラグ)
- VBAからタスクのプロパティをいじるとき、それ自体がまた `TaskChange` イベントを引き起こす原因になります。これを防ぐために `isProcessing` というスイッチを用意し、処理中は二重に走らないようガッチリガードしています。
3. `dep.FromTask` によるリンクの健闘確認
- タスクが誤って削除されたり、外部とのリンクが切れたりすると、依存関係(Dependency)の参照先(`FromTask`)が `Nothing`(空っぽ)になります。ここを見逃さずにキャッチするのがこのツールのキモです。
—
陥りやすいエラーと回避のコツ
初心者の方や、これまでExcel VBAを書いていた方がProject VBAでよくつまずくポイントをまとめました。
- エラー1:「イベントが全然発火しない!」
- 原因: MS Projectのセキュリティ設定でマクロが無効になっているか、イベントハンドラを書く場所が `ThisProject` ではなく通常の「標準モジュール」になっている可能性があります。イベントは必ず `ThisProject` に記述してください。
- エラー2:「マクロを動かしたらProjectがフリーズした」
- 原因: 先ほど解説した「イベントの無限ループ」です。VBAコード内でタスクを変更した際に `EnableEvents` 相当の制御やフラグ制御を行っていないと、イベントのキャット & レスポンスが無限に続き、強制終了せざるを得なくなります。上記のコードにある `isProcessing` のようなセーフティネットを必ず設けてください。
—
まとめ:自動化の先にある「安心できるWBS」へ
今回は、Project VBAのイベント機能を使って「タスク操作時のリンク切断を検知・修復する」という、少し一歩進んだ自動化テクニックをご紹介しました。
マクロの記録ボタンを押すだけでは決して辿り着けない、「システムが裏側でプロジェクトを守ってくれる」という体験は、開発者にとっても実務担当者にとっても大きな自信になります。
ぜひご自身のプロジェクトファイルにこのコードを組み込み、タスクをグリグリ動かしてその堅牢さを体感してみてください。
あなたのProject VBAライフが、より知的で快適なものになりますように。それではまた次の極限知見でお会いしましょう!
