【入門編】【実務中級】プロジェクトテンプレート適用時の「制約条件クリーンアップ」:不要な制約の自動削除スクリプト – Project VBA解析バイブル

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

【実務中級】プロジェクトの「硬直化」を防ぐ:テンプレート適用時の制約条件クリーンアップ術

「タスクの期間を変えたのに、日付が全然動かない……」
「先行タスクをずらしたはずなのに、なぜか後ろのタスクが連動してくれない……」

MS Projectを使い込んでいると、一度はこのような「スケジュールの硬直化」に直面したことがあるはずです。実はこれ、あなたの操作ミスではなく、プロジェクトの中に潜む「古い制約条件(Constraints)」が犯人であることがほとんどなのです。

特に、過去のプロジェクトをコピーして「テンプレート」として再利用しようとする際、この「制約の残骸」が牙を剥きます。

今日は、そんな「見えないブレーキ」を一括で解除し、プロジェクトを真っさらな(=計算エンジンが本来の力を発揮できる)状態に戻すための、制約条件クリーンアップ・スクリプトの極意を伝授しましょう。

ここをクリアすれば、あなたは「マクロを記録する人」から、「プロジェクトの挙動を制御するエンジニア」へと一歩踏み出すことができますよ。

1. なぜ「制約条件」がスケジュールを壊すのか?

まず、エンジニアとして「なぜこれが必要なのか」という本質を理解しておきましょう。ここが抜けると、ただコードを書き写すだけの作業になってしまいます。

MS Projectのスケジュール計算は、大きく分けて2つの要素で決まります。

1. ロジック(依存関係): 「タスクAが終わったらタスクBを始める」という矢印(Predecessors)。
2. 制約条件(Constraints): 「タスクCは、絶対に〇月〇日に開始しなければならない」という、ロジックを無視した強制ルール。

テンプレートを作成する際、過去のプロジェクトからタスクをコピーすると、「開始日指定」や「Must Start On(必ずこの日に開始)」といった制約条件まで一緒に付いてきてしまうことがあります。

制約条件が設定されたタスクは、たとえ先行タスクが遅延しても、その日付に「錨(アンカー)」を下ろしたまま動きません。これが、スケジュールが計算エンジンに従わず、硬直してしまう正体です。

理想的なプロジェクトとは、すべてのタスクが「ASAP(可能な限り早く)」、つまり制約条件が `None`(なし)の状態であり、純粋にロジック(矢印)だけで動いている状態を指します。

2. 実践:制約条件を一括削除するVBAスクリプト

それでは、プロジェクト内の全タスクをスキャンし、不要な制約条件を「なし(pjTaskConstraintNone)」に書き換えるコードを見ていきましょう。

このコードは、単に値を書き換えるだけでなく、「計算負荷」と「エラー回避」を考慮した、実務レベルの構成にしています。

Option Explicit

''' <summary>
''' プロジェクト内の全タスクから制約条件を解除し、
''' スケジュール計算エンジンがロジック通りに動ける状態にします。
''' </summary>
Sub CleanupProjectConstraints()
    Dim t As Task
    Dim taskCount As Long
    Dim resetCount As Long
    
    ' 1. パフォーマンス最適化:計算モードを「手動」に切り替え
    ' 1タスクごとに再計算が走ると、大規模プロジェクトでは数分かかることがあります。
    Application.Calculation = pjManual
    
    ' 画面更新を停止(処理速度向上と画面のチラつき防止)
    ' ※MS Project VBAにはExcelのScreenUpdatingに相当する直接のプロパティがないため、
    '   計算モードの制御が主な高速化手段となります。

    On Error GoTo ErrorHandler

    ' カウント用の変数初期化
    taskCount = 0
    resetCount = 0

    ' 2. プロジェクト内の全タスクをループ処理
    ' ActiveProject.Tasks は、空白行(Nothing)を含む可能性があるため注意が必要
    For Each t In ActiveProject.Tasks
        
        ' タスクが存在しない(空白行)場合はスキップ
        If Not t Is Nothing Then
            taskCount = taskCount + 1
            
            ' 3. 制約条件のチェックと解除
            ' すでに「制約なし」の場合は何もしないことで、無駄な書き込みを避ける
            If t.ConstraintType <> pjTaskConstraintNone Then
                
                ' サマリータスク(中間タスク)への制約解除は、
                ' 下位タスクの計算に影響を与えるため、慎重に行う必要があります。
                ' ここでは、すべてのタスクの制約をリセットします。
                t.ConstraintType = pjTaskConstraintNone
                resetCount = resetCount + 1
                
            End If
        End If
    Next t

    ' 4. 後処理:計算モードを「自動」に戻す
    Application.Calculation = pjAutomatic
    
    MsgBox "【完了】" & vbCrLf & _
           "スキャンしたタスク数: " & taskCount & vbCrLf & _
           "解除した制約数: " & resetCount, vbInformation, "クリーンアップ完了"

    Exit Sub

ErrorHandler:
    ' エラーが発生した場合は、計算モードを必ず「自動」に戻して終了する
    Application.Calculation = pjAutomatic
    MsgBox "エラーが発生しました: " & Err.Description, vbCritical, "エラー"
End Sub

3. コードの「ここがプロの視点」:3つの重要ポイント

「マクロの記録」では絶対に辿り着けない、設計のポイントを解説します。

① `Application.Calculation = pjManual` の魔法

MS Projectは、プロパティ(日付や制約)が一つ変わるたびに、プロジェクト全体のスケジュールを再計算しようとします。
もし1,000個のタスクに対してループを回し、毎回再計算させていたら……? プログラムはフリーズしたように重くなってしまいます。
「作業中は計算を止めておき、最後に一括で計算させる」。これが、大量のデータを扱うエンジニアの鉄則です。

② `If Not t Is Nothing Then` による防御

MS Projectのタスクリストには、ユーザーが何も入力していない「空白の行」が存在します。
この空白行に対して「制約を消せ!」と命令を出すと、プログラムは「そんなタスクはありません」とエラーを吐いて止まってしまいます。
「オブジェクトが実在するかどうかを確認してから操作する」。これはVBAにおける生存戦略です。

③ `pjTaskConstraintNone` という定数

制約を消すとき、単に「空にする」のではなく、`pjTaskConstraintNone` という専用の定数を使います。これにより、MS Projectに対して「このタスクは制約を持たない、純粋なロジック駆動のタスクである」と明確に宣言できるのです。

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

このスクリプトを使う際に、覚えておいてほしい注意点があります。

  • サマリータスク(中間タスク)の扱い:

サマリータスク(タスクをまとめている親行)に制約をかけると、その配下のタスクすべてが不自然な動きをすることがあります。今回のスクリプトはすべてをリセットしますが、もし「親タスクの期間は手動で管理したい」という場合は、`If t.Summary = False Then` という条件を追加して、「作業タスクのみを対象にする」というフィルタリングを行ってください。

  • 「手動スケジューリング」との混同:

制約を消しても、タスクのモードが「手動スケジューリング(Manually Scheduled)」のままだと、日付は自動で動きません。
もし完全に自動化したいなら、コードの中に `t.Manual = False` を追加して、「自動スケジューリング」へ強制変更する処理を組み込むと、より強力なクリーンアップツールになります。

最後に:一歩先へ進むあなたへ

お疲れ様でした! これであなたは、プロジェクトの「硬直化」という厄介な問題に対して、プログラムという武器で立ち向かう術を手に入れました。

「マクロの記録」は、あなたの動きを写し取る便利なツールです。しかし、今回学んだように「計算の重みを制御する」「エラーを未然に防ぐ」「オブジェクトの性質を見極める」といった視点は、記録機能では決して教えてくれません。

これらを意識するだけで、あなたの書くコードは「動くもの」から「信頼されるシステム」へと進化します。

さあ、次のプロジェクトでは、このクリーンな状態から、最高のスケジュールを構築していきましょう!

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