【入門編】【初心者向け】VBAによる制約条件の一括削除と、プロジェクトの完全ASAP化 – Project VBA解析バイブル

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

固まったスケジュールを解き放つ。Project VBAで制約条件をリセットし、完全ASAP化する極意

「前工程の日程をずらしたのに、なぜか後工程の開始日が動かない……」
「ガントチャートがガチガチに固まっていて、計算が合わない……」

MS Projectを使い込んでいると、必ずと言っていいほどこの壁にぶつかります。原因の多くは、タスクに設定された「制約条件(Constraints)」です。

「Must Start On(必ず開始)」や「Start No Earlier Than(開始は〜以降)」といった制約は、一見便利ですが、積み重なるとプロジェクトの柔軟性を奪う「重石」となります。

今日は、そんな複雑に絡まり合った制約を、VBAの力で一気に、かつスマートに解除して、プロジェクトを「本来あるべき自然な流れ(ASAP:可能な限り早く)」へとリセットする方法を伝授しましょう。

ここをクリアすれば、君のProject VBA操作は「記録」から「制御」へと進化しますよ。

1. なぜスケジュールは「固まって」しまうのか?

まず、エンジニアとして「なぜこの現象が起きるのか」という本質を理解しておきましょう。

MS Projectにおけるタスクのスケジュールは、大きく分けて2つの力によって決まります。

1. 論理的関係(Predecessors/Successors): 「Aが終わったらBを始める」というタスク同士のつながり。
2. 制約条件(Constraints): 「Aは絶対に〇月〇日に始めなければならない」という、タスク個別の強制ルール。

制約条件は、いわば「スケジュールに打ち込まれた釘」です。
どれだけ前後のタスク(論理的関係)を動かそうとしても、釘が打たれているタスクはその位置から動きません。これが、スケジュールが動かなくなる正体です。

プロジェクトをリセットして、本来の論理(ネットワーク図)に従って動かしたいなら、この「釘(制約条件)」をすべて抜き取る必要があるのです。

2. 核心となるオブジェクト:`ConstraintType`

VBAでこの「釘」を操作するために、私たちがターゲットにするのは `Task` オブジェクトの `ConstraintType` プロパティです。

MS Projectにはいくつかの制約タイプがありますが、私たちが目指す「制約なし(ASAP)」の状態は、定数で言うと `pjTaskConstraintNone` と定義されています。

これをすべてのタスクに対して実行する。たったこれだけのロジックですが、プログラミング初学者が陥りやすい「落とし穴」がいくつか存在します。

3. 実践:プロジェクト完全ASAP化マクロ

それでは、現場でそのまま使えるコードを見てみましょう。単にループを回すだけでなく、実務に耐えうる「堅牢な」書き方をしています。

Option Explicit

''' <summary>
''' プロジェクト内の全タスクの制約条件を解除し、
''' プロジェクト開始日基準のASAP(可能な限り早く)スケジュールにリセットします。
''' </summary>
Sub ResetProjectToASAP()
    Dim t As Task
    Dim taskCount As Long
    Dim resetCount As Long
    
    ' --- 1. 準備:パフォーマンスと安全性の確保 ---
    ' 画面更新を停止して処理を高速化します
    Application.ScreenUpdating = False
    ' 計算モードを「手動」にすることで、ループ中の再計算による負荷を防ぎます
    Application.Calculation = pjManual
    
    On Error GoTo ErrorHandler
    
    resetCount = 0
    taskCount = 0
    
    Debug.Print "--- Reset Process Started ---"

    ' --- 2. メインロジック:全タスクの走査 ---
    ' ActiveProject.Tasks をループします
    For Each t In ActiveProject.Tasks
        ' 注意:タスク行が空(Nothing)の場合があるため、必ずチェックします
        If Not t Is Nothing Then
            taskCount = taskCount + 1
            
            ' 制約条件が「なし(None)」ではない場合のみ処理を行う
            If t.ConstraintType <> pjTaskConstraintNone Then
                ' 制約タイプを「なし」に書き換える
                t.ConstraintType = pjTaskConstraintNone
                resetCount = resetCount + 1
            End If
        End If
    Next t

    ' --- 3. 後処理:計算の再実行と復元 ---
    ' 制約を外した後は、論理関係に基づいた再計算が必須です
    Application.Calculate
    
    ' 設定を元に戻します
    Application.Calculation = pjAutomatic
    Application.ScreenUpdating = True

    MsgBox "完了しました!" & vbCrLf & _
           "処理タスク数: " & taskCount & vbCrLf & _
           "制約解除数: " & resetCount, vbInformation, "Reset Complete"
    
    Exit Sub

ErrorHandler:
    ' エラーが発生した場合は、設定を元に戻してからメッセージを出します
    Application.Calculation = pjAutomatic
    Application.ScreenUpdating = True
    MsgBox "エラーが発生しました: " & Err.Description, vbCritical, "Error"
End Sub

4. 伝説のアーキテクトが教える「ここが重要!」

コードをコピペして動かすだけでは、君はまだ「使い手」に過ぎません。プロのエンジニアとして、以下の3つのポイントを血肉にしてください。

① `If Not t Is Nothing Then` の重要性

MS Projectのタスクリストには、作業が入っていない「空の行」が存在することがあります。この空の行に対してプロパティを操作しようとすると、VBAは `Object variable or With block variable not set` というエラーを吐いて止まってしまいます。「オブジェクトが存在するかどうかを確認してから触る」。これは自動化における鉄則です。

② `Application.Calculation` の制御

大規模なプロジェクト(数千タスク)で、ループの中で毎回スケジュールを再計算させていたらどうなるでしょうか? 計算エンジンが過負荷になり、マクロが終わるまで数分、あるいは数十分かかることもあります。
一度 `pjManual`(手動計算)に切り替え、すべての「釘」を抜き終えた後に、最後にドカンと `Application.Calculate` で一括計算させる。これが、プロのパフォーマンス制御です。

③ `pjTaskConstraintNone` への書き換え

ここが今回の魔法の言葉です。これを設定することで、タスクは「前工程が終わったら、すぐに始める」という、本来のネットワーク論理に従うようになります。

5. まとめ:次のステップへ

今回のマクロを実行すると、プロジェクトはまるで氷が溶けるように、論理的なつながりに従ってスムーズに動き出すはずです。

「制約を外す = 自由を与える」

この感覚を忘れないでください。複雑なスケジュールに立ち向かうとき、まずは「何が動きを邪魔しているのか(釘はどこにあるのか)」を見極める。そして、それをコードという道具を使ってスマートに解決していく。

これができれば、君のProject VBAのスキルは、単なる作業の自動化を超えて、プロジェクトの「意思決定を支えるツール」へと昇華します。

さあ、次はどの制約を解き放ちますか? 応援していますよ。

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