こんにちは!先輩エンジニアのボクです。
普段、MS Projectの巨大なスケジュールを相手にしていて、「なんだかマクロの動きがやたらと遅いな……」とイライラした経験はありませんか?
「1件タスクのプロパティを書き換えるたびに、画面がチラついて砂時計がクルクル……」
もしそんなコードを書いているとしたら、ちょっともったいないことをしています。
MS Projectのオブジェクトモデル(`Project`, `Task`, `Resource`)は非常にリッチで便利な反面、GUIや背後にあるデータベースと密結合しているため、ワークシート上のセルを1つずつ叩くように、タスクを直接ガリガリ操作すると猛烈に遅くなります。
そこで今回は、プログラミング初学者や「マクロの記録」から一歩抜け出したいあなたへ向けて、「一度メモリ上のCollectionにタスク情報を吸い上げ、超高速で処理した後に、一括してプロジェクトへ書き戻す」という、上級者お墨付きのテクニックを伝授します。
ここをクリアすれば、あなたのProject VBAのスキルは一気にプロの領域へ到達します。さあ、一緒に扉を開けていきましょう!
—
1. なぜ「直接操作」は遅いのか?(オブジェクトモデルの裏側)
MS Projectを開いているとき、画面に表示されているタスクやリソースは、単なるメモリ上のデータではありません。画面の再描画(UIの更新)、依存関係の整合性チェック、スケジュール計算エンジンなどが、あなたがVBAで`.Name`や`.Start`を1回変更するたびに裏でフル稼働しています。
例えば、1,000件のタスクの名称を一斉に変えようとして、ループの中で直接 `Task.Name = …` とやると、1,000回もスケジュール計算と画面描画が走ることになります。これが「遅さ」の正体です。
解決策:メモリ内ワーキング(Collectionの活用)
この問題を解決するアプローチはシンプルです。
1. 【読込】 プロジェクトから必要なタスクのデータを一度だけ読み取り、VBAの標準機能である `Collection`(または独自クラス)に格納する。
2. 【処理】 メモリ上のデータだけで高速に加工・計算を行う(この間、Projectのエンジンは一切邪魔をしません)。
3. 【書込】 処理が終わったデータを、一気にProjectへ書き戻す。
この「メモリ内高速処理」の構造を、実際のコードで見ていきましょう。
—
2. 実践!タスク情報をメモリ内で爆速処理するVBAコード
以下のコードは、アクティブなプロジェクトにあるすべてのタスクの名前の頭に、特定のプレフィックス(接頭辞)を爆速で付与するサンプルです。
開発環境(VBE)の標準モジュールに貼り付けて、そのまま現場で試してみてください。
‘ ==============================================================================
‘ テーマ:Collectionオブジェクトを用いたタスク情報のメモリ内高速処理
‘ 概要 :Projectオブジェクトへの頻繁なアクセスを避け、メモリ上で完結させる
‘ ==============================================================================
Sub FastTaskProcessingSample()
Dim tsk As Task
Dim colTasks As Collection
Dim myTaskInfo As TaskInfoDTO ‘ データを格納する自作UDT(構造体)
‘ 画面描画と自動計算をストップし、さらにパフォーマンスを極限まで引き上げる
Application.ScreenUpdating = False
Application.Calculation = pjCalculationManual
On Error GoTo ErrorHandler
‘ —————————————————-
S
