【入門編】実務中級:リソース平準化と制約条件の競合をVBAで解決する優先順位調整 – Project VBA解析バイブル

スポンサーリンク
スポンサーリンク

「日付」と「リソース」の衝突を乗りこなす —— Project VBAで制御するスケジュールの真実

こんにちは。プロジェクトの複雑なパズルを解き明かす準備はできていますか?

マクロの記録ボタンを押し、記録されたコードを眺めて「ふむふむ、動いているな」と満足する。それは素晴らしい第一歩です。しかし、実務の現場で求められるのは、単なる「操作の自動化」ではありません。

「リソースが足りないけれど、納期(制約条件)は動かせない。この矛盾をどう解決するか?」

この、プロジェクトマネジメントにおける「究極のジレンマ」に、プログラムの力で論理的な答えを出すこと。それこそが、真の自動化エンジニアが目指すべき領域です。

今日は、Microsoft Project VBAにおける「制約条件(Constraints)」と「リソース平準化(Resource Leveling)」の衝突を、どのようにスマートに解決するか。その極限の知見を伝授します。

1. なぜ、スケジュールは「破綻」するのか?

プロジェクトを管理していると、必ずと言っていいほど以下の2つの力が衝突します。

1. 制約条件(Constraint)の力
「このタスクは絶対に〇月〇日に終わらせなければならない(Must Finish On)」という、日付に対する強力な縛りです。
2. リソース平準化(Leveling)の力
「担当者の作業量が限界を超えているから、タスクを後ろにずらして調整しよう」という、現実的なリソースの制約です。

衝突のメカニズム

平準化エンジンが「リソース不足だからタスクを3日後ろにずらそう」と判断したとき、そのタスクに「Must Finish On(〇月〇日に必ず終了)」という制約がかかっていたらどうなるでしょうか?

エンジンは身動きが取れなくなります。
制約(ルール)を守ろうとすれば、リソース不足(現実)を無視することになり、スケジュールは「過負荷(Overallocated)」のまま放置されるか、あるいは計算エラーのような不自然な状態に陥ります。

これを解決するには、「制約を緩める(ASAPにする)」か、「リソースの優先順位を上げる」かの判断を、VBAによるロジックで行う必要があるのです。

2. 掌握すべきプロパティ:`ConstraintType`

ここをクリアすれば、Project VBAの基本はバッチリですよ。
この問題を解決するために、私たちが操るべきは `Task` オブジェクトの `ConstraintType` プロパティです。

Projectには、以下のような制約の種類があります(一部抜粋):

定数 (VBA) 意味 強さ
`pjTaskConstraintAsSoonAsPossible` できるだけ早く (ASAP) 極小 (平準化に従う)
`pjTaskConstraintStartNoEarlierThan` ~より前には開始しない 中
`pjTaskConstraintMustStartOn` ~に必ず開始する 強
`pjTaskConstraintMustFinishOn` ~に必ず終了する 強

実務的な自動化ツールを作るなら、「強すぎる制約(Must系)を、平準化が効く制約(ASAP系)に動的に書き換える」というロジックが非常に強力な武器になります。

3. 実践:制約条件を自動緩和する解決エンジン

それでは、具体的なコードを見ていきましょう。
このコードは、「リソースが過負荷になっているタスクのうち、強すぎる制約(Must系)を持っているものを見つけ出し、平準化を優先するために制約を『できるだけ早く(ASAP)』へ自動的に変更する」というものです。

Option Explicit

''' <summary>
''' リソース平準化を妨げる「強すぎる制約」を検出し、自動的に緩和する
''' </summary>
Sub ResolveConstraintConflicts()
    Dim t As Task
    Dim proj As Project
    Dim conflictCount As Integer
    
    Set proj = ActiveProject
    conflictCount = 0
    
    ' 高速化のためのテクニック:画面更新や再計算を一時停止する(大規模プロジェクトでは必須)
    ' ただし、Project VBAではCalculationの制御がパフォーマンスの鍵を握ります
    On Error GoTo ErrorHandler
    
    Debug.Print "--- スケジュール整合性チェック開始 ---"

    ' 1. プロジェクト内の全タスクをループ
    For Each t In proj.Tasks
        ' 空のタスク(削除済みなど)はスキップ
        If Not t Is Nothing Then
            
            ' 2. 【判定ロジック】
            ' リソースが過負荷(Overallocated)であり、
            ' かつ、制約が「Must(必ず~)」という強いものかチェック
            If t.ResourceOverallocated = True Then
                
                Select Case t.ConstraintType
                    ' 「必ず終了」という強い制約がある場合
                    Case pjTaskConstraintMustFinishOn, pjTaskConstraintMustStartOn
                        
                        Debug.Print "衝突検知: タスク [" & t.Name & "] はリソース過負荷かつ強制制約があります。"
                        
                        ' 3. 【解決策】制約を「できるだけ早く(ASAP)」に変更
                        ' これにより、平準化エンジンがタスクを動かせるようになる
                        t.ConstraintType = pjTaskConstraintAsSoonAsPossible
                        
                        conflictCount = conflictCount + 1
                        Debug.Print "  -> 解決策: 制約を ASAP (As Soon As Possible) に緩和しました。"
                        
                    ' その他の制約(開始不可など)も必要に応じてここに追加可能
                End Select
                
            End If
        End If
    Next t

    ' 4. 変更を反映させるために再計算を実行
    proj.Calculate
    
    MsgBox "処理が完了しました。" & vbCrLf & _
           "緩和したタスク数: " & conflictCount & " 件", vbInformation, "完了"

    Exit Sub

ErrorHandler:
    MsgMsgBox "エラーが発生しました: " & Err.Description, vbCritical
End Sub

コードの解説:プロの視点

1. `t.ResourceOverallocated` の活用:
単に日付を見るのではなく、Projectのエンジンが「この人は無理していますよ」と判定したフラグを直接参照しています。これが最も確実なトリガーです。
2. `Select Case` による精密な選別:
すべての制約を緩めてしまうと、プロジェクトのコントロールを失います。`Must` 系(強制)だけを狙い撃ちにするのが、プロの「加減」です。
3. `proj.Calculate` のタイミング:
ループの中で毎回 `Calculate` を呼んではいけません。これはパフォーマンスを劇的に低下させ、最悪の場合、無限ループのような挙動を引き起こします。「変更をすべて終えてから、最後に一回」。これが鉄則です。

4. 陥りやすいエラーと回避策

この領域を扱う際、初心者が必ずと言っていいほどハマるポイントが2つあります。

① 「無限ループ」の罠

制約を変更したことで、依存関係(プリセッサー)が連鎖的に動き、別のタスクが過負荷になることがあります。
これを考慮せずに「過負荷がなくなるまで繰り返す」というコードを書くと、計算が終わらなくなります。
対策: 「一度のループで緩和できるのはここまで」という、回数制限や条件の明確化が重要です。

② 「意図しないスケジュールの崩壊」

すべての `Must` 制約を解除してしまうと、クライアントとの約束(納期)が勝手に書き換わってしまいます。
対策: ツールを実行する前に、必ず「制約を緩和してもよいタスク」に特定のフラグ(例えば、テキスト欄に “RELAX” と入力しておくなど)を立て、そのフラグがあるタスクだけを対象にする、といった安全装置を組み込みましょう。

最後に:エンジニアとしてのマインドセット

Project VBAを使いこなすということは、単にプログラムを書くことではありません。「プロジェクトの論理構造」を理解し、それをコードという言語で翻訳することです。

制約とリソースの衝突を解決するツールは、単なる便利機能ではなく、プロジェクトの「健全性」を守るための防衛策になります。

「マクロの記録」から一歩踏み出し、今回のような「オブジェクトの性質(ConstraintType)」に基づいたロジックを組み立てられるようになれば、あなたはもう、立派な自動化エンジニアです。

さあ、次はあなたのプロジェクトで、このロジックを試してみてください。応援していますよ!

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