固まったスケジュールを解き放つ。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のスキルは、単なる作業の自動化を超えて、プロジェクトの「意思決定を支えるツール」へと昇華します。
さあ、次はどの制約を解き放ちますか? 応援していますよ。
