こんにちは!現場でバリバリVBAを書いていると、どうしてもぶ壁にぶつかる瞬間がありますよね。「数千行もある巨大なタスクリストをマクロで一気に処理したら、画面がカチコチに固まって、終わる頃にはコーヒーが冷めきっていた……」なんて経験、ありませんか?
マクロの記録から一歩抜け出して、本格的な自動化に挑むあなたへ。今日は、大規模プロジェクトのWBS(タスクの階層構造や前提条件)を操作する際、実行時間を数分から数秒に縮める「極限の高速化テクニック」を伝授します。
ここをクリアすれば、Project VBAの基本はもちろん、プロとしてのパフォーマンスチューニングの極意までバッチリ身につきますよ。それでは、優しく、そして深く、その扉を開いていきましょう。
—
1. なぜ巨大なタスク操作は「爆発的に遅くなる」のか?
Excel VBAでも同じことが言えますが、Microsoft Project(MSP)は特に「データ構造の連鎖」が重いアプリケーションです。
数千行のタスクに対して、VBAで1行ずつ以下のような操作を行っていないでしょうか?
- タスクを追加する
- 前提条件(リンク)を結ぶ
- インデント(階層化)を変更する
MSPは、これら一つの操作が行われるたびに、親切心から「全体のスケジュール再計算(スケジュールエンジン)」と「画面の再描画(UIの更新)」を裏で自動実行します。
つまり、3,000行のタスクがあれば、3,000回も全計算と画面描画を繰り返しているわけです。そりゃあパソコンも音を上げますよね。
—
2. 高速化の二大巨頭:「計算モード制御」と「画面更新停止」
この無駄な裏方仕事をピタッと止めるのが、今回マスターする二大技術です。
1. 計算モードを手動にする (`Calculation` / `Manual`):
タスクをいじり倒している間はスケジュールの再計算を一切させず、すべての処理が終わった最後に「ドーン!」と一括計算させます。
2. 画面描画を止める (`ScreenUpdating`):
人間には見えない高速な変更のたびに画面を書き換えるのをやめさせ、PCの処理能力を純粋なデータ処理に全振りさせます。
それでは、実際のコードを見てみましょう。ここが今日のハイライトです。
—
3. 【実践】数分を数秒に変える!高速化テンプレートコード
以下のコードは、大規模なタスク追加や依存関係の設定を行う際の「黄金の骨組み(デザインパターン)」です。開発現場でそのままコピペして使えます。
Sub OptimizeTaskCreationDemo()
Dim startTime As Double
startTime = Timer ‘ 実行時間計測用
‘ ==========================================
‘ 【極意1】環境設定の退避 & 爆速モードへの切り替え
‘ ==========================================
Dim originalCalc As Long
originalCalc = Application.Calculation
‘ 計算モードを「手動(Manual)」に変更し、裏での自動再計算を完全にストップ
Application.Calculation = pjCalculationManual
‘ 画面描画を停止し、UIの更新コストをゼロにする
AppCacheScreenUpdating False
On Error GoTo ErrorHandler ‘ エラー時に設定が戻らなくなるのを防ぐおまじない
‘ ==========================================
‘ 【メイン処理】ここに重いタスク操作を書く
‘ ==========================================
Dim i As Long
Dim t As Task
Sub “処理を開始します…”
‘ 例:3000行のタスクを連続作成するシミュレーション
For i = 1 to 3000
‘ TaskCollectionに対して高速にタスクを追加
Set t = ActiveProject.Tasks.Add(“タスク & ” & i)
‘ 期間を設定(この時点ではスケジュールは再計算されません)
t.Duration = “8h”
Next i
‘ ==========================================
‘ 【極意2】処理完了後の「一度だけの」全体計算
‘ ==========================================
‘ 計算モードを戻すと同時に、MSPが全体を最適化して一気に再計算する
Application.Calculation = pjCalculationAutomatic
‘ 画面描画を復元
AppCacheScreenUpdating True
‘ 終了メッセージと計測結果の表示
MsgBox “処理が完了しました! 実行時間: ” & Format(Timer – startTime, “0.00”) & ” 秒”, vbInformation
Exit Sub
ErrorHandler:
‘ ==========================================
‘ 【安全装置】エラーハンドリング
‘ ==========================================
‘ 万が一マクロが途中でエラー落ちしても、設定が元の状態に戻るようにする
Application.Calculation = originalCalc
AppCacheScreenUpdating True
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
End Sub
‘ 画面更新を安全に切り替えるためのヘルパープロシージャ
Private Sub AppCacheScreenUpdating(ByVal state As Boolean)
On Error Resume Next
Application.ScreenUpdating = state
On Error GoTo 0
End Sub
—
4. コードの深掘り解説:なぜこれほど速くなるのか?
初学者の方がつまずきやすいポイントをいくつか解説しますね。
① `Application.Calculation` の正体
Projectには、計算方法を自動(Automatic)にするか手動(Manual)にするかのグローバル設定があります。これを `pjCalculationManual` にすることで、タスクを追加・削除してもWBSの「前提条件のズレ」や「クリティカルパスの再計算」が一切行われなくなります。
「とりあえず散らかすだけ散らかして、最後に片付けをさせる」というイメージです。
② エラーハンドリング(安全装置)の重要性
プログラミング初学者がやりがちなミスが、「画面を止めたままエラーでマクロが強制終了し、Projectの画面が二度と動かなくなる(または計算しなくなる)」という現象です。
必ず `On Error GoTo ErrorHandler` を仕込み、どんな結末を迎えても元の設定(計算モードと画面描画)に復元するコードをセットで書きましょう。これがプロの作法です。
—
5. 陥りやすい罠とエラー回避のコツ
大規模プロジェクトを扱う際、上記の高速化コードを使ってもなおハマりがちな「罠」がいくつかあります。
- 罠1: ループ内で `ActiveProject.Update工地` などを呼び出していないか?
高速化モードにしていても、ループの中でうっかりプロジェクト全体を強制計算させるようなメソッドを叩いてしまうと、効果が台無しになります。処理は「溜めて、最後にドン」が鉄則です。
- 罠2: タスクID(ID)とユニークID(UniqueID)の混同
数千行のタスク間で前提条件(リンク)を組むとき、並び替えが発生すると `Task.ID`(上から何番目か)は簡単にズレます。依存関係をプログラムで組む際は、絶対に変動しない `Task.UniqueID` をキーにして操作するようにしてください。
—
おわりに:ここをクリアすれば、あなたはもう中級者!
いかがでしたか?
「画面更新停止」と「計算モード制御」は、Project VBAのパフォーマンスを語る上で避けて通れない、いわば登竜門です。
この二つを正しく理解し、自分のコードに組み込めるようになったあなたは、もう「マクロの記録をポチポチ押すだけの人」ではありません。大規模なプロジェクトデータを自在に操る、立派な業務自動化エンジニアです。
ぜひ次の開発案件でこのテクニックを試して、圧倒的なスピードの差を体感してみてくださいね。それでは、また次回の極限の知見でお会いしましょう!
