【上級プロ】Project VBAによる「リソース平準化」の自動実行と競合検知・品質管理エンジンの構築
開発現場のリーダー諸君、日々のリソース管理に頭を悩ませていないか?
「マルチプロジェクトでリソースがオーバーアロケーション(過負荷)を起こしている」「手動で平準化をかけたが、どこにしわ寄せがいったか分からない」「気づけば納期が遅延している」――こうした泥臭い課題を、VBAのコード一本でスマートに解決するのがプロのエンジニアの仕事だ。
MS Projectの標準機能である「リソース平準化(Leveling)」は強力だが、UIからポチポチと手動で実行しているようでは、大規模案件の品質管理において致命的な属人性を生む。さらに、平準化を実行した結果、「どのタスクがどれだけ押し出されたのか」「どのリソースの悲鳴が止まっていないのか」を自動でキャッチアップしなければ、真の進捗コントロールとは言えない。
今回は、Project VBAのオブジェクトモデルを極限まで理解し、`LevelingOptions`を自在に操り、平準化後の競合(オーバーアロケーション)を自動検知して構造化ログを出力する「品質管理エンジン」のプロダクションコードを伝授する。
—
1. なぜ「手動平準化」と「安易なVBAコード」は失敗するのか
多くの自称・中級プログラマブルなコードは、単に `ProjectLevel` メソッドを呼び出して終わりにする。
これでは実務で使い物にならない。理由は以下の3点だ。
1. スコープの統制不在: プロジェクト全体を無条件に平準化すると、クリティカルパス上の固定タスクまで歪められ、マイルストーンが崩壊する。
2. 結果のブラックボックス化: 平準化アルゴリズムがどこで妥協し、どのリソースにオーバーアロケーションが残存したのかをコードが検知していない。
3. エラーハンドリングの欠如: リソースプールや外部リンクを持つファイル群で平準化を実行すると、MS Project特有のモーダルダイアログがポップアップし、バッチ処理が完全にフリーズする。
これらを完全に克服するためには、「実行前の環境構築(`LevelingOptions`の厳密な設定)」と、「実行後のオブジェクト走査による差分・残存競合の検知」をセットで実装する必要がある。
—
2. プロダクションコード:リソース平準化&競合検知エンジン
以下のコードは、エラーハンドリング、ダイアログ抑制、詳細な平準化ルールの適用、そして平準化後にまだオーバーアロケーションにあえぐリソースとタスクを特定してイミディエイトウィンドウ(あるいはログファイル)に出力する完全版のモジュールだ。
Option Explicit
‘================================================================================
次元を超えるProject VBA: リソース平準化 & 品質管理エンジン
Architected by 首席自動化エンジニア
================================================================================
Public Sub RunAdvancedResourceLevelingEngine()
Dim prj As Project
Set prj = ActiveProject
‘ 1. 安全性の担保:UI描画とアラートの抑制(バッチ処理の基本)
App.ScreenUpdating = False
App.DisplayAlerts = False
On Error GoTo ErrorHandler
Debug.Print “=== [INFO] リソース平準化エンジン起動: ” & prj.Name & ” ===”
‘ 2. 平準化オプション(LevelingOptions)の厳密なチューニング
With prj
.LevelingOptions.ClearLd ‘ 既存の平準化遅延をクリア(クリーンslateから開始)
.LevelingOrder = pjLevelID ‘ ID順(または pjLevelStandard / pjLevelPriority)
.LevelingCanSplit = True ‘ タスクの分割を許可し、過負荷を柔軟に吸収
.LevelingAdjust = pjLevelFreeSlack ‘ フリーバッファ(自由余裕時間)の範囲内で調整
.LevelingRange = pjLevelEntire ‘ プロジェクト全体を対象
.LevelingManual = False ‘ 自動平準化モードを有効化
End With
‘ 3. リソース平準化の実行
‘ 引数: ClearBeyond = False (遅延を超えたクリアはしない), SingleProject = prj
prj.LevelNow ClearBeyond:=False, SingleProject:=prj
Debug.Print “[SUCCESS] リソース平準化の実行が完了しました。残存競合の解析を開始します…”
‘ 4. 品質管理:平準化後のオーバーアロケーション(競合)自動検知
Call AnalyzeRemainingConflicts(prj)
CleanUp:
‘ 5. 環境の復元
App.ScreenUpdating = True
App.DisplayAlerts = True
Debug.Print “=== [INFO] エンジン処理が正常終了しました ===”
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“Error No: ” & Err.Number & vbCrLf & _
“Description: ” & Err.Description, vbCritical, “Project VBA Engine Error”
Resume CleanUp
End Sub
‘================================================================================
‘ 平準化残存競合(オーバーアロケーション)の深層解析とログ出力
‘================================================================================
Private Sub AnalyzeRemainingConflicts(ByVal targetPrj As Project)
Dim res As Resource
Dim asg As Assignment
Dim conflictCount As Long
conflictCount = 0
Debug.Print “————————————————–”
Debug.Print ” [REPORT] 平準化残存オーバーアロケーション分析レポート”
Debug.Print “————————————————–”
‘ リソースコレクションを走査
For Each res In targetPrj.Resources
‘ リソースが有効かつ、コストやマテリアルではなく「仕事現場の人員」である場合
If Not res Is Nothing Then
If res.Type = pjResourceTypeWork Then
‘ Peak (ピークユニット) が MaxUnits を超えているかをチェック
‘ ※ Projectオブジェクトモデルでは Peak >= MaxUnits 100 で過負荷判定
If res.Peak > (res.MaxUnits 100) Then
conflictCount = conflictCount + 1
Debug.Print “【警告 # ” & conflictCount & “】過負荷リソース検知”
Debug.Print ” – リソース名: ” & res.Name
Debug.Print ” – 最大キャパ: ” & (res.MaxUnits 100) & “%”
Debug.Print ” – ピーク負荷 : ” & res.Peak & “%”
Debug.Print ” – 該当する割当タスク:”
‘ このリソースに起因するオーバーアロケーションタスクを特定
For Each asg In res.Assignments
If asg.Overallocated Then
Debug.Print ” -> タスクID: ” & asg.Task.ID & _
” / タスク名: ” & asg.Task.Name & _
” / 期間: ” & asg.Start & ” ~ ” & asg.Finish
End If
Next asg
Debug.Print “————————————————–”
End If
End If
End If
Next res
If conflictCount = 0T Then
Debug.Print “[判定] 素晴らしい!すべてのリソース競合が完全に解消されました。”
Else
Debug.Print “[判定] 警告: ” & conflictCount & ” 件のリソースで平準化しきれない過負荷が残存しています。”
Debug.Print ” プロジェクトマネージャーによる手動調整(スコープ削減または納期延長)が必要です。”
End If
End Sub
—
3. コードのキームーブと設計思想の解説
1. `App.ScreenUpdating = False` と `DisplayAlerts = False` の鉄則
MS Projectは、VBAからオブジェクトを操作するたびにガントチャートの再描画や、リソース競合警告のポップアップを律儀に実行する。これが数千行のタスクを持つプロジェクトファイルで起きると、実行速度が数十倍〜数百倍に低下するだけでなく、ダイアログで処理がストップする。バッチ処理の冒頭で確実にロックし、終了時に復元する設計がプロの必須作法だ。
2. `LevelingOptions` の明示的初期化
デフォルトの平準化プロパティは、前回のユーザー操作(UIでの設定)を引き継ぐため、環境によって挙動が変わるという致命的なバグの温床になる。
コード内で `.LevelingOrder`, `.LevelingCanSplit`, `.LevelingAdjust` を毎回明示的に指定することで、どのPC、どのプロジェクトファイルで実行しても「完全に再現性のある結果」を担保している。
3. `Assignment.Overallocated` による精緻な差分検知
平準化を実行した後に「本当にリソースの悲鳴が消えたのか」を判定するため、リソースの `Peak` 値と、各割当(`Assignment`)の `Overallocated` プロパティを走査している。
これにより、「どのタスクが原因で、そのリソースがパンクしているのか」をイミディエイトウィンドウへ構造化テキストとして出力でき、そのままCSVやデータベース、Teams等の通知チャネルへ連携する拡張性を持たせている。
—
4. 現場へ導入する際のデータベース・ファイル連携の注意点
このVBAエンジンを組織の標準ツールとして組み込む場合、以下のインフラ的配慮が不可欠である。
- 排他制御(マルチユーザー環境の罠):
企業内の共有サーバーやProject Server / Project Online環境において、他者が編集中(チェックアウト状態)のファイルをVBAから強制平準化しようとすると、保存時競合エラーが発生する。実行前に `FileOpen` やオブジェクトの読取専用フラグをチェックするガード節を入れること。
- ログの永続化:
今回のサンプルコードでは `Debug.Print`(イミディエイトウィンドウ出力)を用いているが、プロダクション環境では `FileSystemObject (FSO)` を用いて、ローカルまたはネットワークドライブの `C:\Logs\ProjectLeveling_{YYYYMMDD}.log` へ吐き出すように拡張してほしい。これにより、過去の平準化履歴と品質推移をBIツール(Power BI等)でトラッキング可能になる。
—
総括
VBAは、単なる「退屈な作業の自動化ツール」ではない。
正しく設計されたProject VBAは、プロジェクトの遅延リスクを未然に刈り取る「攻めのガバナンス・エンジン」へと昇華する。
今回提供したコードをあなたの開発環境にブチ込み、リソース管理の品質を次のステージへと引き上げてくれ。健闘を祈る。
