こんにちは。プロジェクト管理の荒波を乗り越えてきたエンジニアの皆さん、そしてこれからProject VBAの深淵に触れようとしている皆さん。私は、数えきれないほどのガントチャートを自動化し、リソースの悲鳴をコードで解決してきたチーフアーキテクトです。
MS Projectを使っていると、必ずぶつかる壁があります。そう、「リソースの超過(オーバーアロケーション)」です。
画面に並ぶ真っ赤な人型アイコン……。これを見ただけで胃が痛くなるマネージャーも多いはず。標準機能の「リソースの平準化」も強力ですが、「なぜこのタスクがここに動いたのか?」というロジックがブラックボックスになりがちです。
今日は、「カスタムフィールドで設定した優先度に従って、オーバーアロケーションを自動で解消するシミュレーター」をVBAで構築しましょう。マクロの記録を卒業し、Projectのオブジェクトモデルを掌握する第一歩として、これほど最適なテーマはありません。
—
1. Project VBAの本質:タスクとリソースの「対話」を理解する
コードを書く前に、Project VBAを操る上で最も大切な概念を整理しましょう。
MS Projectのデータ構造は、大きく分けて3つの要素で構成されています。
1. Task(タスク): 「何を」やるか
2. Resource(リソース): 「誰が」やるか
3. Assignment(割り当て): 「誰が・何を」やるかという接点
オーバーアロケーションの解消とは、このAssignment(接点)の時間をずらす作業に他なりません。今回は、「優先度の低いタスクは、空くまで後回しにする」という極めて人間的で合理的なロジックを実装します。
—
2. 準備:カスタムフィールドの設定
今回のコードでは、タスクの「優先度」を判定基準にします。
MS Projectの標準フィールド「優先度(Priority)」を使っても良いですが、今回はより柔軟に「数字1(Number1)」というカスタムフィールドを使ってみましょう。
- 数字1: 1(最優先)〜 99(後回しOK)
- ルール: 数値が小さいほど偉い(動かさない)。数値が大きいほど、リソースが足りない時に後ろに倒される。
—
3. 実践:優先度ベースの自動ソート&シフト・コード
それでは、魂を込めたコードを紹介します。このマクロは、プロジェクト内の全リソースをチェックし、負荷超過がある場合に「優先度の低いタスク」を1日ずつ後ろにずらしてシミュレーションを行います。
Option Explicit
‘ ==========================================================================
‘ プログラム名:ResourcePriorityLeveling
‘ 概要:リソースの超過を検知し、タスクの優先度(数字1)に基づき自動で後ろ倒しする
‘ ==========================================================================
Sub ResourcePriorityLeveling()
Dim rs As Resource
Dim t As Task
Dim asgn As Assignment
Dim loopCount As Integer
Dim maxIterations As Integer
Dim isShifted As Boolean
‘ 無限ループ防止用の安全装置(100回試行してダメなら停止)
maxIterations = 100
loopCount = 0
‘ 描画停止による高速化
Application.ScreenUpdating = False
Debug.Print “— シミュレーション開始 —”
‘ 1. プロジェクト内の全リソースをスキャン
For Each rs In ActiveProject.Resources
If Not rs Is Nothing Then
‘ リソースがオーバーアロケーション(超過)しているか?
Do While rs.Overallocated
isShifted = False
loopCount = loopCount + 1
‘ 安全装置のチェック
If loopCount > maxIterations Then
MsgBox rs.Name & ” の負荷調整が規定回数内で終わりませんでした。手動調整を検討してください。”, vbExclamation
Exit Do
End If
‘ 2. そのリソースに割り当てられたタスクの中から、最も優先度の低い(数字1が大きい)ものを探す
Dim targetAsgn As Assignment
Dim maxPriority As Double
maxPriority = -1
For Each asgn In rs.Assignments
‘ 完了していないタスクのみ対象
If asgn.Task.PercentComplete < 100 Then
' カスタムフィールド「数字1」を優先度として読み込む(空なら999とする)
Dim currentPriority As Double
currentPriority = IIf(IsNumeric(asgn.Task.Number1), asgn.Task.Number1, 999)
' より優先度が低い(数値が大きい)タスクをターゲットに設定
If currentPriority > maxPriority Then
maxPriority = currentPriority
Set targetAsgn = asgn
End If
End If
Next asgn
‘ 3. ターゲットにしたタスクの開始日を1日後ろにずらす
If Not targetAsgn Is Nothing Then
‘ ※ Project VBAの基本:タスクのStartを書き換えると割り当て全体が動く
targetAsgn.Task.Start = Application.DateAdd(targetAsgn.Task.Start, “1d”)
isShifted = True
‘ ログ出力(イミディエイトウィンドウ)
Debug.Print “調整中: リソース[” & rs.Name & “] タスク[” & targetAsgn.TaskName & “] を1日後ろ倒ししました。”
End If
‘ もし何も動かせなかったらループを抜ける
If Not isShifted Then Exit Do
Loop
End If
Next rs
Application.ScreenUpdating = True
MsgBox “リソース負荷の調整シミュレーションが完了しました。”, vbInformation, “完了”
End Sub
—
4. コードの急所:なぜこう書くのか?
このコードには、Project VBAを掌握するためのエッセンスが詰まっています。
① `rs.Overallocated` プロパティ
これはMS Projectが内部で計算している「赤い人型アイコン」の状態を直接参照しています。自分でカレンダーを計算する必要はありません。Projectの脳が「苦しい!」と言っている間、ループを回せば良いのです。
② `Assignment` オブジェクトの操作
`Task`だけを見ても、「誰がそのせいで忙しいのか」は分かりません。リソース(`Resource`)側から紐付いている `Assignments`(割り当て)を走査することで、ピンポイントに原因となっているタスクを特定できます。
③ `Application.DateAdd` の活用
VBA標準の `DateAdd` ではなく、Projectアプリケーションの `DateAdd` を使ってください。これにより、プロジェクトのカレンダー(休日設定など)を考慮して「1日後」を計算してくれます。土日を無視して無理やりタスクを突っ込むような無粋な真似はしません。
—
5. 陥りやすいエラーと回避策
初心者の方が最初につまずくポイントを、チーフアーキテクトの視点で解説します。
- 「オブジェクトが必要です」エラー (424):
空のリソース行(名前が入っていない行)がある場合に発生しやすいです。`If Not rs Is Nothing Then` や `If Not t Is Nothing Then` といった「存在チェック」を癖にしましょう。
- 無限ループの恐怖:
優先度が同じタスクが並んでいる場合や、依存関係(先行タスク)が複雑な場合、日付を動かしても超過が解消されないことがあります。コード内に `loopCount` という安全装置を入れたのはそのためです。
- 先行タスクとの競合:
このコードは単純に日付を動かしますが、タスクに「終了-開始(FS)」などのリンクがある場合、Projectのスケジュールエンジンが自動的に後続タスクも動かします。これが「連鎖反応」となって全体の工期が伸びる様子を、ぜひイミディエイトウィンドウで観察してみてください。
—
結びに:Project VBAを学ぶあなたへ
マクロの記録で得られるコードは、いわば「操作の足跡」です。しかし、今回のように 「オブジェクト(リソースやタスク)の状態を監視し、判断を下させる」 コードが書けるようになると、MS Projectは単なる管理表から「優秀な秘書」へと進化します。
リソースの負荷を自動で調整する。このロジックを自力で組めたなら、あなたはもう初学者ではありません。Projectの心臓部を動かすエンジニアへの門を叩いています。
次は、コスト(Cost)計算や、実績進捗(Actual)との連動に挑戦してみてください。Project VBAの世界は、知れば知るほどあなたのビジネス武器になるはずです。
「ここをクリアすれば、Project VBAの基本はバッチリですよ。応援しています!」
