【入門編】【実務中級】マイルストーンタスクへの「終了日固定」制約一括適用:納品日管理の自動化ツール – Project VBA解析バイブル

スポンサーリンク

こんにちは。今日は、Microsoft Projectを単なる「予定表」から、プロジェクトの「守護神」へと進化させるための、少し踏み込んだテクニックについてお話ししましょう。

「マクロの記録」を使って、ボタン一つで色を変えたり、文字を入力したりすることには慣れてきた。でも、プロジェクトのスケジュールが動くたびに、「あ、このマイルストーンの納期を固定し忘れていた!」とヒヤヒヤすることはありませんか?

今日は、そんな不安を解消するために、「特定のフラグが立ったマイルストーンに対して、一括で『終了日固定制約』を叩き込む自動化ツール」を作っていきましょう。

ここをマスターすれば、あなたは「ただマクロが書ける人」から、「プロジェクトの計算ロジックを制御できるエンジニア」への一歩を踏み出すことになりますよ。

1. なぜ「日付を入れるだけ」では足りないのか?

ここが、初級者と中級者を分ける最も重要な境界線です。

多くのユーザーは、納期を守らせたいとき、タスクの「終了日」のセルに直接日付を入力します。しかし、Microsoft Projectの計算エンジン(スケジューリング・エンジン)にとって、それは単なる「一時の希望」に過ぎないことが多いのです。

「日付入力」と「制約(Constraint)」の違い

  • 日付だけを入力した場合:

前後のタスクとの関係(先行・後続)が変更されたり、リソースの制約が入ったりすると、Projectは「あ、このタスクは後ろにずらしたほうが合理的だな」と判断し、入力した日付を勝手に書き換えてしまいます。

  • 「制約(Constraint)」を設定した場合:

これは計算エンジンに対する「命令」です。「何があっても、この日に終わらせろ(あるいは、この日より後にずらすな)」という、ロジックのルールを定義することになります。

今回私たちが実装するのは、後者の「制約(ConstraintType)」の制御です。これこそが、プロジェクトの納期を死守するためのプロの手法です。

2. 設計図:どのような仕組みを作るか

いきなりコードを書く前に、設計図(アルゴリズム)を整理しましょう。エンジニアの仕事は、コードを書くことではなく「設計すること」です。

今回作るツールの動きはこうです:

1. ユーザーの準備:

  • マイルストーンの「テキスト1」列に、`FIX` という文字を入れる(これがフラグになります)。
  • 「日付1」列に、守るべき「納期」を入力しておく。

2. VBAの動作:

  • プロジェクト内の全タスクを一つずつチェックする。
  • もし「テキスト1」が `FIX` だったら……
  • そのタスクの制約タイプを「Must Finish On(必ずこの日に終了)」に書き換え、制約日を「日付1」に設定する。

3. 完了:

  • 一瞬で、すべての重要納期が「ガチガチに固定」される。

3. 実装:魂を込めたコード例

それでは、コードを見ていきましょう。コピー&ペーストして動かすこともできますが、ぜひコメントを読みながら「なぜこう書くのか」を感じ取ってください。

Option Explicit

''' <summary>
''' マイルストーンの納期を強制適用するプロシージャ
''' テキスト1列に "FIX" と入力され、日付1列に納期が入っているタスクを対象とする
''' </summary>
Sub ApplyMilestoneConstraints()
    Dim t As Task
    Dim count As Integer
    count = 0
    
    ' 画面更新を停止してパフォーマンスを向上させる(大規模プロジェクト対策)
    Application.ScreenUpdating = False
    
    On Error GoTo ErrorHandler

    ' プロジェクト内の全タスクをループ処理
    For Each t In ActiveProject.Tasks
        
        ' タスクが存在しない(空行)場合はスキップ
        If Not t Is Nothing Then
            
            ' --- 条件判定のロジック ---
            ' Text1列に "FIX" というフラグが立っているか?
            If t.Text1 = "FIX" Then
                
                ' 日付1列に有効な日付が入っているか確認
                If t.Date1 <> "N/A" Then
                    
                    ' 【ここが心臓部】制約タイプを「Must Finish On(必ずこの日に終了)」に変更
                    ' pjMustFinishOn = 3 (定数)
                    t.ConstraintType = pjMustFinishOn
                    
                    ' 制約日を、日付1列に入力された値に設定
                    t.ConstraintDate = t.Date1
                    
                    count = count + 1
                Else
                    ' フラグはあるのに日付がない場合は、警告としてセルに色をつける等の処理も可能
                    ' 今回はシンプルにスキップ
                End If
                
            End If
        End If
    Next t

    ' 画面更新を再開
    Application.ScreenUpdating = True
    
    MsgBox count & " 件のマイルストーンに納期固定制約を適用しました。", vbInformation, "完了"
    Exit Sub

ErrorHandler:
    Application.ScreenUpdating = True
    MsgBox "エラーが発生しました: " & Err.Description, vbCritical, "エラー"
End Sub

コードのポイント解説

1. `If Not t Is Nothing Then`:
Projectのタスクリストには、途中に空行が含まれることがあります。空のオブジェクトに対してプロパティを操作しようとするとエラーで止まってしまうため、この一行は「エンジニアの嗜み」として必ず入れましょう。
2. `pjMustFinishOn`:
これはProject VBAが定義している「定数」です。数字の `3` と書いても動きますが、後でコードを読み返したときに「何をしているか」を一目で理解するために、名前(定数)を使いましょう。
3. `Application.ScreenUpdating`:
タスクが数千件あるプロジェクトでは、一つずつ処理するたびに画面がチカチカ動くと、それだけで計算リソースを食いつぶします。これを `False` にすることで、処理速度が劇的に向上します。

4. 陥りやすい「罠」と、プロの回避術

このツールを使っていると、必ずと言っていいほど直面する問題があります。それは、「スケジュールが矛盾して、見た目がめちゃくちゃになる」ことです。

なぜ矛盾が起きるのか?

「必ずこの日に終わらせろ!」という強力な命令(制約)を、前後のタスクとの関係を無視して無理やり適用すると、Projectの計算エンジンはパニックを起こします。
例えば、

  • タスクA(先行)が終わるのが10日。
  • タスクB(マイルストーン)を「必ず5日に終わらせろ」と制約。
  • 結果 $\rightarrow$ 「マイナスの期間」や「不可能なスケジュール」が発生。

プロのアドバイス

制約を適用した後は、必ず「クリティカルパス」と「スラック(余裕時間)」を確認してください。
もし、制約を適用したせいでスケジュールが赤くなったり、矛盾が出たりした場合は、その制約は「物理的に不可能」であることを意味しています。

自動化ツールは「命令を実行する道具」であって、「無理な計画を正当化する道具」ではありません。ツールが教えてくれた矛盾を、人間が調整する。この「機械のスピード」と「人間の判断」の協調こそが、真のプロジェクト管理です。

まとめ:ここをクリアすれば、基本はバッチリです

いかがでしたか?
単に日付を書き換えるのではなく、`ConstraintType` を操作して「計算エンジンに命令を出す」という考え方。これが理解できれば、あなたはもう「マクロの記録」の域を完全に脱しています。

今回のステップアップ・ポイント:
1. オブジェクトのプロパティ(ConstraintType)を直接制御する。
2. カスタムフィールド(Text1, Date1)を「司令塔」として利用する。
3. エラーハンドリングとパフォーマンス(ScreenUpdating)を意識する。

これらを意識して、ぜひ自分のプロジェクトで試してみてください。
もしエラーが出ても、それは成長のチャンスです。コードの向こう側にある「プロジェクトの論理」を、楽しんでくださいね。

応援していますよ!

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