【入門編】【上級プロ】Projectの「計算エンジン」をVBAで一時停止・再開する際の整合性維持テクニック – Project VBA解析バイブル

スポンサーリンク

こんにちは!プロジェクト管理の現場で日々奮闘されている皆さん、お疲れ様です。
マクロの記録から一歩抜け出し、「いざ本格的なMS Projectの自動化に挑もう!」と意気込んだものの、なぜかコードが重かったり、予期せぬスケジュール崩壊を起こして頭を抱えたりしていませんか?

今回は、MS Project VBAの真髄であり、大規模プロジェクトを爆速かつ安全にコントロールするための最重要テクニック「計算エンジンの制御と整合性維持」について、徹底的に解説していきます。

ここをクリアすれば、あなたも単なる「VBAの利用者」から、アーキテクトの領域へとステップアップできますよ。それでは、一緒に紐解いていきましょう!

1. なぜMS ProjectのVBAは「重い」のか?(計算エンジンの正体)

Excel VBAを使っている感覚でMS Projectのコードを書くと、大抵痛い目に遭います。その元凶が 「計算エンジン(Calculation Engine)」 です。

MS Projectを開き、一つのタスクの日付を変えた瞬間を思い浮かべてみてください。
先行タスクの変更に伴い、後続タスクの開始日、サマリータスク(親タスク)の期間、リソースの割り当て状況、クリティカルパスに至るまで、ドミノ倒しのようにプロジェクト全体が再計算されますよね。

[タスクAの日付変更]
↓ (一瞬で連鎖)
[タスクB・Cの再計算] → [サマリーの更新] → [リソース過負荷チェック] → [クリティカルパス再描画]

VBAでループを回して100個のタスクの数値を書き換えるコードを書いた場合、「1回書き換えるごとに、この重厚な再計算が100回走る」ことになります。これが、マクロが途中でフリーズしたかのように遅くなる真の理由です。

2. 計算エンジンの停止(`Application.Calculation = False`)の罠

「じゃあ、書き換える前に計算を止めればいいんでしょ?」
その通り! `Application.Calculation = False` を使えば、VBA実行中の自動計算をストップし、爆速で処理を完了させることができます。ここまでは初級〜中級のテクニックです。

しかし、ここからが上級者の領域。
計算を止めている間、プロジェクト内のデータは「意図的な不整合状態」にあります。

この状態で、依存関係(リンク)を持つタスクのデータを誤った順序で操作したり、計算を再開させるタイミングを誤ったりすると、以下のような恐ろしい現象が発生します。

  • スケジュール崩壊: 辻褄の合わない日付が固定化され、後から直そうにも直せないゾンビタスクが生まれる。
  • リンク切れ・矛盾: 先行・後続の制約条件が壊れ、Projectが強制終了するか、ファイルが破損する。

3. 【実践】整合性を完全担保するセキュア・アップデート・パターン

計算エンジンを一時停止し、安全に一括更新を行うための「黄金手順」は以下の3ステップです。

1. 計算モードの手動化(Manual)への切り替え
2. データの安全な一括書き換え(影響の少ない順・またはIDベース)
3. 計算の強制実行(`Calculate`)と、自動計算モードの復元

実際の現場でそのままコピペして使える、堅牢なテンプレートコードを用意しました。コメントを頼りに構造を読み解いてみてください。

Sub SecureTaskUpdatePattern()
Dim t As Task
Dim originalCalc As Long

‘ 0. 現在の計算モードを退避(後で必ず元に戻すため)
originalCalc = Application.Calculation

On Error GoTo ErrorHandler ‘ 予期せぬエラーでも計算モードがOFFのままにならないようにする

‘ 1. 計算エンジンを一時停止(Manualモードに設定)
‘ ※注意: Projectの Calculation プロパティは pjCalculationManual(0) または pjCalculationAutomatic(1) を取ります
Application.Calculation = pjCalculationManual

‘ 画面描画も止めると、さらにスピードが跳ね上がります
AppActivate ActiveProject.Name

‘ 2. 大量のタスクデータを一括操作
‘ ここでは例として、すべてのタスクに独自のテキストを流し込み、期間を調整します
For Each t In ActiveProject.Tasks
If Not t Is Nothing Then
‘ サマリータスク以外を対象にするなどのガードを入れるとより安全
If Not t.Summary Then
t.Text1 = “一括更新済み”
‘ 期間を変更(例: すべてのタスクを3日に設定)
t.Duration = “3d”
End If
End If
Next t

‘ 3. 【最重要】計算を再開する前に、プロジェクト全体の整合性を強制的に再計算させる
‘ これにより、止めていた間にバラバラになったパズルのピースが正しく組み合わされます
Application.Calculate

‘ 4. 計算モードを元の状態(通常は自動)に戻す
Application.Calculation = originalCalc

MsgBox “プロジェクトの整合性を維持したまま、一括更新が完了しました!”, vbInformation
Exit Sub

ErrorHandler:
‘ エラーハンドリング:万が一マクロがクラッシュしても、計算モードを元に戻してデータ破損を防ぐ
Application.Calculation = originalCalc
MsgBox “エラーが発生しました。安全のため計算モードを復元しました。” & vbCrLf & _
“エラー内容: ” & Err.Description, vbCritical
End Sub

4. プロが教える「絶対に守るべき鉄則」

上記のコードを見て、「おっ、これなら完璧だな」と思ったあなた。さらに現場で生き抜くための実践的な知見をいくつか授けましょう。

鉄則①:エラーハンドリング(`On Error GoTo`)は絶対に省くな!

計算を止めている最中にVBAがエラーで強制終了すると、MS Projectは「計算がされない危険な状態」のまま放置されます。ユーザーがそれに気づかず上書き保存してしまうと、プロジェクトファイルが再起不能になることがあります。
必ずエラー時にも元の計算モードに戻す保険(ファイアウォール)を組み込んでください。

鉄則②:制約条件(Constraint Type)との戦い

タスクに「2023/10/01以降に開始」といった強い制約(`pjConstraintStartNoEarlierThan`など)がかかっている場合、計算エンジンを再開した際に、VBAで書き換えた期間と衝突してエラーアラップ(ロジックの矛盾)が発生することがあります。
日付や期間を操作するマクロを書くときは、事前にタスクの制約条件が「できるだけ早く(As Soon As Possible)」になっているかを確認・制御するロジックを挟むのがプロの技です。

ここをクリアすれば、Project VBAの基本はバッチリですよ!

お疲れ様でした!今回は少しアグレッシブな、裏側の仕組みに踏み込んだ内容をお届けしました。

「計算エンジンを止める」というアプローチは、諸刃の剣です。しかし、その裏にある「データの不整合を防ぐための手順(Calculateの挟み込みとエラー対策)」さえしっかりと押さえておけば、どんなに巨大なWBS(数千行規模のスケジュール)であっても、一瞬で、かつ安全にコントロールできるようになります。

この知見をあなたの武器に組み込んで、ぜひスマートな自動化ライフを実現してください。
それでは、次回の応用編でお会いしましょう!

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