Project VBAを掌握せよ:数千件の「カレンダー例外」を瞬時に叩き込む極限の最適化術
こんにちは。Project VBAの世界へようこそ。
「プロジェクトの稼働日を設定しようと、マクロを回したら画面がフリーズした…」
「数百人のリソースに休日を適用するのに、コーヒーを飲んで戻ってきても終わらない…」
そんな経験はありませんか? もしあなたが、`For Each`ループの中で無邪気に`Add`メソッドを呼び出し、PCのファンを唸らせているなら――今日でその非効率な習慣とは決別しましょう。
今日は、Project VBAの心臓部である「リソースカレンダー」を、プロのエンジニアがどう扱っているのか。その真髄を伝授します。
—
1. なぜ「ループ処理」がボトルネックになるのか?
初学者が陥る最大の罠は、「オブジェクトの生成コスト」を軽視することです。
Project VBAにおいて、リソースのカレンダーに例外(休日など)を追加する際、個別に`Exceptions.Add`を呼び出すと、プロジェクト・ファイルは毎回「再計算」や「整合性チェック」を内部的に走らせます。1件なら0.01秒でも、1,000件あれば? 数分待たされるのは当然の結果なのです。
極限の最適化の鍵は、「処理の最小化」と「オブジェクトへの直接アクセス」にあります。
—
2. 実践:ExcelからProjectへの高速一括適用コード
今回は、ExcelのA列に並んだ「休日リスト」を、Projectの全リソースに一括適用するコードを紹介します。
Sub ApplyHolidaysToResources_Fast()
Dim projApp As Object
Dim res As Resource
Dim xlApp As Object
Dim ws As Worksheet
Dim holidayRange As Range
Dim cell As Range
‘ プロジェクトへの接続(自身で実行する場合はActiveProjectでOK)
Set projApp = Application
‘ Excel側の休日リストを参照(外部ブックの場合の想定)
Set ws = ThisWorkbook.Sheets(“HolidayList”)
Set holidayRange = ws.Range(“A2:A” & ws.Cells(ws.Rows.Count, 1).End(xlUp).Row)
‘ 【重要】画面更新を停止し、再計算を抑制する
‘ これだけで速度が劇的に変わります
projApp.ScreenUpdating = False
‘ 全リソースに対してループ
For Each res In ActiveProject.Resources
If Not res Is Nothing Then
‘ リソースごとに例外を追加
For Each cell In holidayRange
‘ 開始日と終了日が同じなら「1日だけの例外」として登録
‘ エラーハンドリング:既に同じ日が登録されている場合の重複エラーを回避
On Error Resume Next
res.Calendar.Exceptions.Add Type:=pjDayTypeWorking, _
Start:=cell.Value, _
Finish:=cell.Value
On Error GoTo 0
Next cell
End If
Next res
projApp.ScreenUpdating = True
MsgBox “全リソースへの休日適用が完了しました!”, vbInformation
End Sub
このコードの「極意」
1. `ScreenUpdating = False`: 画面の描画を止めることで、UI更新のオーバーヘッドをゼロにします。
2. `On Error Resume Next`: Projectの仕様上、既に登録されている例外を追加しようとするとエラーが発生します。これをスキップさせることで、処理を止めずに全適用を完遂させます。
3. オブジェクトの直接指定: `res.Calendar`へ直接アクセスすることで、不必要なクエリを避けています。
—
3. さらに上を目指す「アーキテクト」へのアドバイス
上記のコードで十分高速ですが、もし対象が「数万人規模のリソース」であれば、次のステップを検討してください。
- ベースカレンダーの活用: 全リソースに個別の例外を登録するのではなく、「ベースカレンダー」に休日を設定し、各リソースがそのカレンダーを参照するように設計します。これがProjectの構造設計における「ベストプラクティス」です。
- 例外処理のバッチ化: もし可能であれば、日付が連続している場合は`Start`と`Finish`をまとめて登録してください。`1/1, 1/2, 1/3`と別々に登録するより、`Start:=1/1, Finish:=1/3`とする方が、内部のデータ構造が圧倒的に軽くなります。
—
最後に:VBAは「道具」ではなく「思考」である
Project VBAを扱うことは、単に自動化することではありません。「プロジェクトの時間の流れを、コードで制御する」ということです。
最初は難しく感じるかもしれませんが、オブジェクトがどう動いているのか、どの処理に負荷がかかっているのかを想像できるようになれば、あなたはもうただの初心者ではありません。
ここをクリアすれば、Project VBAの基本はバッチリです。自信を持って、次の自動化へ進んでください。あなたのプロジェクトが、より効率的で、よりクリエイティブなものになることを心から応援しています!
何か詰まったら、いつでもまた聞きに来てくださいね。
