【入門編】初心者向け:タスクの「制約なし」状態をVBAで判定し、デフォルト値へ置換する – Project VBA解析バイブル

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

【Project VBA極意】「制約」を制する者はスケジュールを制す:タスクの制約を判定し、理想のデフォルトへ書き換える技術

こんにちは。プロジェクトの自動化、そしてスケジュール・エンジンの最適化を専門としているアーキテクトです。

「マクロの記録」ボタンを押し、記録されたコードを眺めては「なぜこれで動くのか?」「どうしてエラーが出るのか?」と頭を悩ませていませんか? もしそうなら、おめでとうございます。あなたは今、「単なる操作の記録」から「プログラミングによる制御」へと脱皮する境界線に立っています。

今日、皆さんに伝授するのは、Microsoft Projectを単なる「表計算ソフト」ではなく、真の「動的スケジュール計算エンジン」として使いこなすための第一歩です。

テーマは、「タスクの制約条件(Constraint)の判定と、理想的なデフォルト状態への一括置換」です。ここをマスターすれば、プロジェクトの柔軟性を劇的に高めるコードが書けるようになります。

1. なぜ「制約(Constraint)」を制御しなければならないのか?

MS Projectの凄みは、タスク間の依存関係(先行・後続)を計算し、一つの変更がプロジェクト全体にどう波及するかを瞬時に解いてくれる「計算エンジン」にあります。

しかし、このエンジンには「制約(Constraint)」という強力なルールが存在します。

例えば、あるタスクに「2023年10月1日以降に開始」という制約(Start No Earlier Than)がついてしまったとしましょう。たとえ前工程が早く終わって、スケジュールを前倒ししようとしても、この「制約」という壁がエンジンの計算をブロックしてしまいます。

プロジェクト作成時、ユーザーがうっかり日付を直接入力したりすると、MS Projectは気を利かせて(あるいは余計なお世話で)、自動的にこの「制約」を付与してしまうことがあります。

「制約だらけのスケジュールは、硬直したスケジュールである」

これがエンジニアとしての格言です。柔軟で、変化に強いプロジェクトを作るためには、VBAを使ってこれらの制約を検出し、本来あるべき「制約なし(As Soon As Possible)」の状態へリセットする技術が必要なのです。

2. 核心となる概念:TaskオブジェクトとConstraintType

コードを書く前に、私たちが操作する「対象」の正体を理解しましょう。

Taskオブジェクト

プロジェクト内の各行(タスク)は、すべて`Task`というオブジェクトとして管理されています。

ConstraintType(制約の種類)

タスクがどのようなルールに従っているかは、`ConstraintType`というプロパティで決まります。MS Project VBAでは、これらは「列挙型(Enum)」という特別な名前で定義されています。

よく使うのは以下のものです:

  • `pjTaskConstraintAsSoonAsPossible`:「可能な限り早く」(制約なしの状態。これが理想!)
  • `pjTaskConstraintStartNoEarlierThan`:「〜以降に開始」(日付を入力した時に付与されやすい制約)
  • `pjTaskConstraintMustStartOn`:「〜に開始」(日付を固定してしまった状態)

3. 実践:制約を判定してリセットするコード

それでは、実際に「制約が設定されているタスクを見つけ出し、それを『可能な限り早く』に書き換える」コードを見てみましょう。

初心者の方が最も躓きやすい「エラーの罠」を回避する書き方を盛り込んでいます。

Option Explicit

''' <summary>
''' プロジェクト内の全タスクをスキャンし、
''' 「〜以降に開始」等の制約が付いているタスクを
''' 「可能な限り早く(制約なし)」へ自動的に修正する。
''' </summary>
Sub ResetTaskConstraintsToASAP()
    Dim t As Task
    Dim count As Integer
    count = 0

    ' 1. プロジェクト内のすべてのタスクをループ処理する
    ' ActiveProject.Tasks は、プロジェクトに含まれるすべてのタスクの集合体です
    For Each t In ActiveProject.Tasks
        
        ' 【重要:プロの知恵】
        ' MS Projectのタスクコレクションには、空白の行(Nothing)が含まれることがあります。
        ' Nothingに対してプロパティを参照しようとすると、実行時エラーでプログラムが停止します。
        ' 必ず「t が Nothing ではないこと」を確認してから処理を行います。
        If Not t Is Nothing Then
            
            ' 2. タスクに「開始日以降(Start No Earlier Than)」の制約がかかっているか判定
            ' ここでは、意図せず日付固定されてしまったタスクをターゲットにします
            If t.ConstraintType = pjTaskConstraintStartNoEarlierThan Or _
               t.ConstraintType = pjTaskConstraintMustStartOn Then
                
                ' 3. 制約を「可能な限り早く(As Soon As Possible)」に書き換える
                ' これにより、タスクは依存関係に基づいた自由な計算が可能になります
                t.ConstraintType = pjTaskConstraintAsSoonAsPossible
                
                ' 修正した数をカウント(後で報告するため)
                count = count + 1
                
                ' デバッグ用:イミディエイトウィンドウにどのタスクを直したか表示
                Debug.Print "修正完了: " & t.Name
            End If
            
        End If
    Next t

    ' 4. 結果をユーザーに通知
    MsgBox count & " 個のタスクの制約を解除し、柔軟なスケジュール状態に設定しました。", vbInformation, "処理完了"
End Sub

4. ここが重要!陥りやすい「3つの罠」と回避策

このコードを理解する上で、絶対に外してはいけないポイントを解説します。

① 「Nothing」の罠(オブジェクトのライフサイクル)

マクロの記録では見えにくい部分ですが、MS Projectのタスク一覧には、ユーザーが何も入力していない「空の行」が存在します。
`For Each t In ActiveProject.Tasks` でループを回すと、プログラムはこの「空の行」にもアクセスしようとします。しかし、空の行には「制約(ConstraintType)」という概念が存在しません。存在しないものに質問を投げれば、プログラムは「そんなものはない!」と怒って止まってしまいます(Runtime Error 91)。

回避策: `If Not t Is Nothing Then` という一文を入れる。これが「オブジェクトが存在するかどうか」を確認する、プロの防衛策です。

② 「数値」ではなく「名前(Enum)」で書く

「制約タイプは 1 が『開始以降』で、0 が『可能な限り早く』だ」と、数字でコードを書く人がいます。
これは絶対にやめてください。なぜなら、半年後の自分や、他のエンジニアがそのコードを見たとき、その数字が何を意味するのか分からなくなるからです。
`pjTaskConstraintAsSoonAsPossible` のように、意味のある名前(列挙型)を使うことで、コードは「仕様書」としての価値を持ちます。

③ 「計算エンジン」への敬意

制約を解除した直後は、プロジェクト全体のスケジュールがガクンと動くことがあります。これはバグではなく、エンジンが本来の力を発揮して、最適な計算を行った結果です。
制約を消すことは、スケジュールを「壊す」ことではなく、スケジュールを「解放する」ことだと理解してください。

5. まとめ:次の一歩へ

お疲れ様でした。今日あなたは、単にタスクを操作するだけでなく、「プロジェクトの計算ロジックそのものを制御する」という、一段高い視点を得ました。

「制約を判定し、適切なデフォルト値へ置換する」というロジックは、あらゆる業務自動化の基礎となる「判定(If)と反復(Loop)」の組み合わせです。

ここをクリアすれば、次は「特定の期間内にあるタスクだけを抽出する」や「リソースの負荷が高いタスクだけを特定する」といった、より高度な自動化へと進むことができます。

一歩ずつ、着実に。
MS Projectの深淵なる世界を楽しんでください。応援していますよ。

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