こんにちは!プロジェクトマネジメントの現場で、日々数え切れないタスクの網の目に頭を悩ませていませんか?
「マクロの記録」でVBAの第一歩を踏み出したものの、「本格的なWBS(Work Breakdown Structure)を自動制御したい」「プロジェクトの品質を保つためのチェッカーを作りたい」と思ったとき、MS ProjectのVBA(Project VBA)は最強の武器になります。
今回は、上級者向けテーマとして「依存関係の複雑度スコアリング:リンクが多すぎるタスクを自動抽出する品質管理ツール」を一緒に作っていきます。
「ここをクリアすれば、Project VBAのオブジェクトモデルの核心はバッチリですよ!」
難解に見える依存関係(先行タスク・後続タスク)の裏側を、優しく、そしてプロの知見を込めて紐解いていきますね。
—
なぜ「リンクが多すぎるタスク」は悪なのか?
WBSにおいて、タスク同士を結ぶ「依存関係(リンク)」は命綱です。しかし、これが過剰になるとどうなるでしょうか?
1. 変更への耐性がゼロになる:1つのタスクが遅延しただけで、スパゲッティ状に絡み合ったネットワーク全体が崩壊します。
2. クリティカルパスが見えなくなる:どこが本当のボトルネックなのか分からなくなります。
プロの現場では、「1つのタスクに集中する先行・後続リンクの総数(次数)」をモニタリングし、複雑すぎるタスクを早期に検知・修正することが品質管理の要となります。これをVBAで完全自動化してみましょう。
—
押さえておくべきProject VBAの基本とオブジェクト構造
Excel VBAと違い、MS Project VBAには独特の「重み」と「作法」があります。
- `ActiveProject.Tasks` コレクション:プロジェクト内の全タスクの集合体です。
- `Task.Predecessors` と `Task.Successors`:ここが今回のキモです。タスクオブジェクトは、自分に繋がる「先行タスク(Predecessors)」と、自分が渡す「後続タスク(Successors)」のコレクションを持っています。
- インデックスの罠:MS ProjectのタスクIDは 1 から始まります。コレクションをループさせる際は、削除や追加を行わない参照専用であれば `For Each` が安全かつ高速です。
—
【実践】リンク過多タスクを自動抽出する品質管理マクロ
それでは、実務でそのままコピペして使える完全版のコードを公開します。
このコードは、全タスクの「先行リンク数 + 後続リンク数」を計算し、閾値(今回は例として `5`)を超えている危険なタスクをイミディエイトウィンドウに警告し、さらにタスクの色を変更して視覚的に炙り出します。
‘ ==============================================================================
‘ 依存関係の複雑度スコアリング・品質管理ツール
‘ 概要: 各タスクのリンク総数(先行+後続)を算出し、過剰な複雑性を持つタスクを検知
‘ ==============================================================================
Sub AuditTaskComplexity()
Dim tsk As Task
Dim predCount As Long
Dim succCount As Long
Dim totalLinks As Long
‘ 【設定】危険水域とするリンク数の閾値(この数を超えると警告)
Const THRESHOLD_LIMIT As Long = 5
‘ 処理カウンター
Dim warningCount As Long
warningCount = 0
‘ ヘッダー出力(イミディエイトウィンドウ)
Debug.Print “==================================================”
Debug.Print ” [WBS品質監査] 依存関係複雑度チェックを開始します…”
Debug.Print ” 閾値設定: リンク総数 ” & THRESHOLD_LIMIT & ” 超過を検知します。”
Debug.Print “==================================================”
‘ 画面描画を停止してマクロの実行速度を爆発的に上げる(プロの常道)
Application.ScreenUpdating = False
‘ プロジェクト内の全タスクを走査
For Each tsk In ActiveProject.Tasks
‘ サマリータスク(親タスク)や削除済みタスクを除外するための安全策
If Not tsk Is Nothing Then
If tsk.Summary = False And tsk.Active = True Then
‘ 先行タスク数と後続タスク数をカウント
‘ ※ .Count プロパティでコレクションの要素数を一発で取得できます
predCount = tsk.Predecessors.Count
succCount = tsk.Successors.Count
totalLinks = predCount + succCount
‘ 複雑度が閾値を超えているか判定
If totalLinks > THRESHOLD_LIMIT Then
warningCount = warningCount + 1
‘ 1. イミディエイトウィンドウに詳細を出力
Debug.Print “【警告 #” & warningCount & “】” & _
“ID: ” & tsk.ID & ” | ” & _
“タスク名: ” & tsk.Name & ” | ” & _
“リンク総数: ” & totalLinks & _
” (先行: ” & predCount & ” / 後続: ” & succCount & “)”
‘ 2. 視覚的警告:該当タスクの背景色を「赤」に変更(MS Project標準のFontColorを使用)
‘ ※視覚化することでガントチャート上で一発で発見できます
tsk.FontColor = pjRed
Else
‘ 正常なタスクは色をデフォルトに戻す
tsk.FontColor = pjAutomatic
End If
End If
End If
Next tsk
‘ 画面描画を再開
Application.ScreenUpdating = True
‘ 監査結果サマリー
Debug.Print “==================================================”
Debug.Print ” 監査終了。 危険水域のタスク数: ” & warningCount & ” 件”
Debug.Print “==================================================”
‘ ユーザーへのポップアップ通知
If warningCount > 0 Then
MsgBox “品質監査が完了しました。” & vbCrLf & _
“リンクが過剰なタスクが ” & warningCount & ” 件検出されました。” & vbCrLf & _
“イミディエイトウィンドウ(Ctrl + G)およびガントチャートの赤字を確認してください。”, _
vbExclamation, “WBS品質警告”
Else
MsgBox “品質監査が完了しました。” & vbCrLf & _
“検出された過剰リンクタスクはありません。素晴らしい状態です!”, _
vbInformation, “WBS品質正常”
End If
End Sub
—
コードの核心:ここがエンジニアのこだわりポイント
初心者から一歩抜け出すために、上記のコードに込めた「3つのエンジニアリング知見」を解説します。
1. `Application.ScreenUpdating = False` による爆速化
MS Projectは、タスクのプロパティ(今回は `FontColor`)を書き換えるたびに画面のガントチャートを再描画しようとします。タスクが1,000件あると、これだけで数秒〜数十秒のロスになります。処理の最初に画面更新を止め、最後に復帰させることで、数ミリ秒単位の高速化を実現しています。これが大規模プロジェクトを扱うプロの作法です。
2. サマリータスク(親タスク)の除外
`If tsk.Summary = False` という条件に注目してください。
MS Projectのサマリータスクは、子タスクの集約によって自動的にスケジュールやリンクが計算されることが多く、手動で複雑な依存関係を結ぶべきではありません。ここを判定せずにカウントしてしまうと、誤検知の山になってしまいます。実務に耐えうるツールにするための必須のフィルターです。
3. コレクションの `.Count` プロパティの活用
`tsk.Predecessors.Count` は、そのタスクに何本の矢印が刺さっているかを一瞬で教えてくれます。複雑なループを回さずともプロパティ一発で取得できるため、Project VBAのオブジェクトモデルを正しく理解していれば非常にシンプルに記述できます。
—
陥りやすいエラーと回避策
- エラー 91: 「オブジェクト変数または With ブロック変数が見つかりません。」
- 原因: 途中で削除されたタスク(空番)にアクセスしようとしたときに発生します。
- 対策: 今回のコードのように `If Not tsk Is Nothing Then` で存在チェックを挟むことで完全に防御できます。
- リンク数がなぜか0になる
- 原因: リンク先のタスクが「非アクティブ(Active = False)」になっている場合、集計から外れることがあります。プロジェクトの運用ルールに合わせて `tsk.Active` の条件は見直してください。
—
まとめ:自動化で「本質的なプロジェクト管理」に集中しよう
今回は、依存関係の複雑度をスコアリングし、スパゲッティ状になった危険なタスクを自動抽出する品質管理ツールをご紹介しました。
「ここをクリアすれば、Project VBAの基本はバッチリですよ!」
タスクの洗い出しや細かいリンクのチェックといった機械的な作業はすべてVBAに任せ、私たちエンジニアやPMは、「どうすればプロジェクトが成功するか」という本質的なリスクヘッジとコミュニケーションに時間を使いましょう。
あなたの現場のWBSが、美しく健全な構造に生まれ変わる手助けになれば幸いです。次回の応用編もお楽しみに!
