【入門編】制約条件の「強制解除」によるスケジュール最適化:VBAを用いたボトルネック解消 – Project VBA解析バイブル

スポンサーリンク

こんにちは!Project VBAの世界へようこそ。
マクロの記録から一歩踏み出し、「自分の手でプロジェクトを自在にコントロールしたい」と願うあなたへ、今日はとてもエキサイティングなテーマをお届けします。

テーマはずばり、「制約条件の『強制解除』によるスケジュール最適化:VBAを用いたボトルネック解消」です。

「スケジュールを短縮したいのに、なぜかガチガチに組まれた制約(ASAPやALAP、特定の日付指定など)が邪魔をして進まない……」
そんな現場の絶望感を、VBAの力で鮮やかにハックし、工期短縮のシミュレーションを自動化する方法を一緒に見ていきましょう。

ここをクリアすれば、あなたも単なる「操作する人」から「プロジェクトの構造を操るエンジニア」へと生まれ変わります。さあ、深呼吸して、最高のコードの旅を始めましょう!

—

1. なぜ「制約条件」がプロジェクトのボトルネックになるのか?

MS Projectを実務で使っていると、こんな壁にぶつかりませんか?

  • 「このタスク、本当は前倒しできるはずなのに、『できる限り遅く(ALAP)』が入っていてスケジュールが後ろに張り付いている……」
  • 「進捗遅れを取り戻したいのに、無数の『指定日以降に開始(SNET)』が足かせになって、全体が短縮できない……」

一つひとつ手作業でタスクのプロパティを開き、制約の種類を「可能な限り早く(ASAP)」に変更して……なんて作業、タスクが数百件あったら日が暮れてしまいますよね。

ここで登場するのが Project VBA(Visual Basic for Applications) です。
VBAを使えば、プログラムの高速な演算処理によって「どの制約が全体の工期を引っ張っているのか(ボトルネック)」を瞬時に見つけ出し、必要に応じて自動で制約を緩める(あるいは解除する)シミュレーションをノンストップで実行できます。

—

2. Project VBAの基本:オブジェクトの階層構造を掴む

Excel VBAとMS Project VBAの最大の違い、それは「時間軸と依存関係(ネットワーク)」を扱うかどうかです。

MS ProjectのVBAでは、次のような階層構造を意識する必要があります。

Application (MS Project本体)
┗ ActiveProject (現在開いているプロジェクト)
┗ Tasks (タスクの集合体)
┗ Task (個々のタスク)
┣ .ConstraintType (制約の種類)
┣ .ConstraintDate (制約の日付)
┗ .Start / .Finish (開始日・終了日)

Excelのように「セル(i, j)の値を取る」のとは違い、タスクには「他のタスクとの繋がり(先行・後続)」や「制約条件」という命が吹き込まれています。ここをプログラムから操作するのが、Project VBAの醍醐味です。

—

3. 実装:ボトルネックとなっている制約を自動解除するシミュレーションツールのコード

お待たせしました! 現場でそのままコピペして使える、実用的なVBAコードをプレゼントします。

このコードは、「プロジェクト全体の終了日を遅らせている元凶(今回は例として『指定日以降に開始(SNET: Start No Earlier Than)』などの硬い制約)を検出し、一時的に『可能な限り早く(ASAP)』に書き換えて工期がどれくらい短縮できるかをシミュレーションする」ものです。

Sub SimulateConstraintRelaxation()
‘ =====================================================================
‘ テーマ: 制約条件の強制解除によるスケジュール最適化シミュレーション
‘ 開発者ノート: 変更前の状態を退避できるよう、実行前にプロジェクトの
‘ バックアップをとることを強く推奨します。
‘ =====================================================================

Dim t As Task
Dim modifiedCount As Long
Dim originalFinish As Date
Dim newFinish As Date

‘ エラーハンドリングの基本
On Error GoTo ErrorHandler

‘ 1. 最適化前のプロジェクト全体終了日を記録
originalFinish = ActiveProject.ProjectFinish
modifiedCount = 0

‘ 画面描画を停止してマクロの実行速度を爆発的に上げる(お作法です!)
Application.ScreenUpdating = False

MsgBox “シミュレーションを開始します。” & vbCrLf & _
“現在のプロジェクト完了日: ” & originalFinish, vbInformation, “開始”

‘ 2. プロジェクト内の全タスクをループ処理
For Each t In ActiveProject.Tasks
‘ タスクが有効(サマリータスクや削除済みではない)かチェック
If Not t Is Nothing Then
If Not t.Summary Then ‘ サマリータスク以外を対象にする

‘ 例として、「指定日以降に開始(pjConstraintStartNoEarlierThan)」等の
‘ スケジュールを縛る制約が入っているかをチェック
If t.ConstraintType = pjConstraintStartNoEarlierThan Or _
t.ConstraintType.ConstraintType = pjConstraintMustStartOn Then

‘ 【ボトルネックの緩和】
‘ 制約を最も柔軟な「可能な限り早く (ASAP)」に変更する
t.ConstraintType = pjConstraintAsSoonAsPossible

‘ 変更したタスクの数をカウント
modifiedCount = modifiedCount + 1

‘ デバッグウィンドウにどのタスクを緩和したかを出力
Debug.Print “緩和タスク: ID=” & t.ID & ” / 名称=” & t.Name
End If

End If
End If
Next t

‘ 3. スケジュールの再計算を強制実行
CalculateAll

‘ 4. 最適化後のプロジェクト全体終了日を取得
newFinish = ActiveProject.ProjectFinish

‘ 画面描画を再開
Application.ScreenUpdating = True

‘ 5. 結果発表!
MsgBox “シミュレーションが完了しました!” & vbCrLf & _
“———————————-” & vbCrLf & _
“緩和した制約の数: ” & modifiedCount & ” 件” & vbCrLf & _
“変更前の完了日: ” & originalFinish & vbCrLf & _
“変更後の完了日: ” & newFinish & vbCrLf & _
“———————————-” & vbCrLf & _
“工期短縮効果を確認してください。”, vbInformation, “最適化完了”

Exit Sub

ErrorHandler:
‘ 万が一エラーが起きた時も画面描画のロックは必ず解除する
Application.ScreenUpdating = True
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical, “予期せぬエラー”
End Sub

—

4. コードのポイントと、初心者が陥りやすい罠(エラー対策)

このコードには、現場で生き残るための知恵がいくつか詰まっています。ポイントを優しく解説しますね。

① `Application.ScreenUpdating = False` の魔法

タスクの数が多いプロジェクト(数千行レベル)で、一つひとつタスクのプロパティをいじると、MS Projectは毎回ガリガリと画面を再描画しようとして激重になります。
処理の最初に `False` にし、最後に `True` に戻す。これだけで実行速度が何倍にも跳ね上がります。これはプロのエンジニアなら必ず入れる定石です。

② `Not t Is Nothing` というお作法

VBAで `For Each t In ActiveProject.Tasks` を回すとき、タスクが途中で削除されていたり空行だったりすると、`t` が「中身のない空っぽ(Nothing)」の状態になることがあります。
これをチェックせずに `t.Name` などを呼び出すと、容赦なく「オブジェクト変数が設定されていません」というお馴染みのエラーに撃墜されます。このガード節は絶対に忘れないようにしましょう。

③ サマリータスク(親タスク)への配慮

MS Projectでは、親タスク(サマリータスク)の日付や制約は、基本的に子タスクの集計値によって自動的に決まります。親タスクに対して無理やり制約を書き換えようとするとエラーの原因になるため、`If Not t.Summary Then` でしっかりと除外しています。

—

5. まとめ:ここをクリアすれば、Project VBAの基本はバッチリです!

お疲れ様でした!今回は「制約条件の強制解除によるボトルネック解消」という、一歩進んだ実用的なテーマを通じて、Project VBAの心臓部を覗いてみました。

  • オブジェクトの階層構造を意識すること
  • 画面描画の制御(ScreenUpdating)でパフォーマンスを最適化すること
  • サマリータスクやNullチェックなどの現場特有のトラップを回避すること

ここをしっかりと押さえたあなたなら、もう「マクロの記録をポチポチ押すだけの人」ではありません。プロジェクトの複雑な制約を自分の意のままに操り、現場を救う自動化エンジニアの第一歩を踏み出しています。

「ここをもっとこうしたい」「こんなカスタムフィールドと連携させたい」といった疑問が出てきたら、いつでも先輩エンジニアに聞いてくださいね。あなたのVBAライフを、心から応援しています!

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