数万行のプロジェクトを数秒で支配する。Project VBA「計算エンジン制御」の極意
こんにちは。プロジェクト管理の自動化、その深淵へようこそ。
「マクロの記録」を使って、小さなタスクの期間を変えたり、制約条件をいじったりすることには慣れてきましたか? それができれば、あなたはすでに自動化の入り口に立っています。素晴らしい一歩です。
しかし、いざ実務で「数千、数万行に及ぶ大規模なプロジェクトファイル」を相手にしたとき、ある壁にぶち当たることがあります。
「マクロを実行した瞬間、ExcelやProjectが『応答なし』になり、数分間そのまま動かなくなった……」
「計算が終わるまで、まるで時間が止まったかのように感じられる……」
もしあなたが今、この壁に直面しているなら、おめでとうございます。あなたは「計算エンジンのライフサイクル」という、プロフェッショナルへの登竜門に到達したのです。
今日は、大規模データを扱うプロが必ず使う、計算エンジンの負荷を劇的に抑えるテクニックを伝授します。ここをクリアすれば、あなたの書くコードは「動くツール」から「プロの武器」へと進化します。
なぜ、あなたのマクロは遅いのか?
MS Projectは、非常に「気が利く」ソフトウェアです。
タスクの開始日を1日ずらした瞬間、それに関連する後続タスク、リソースの負荷、クリティカルパス……それらすべてを瞬時に再計算しようとします。
これが、マクロを実行している最中に起こるとどうなるでしょうか?
1. VBAが「タスクAの制約を『ASAP』に変更」と命令する。
2. Projectが「了解! プロジェクト全体を再計算します!」と動き出す。
3. VBAが「次はタスクBを……」と命令する。
4. Projectが「また再計算します!」と動き出す。
……これを数千回繰り返しているのです。
「1行書き換えるたびに、プロジェクト全体の全計算をやり直している」。これが、処理が重くなる真犯人です。
解決策:計算エンジンを「一時停止」させる
プロのエンジニアは、作業中に何度も「再計算」をさせたりはしません。
「一括でデータを書き換える間は、計算を止めておけ。最後に一度だけ、まとめて計算しろ」と命令するのです。
ここで登場するのが、`Calculation` オブジェクトの `ManualCalculation`(手動計算モード) です。
制御の3ステップ
1. 自動計算モードを「手動」に切り替える(エンジンの停止)
2. 大量のデータ更新処理を行う(高速な書き換え)
3. 計算モードを「自動」に戻し、一度だけ再計算させる(結果の反映)
実戦コード:大規模データ更新の黄金パターン
では、実際にどのように書くのか。
単にモードを切り替えるだけでは不十分です。もし、書き換えの途中でエラーが起きたらどうなるでしょうか? 計算モードが「手動」のまま止まってしまい、ユーザーは「Projectが壊れた!」とパニックになります。
プロは必ず「エラーハンドリング(例外処理)」を組み込みます。
Sub UpdateLargeProjectConstraints()
' ============================================================
' テーマ:大規模データ更新時の計算エンジン負荷抑制
' 内容:制約条件を一括更新し、計算負荷を最小限に抑える
' ============================================================
Dim t As Task
Dim startTime As Double
' 処理時間を計測するための準備
startTime = Timer
' --- [STEP 1] エラーハンドリングの設定 ---
' エラーが発生した場合は、エラー処理ルーチン(ErrorHandler)へジャンプさせる
On Error GoTo ErrorHandler
' --- [STEP 2] 計算モードを「手動」に切り替え ---
' これにより、タスク更新ごとの再計算が止まり、劇的に高速化します
Application.Calculation = pjManualCalculation
' 画面更新を止めてさらに高速化(おまじないのようなものですが効果的です)
Application.ScreenUpdating = False
Debug.Print "処理を開始します..."
' --- [STEP 3] 大量データの更新ループ ---
' ここでは例として、全てのタスクの制約条件を「ASAP」に変更する処理を行います
For Each t In ActiveProject.Tasks
' 空のタスク(削除済みタスクなど)はスキップ
If Not t Is Nothing Then
' 制約条件を「開始日指定なし(ASAP)」に変更
t.ConstraintType = pjAsapConstraint
' ここで他のプロパティ(期間やリソースなど)を更新しても、
' 計算エンジンは動かないので爆速で処理が進みます
End If
Next t
' --- [STEP 4] 後処理:計算モードを「自動」に戻して再計算 ---
' 全ての書き換えが終わったら、最後に一度だけ「自動」に戻して計算を実行します
Application.Calculation = pjAutomaticCalculation
Application.Calculate ' 明示的に再計算を実行
' 画面更新を元に戻す
Application.ScreenUpdating = True
' 完了報告
MsgBox "更新が完了しました!" & vbCrLf & _
"処理時間: " & Round(Timer - startTime, 2) & " 秒", vbInformation, "成功"
Exit Sub
' --- [STEP 5] エラーハンドリングルーチン ---
ErrorHandler:
' 万が一エラーが起きても、計算モードを「自動」に戻すことを徹底する
' これを忘れると、ユーザーのProjectが「計算されない状態」で放置されてしまいます
Application.Calculation = pjAutomaticCalculation
Application.ScreenUpdating = True
MsgBox "エラーが発生しました。設定を元に戻しました。" & vbCrLf & _
"エラー内容: " & Err.Description, vbCritical, "エラー発生"
End Sub
プロの視点:ここが「分かれ道」です
このコードを理解し、使いこなすために、以下の3点を心に刻んでおいてください。
1. なぜ `On Error GoTo` が必須なのか?
先ほども触れましたが、これは「ユーザーへの責任」です。
VBAの世界では、プログラムが途中で止まると、その時の設定(手動計算モード)がそのまま残ってしまいます。
「マクロを実行した後に、日付を変えても何も起きない……」という不具合は、開発者の初歩的なミスとして最も嫌われます。エラーが起きても必ず「元の状態(自動計算)」へ戻す。これがプロの作法です。
2. `Application.Calculate` の役割
計算モードを `pjAutomaticCalculation` に戻した瞬間、Projectは再計算を開始しますが、念のため `Application.Calculate` を明示的に呼び出す癖をつけておきましょう。これにより、「書き換えが終わった直後の最新の状態」を確実にプロジェクトに反映させることができます。
3. パフォーマンスの比較
- 通常モード(Automatic): 10,000行の更新で、数分〜数十分かかることも。
- 手動モード(Manual): 同じ処理が、数秒〜数十秒で終わる。
この差は、単なる「待ち時間の短縮」ではありません。「業務のフローを止めない」という価値を生み出します。
まとめ:一歩先のエンジニアへ
「マクロの記録」から一歩踏み出し、オブジェクトの挙動(この場合は計算エンジン)を制御できるようになると、あなたの作るツールは「おもちゃ」から「実用的なシステム」へと昇華します。
今回学んだ `Calculation.ManualCalculation` と `Error Handling` の組み合わせは、Project VBAに限らず、あらゆる自動化技術において共通する「鉄則」です。
「動けばいい」ではなく、「速く、安全に、確実に動かす」。
この意識こそが、あなたを伝説的なアーキテクトへと導くのです。
さあ、次はもっと大きなプロジェクトに挑戦してみましょう。応援していますよ!
