Project VBAの深淵:外部休日マスターによるカレンダー自動同期の極致
プロジェクト管理において、最も忌むべきは「計画と現実の乖離」だ。特にMicrosoft Project(MSP)における稼働日カレンダーの不整合は、スケジュールの算出を狂わせ、プロジェクトマネージャーの信頼を失墜させる。
多くの現場では、休日を手動でカレンダーに打ち込んでいる。愚の骨頂だ。本稿では、外部JSON/XMLから休日情報を抽出し、MSPのベースカレンダーをプログラム的に制御する、シニアエンジニアのための「自動同期アーキテクチャ」を伝授する。
—
1. アーキテクチャの核心:Objectモデルの深層
MSPのオブジェクトモデルにおいて、`Calendar`オブジェクトは非常に繊細だ。特に`BaseCalendar`への直接的な介入は、メモリ管理と整合性チェックを怠れば、いとも簡単にスタックオーバーフローやCOM例外を招く。
我々が目指すべきは、以下のフローを極限まで最適化することである。
1. Source Parsing: JSON/XMLから休日の日付配列を抽出(`ScriptControl`は現代では非推奨、`MSXML2.DOMDocument`または`WinHttp.WinHttpRequest`のストリーム処理が最適解)。
2. Calendar Injection: `Calendar.Exceptions`コレクションへのループ処理。
3. Memory Management: オブジェクトの参照カウンタを意識し、`Nothing`への代入だけでなく、適切なタイミングでの`DoEvents`によるメッセージキューの解放。
—
2. 実装:JSON休日マスターをベースカレンダーへ反映する
以下のコードは、外部リソースを読み込み、MSPのベースカレンダーを更新するプロセスの核心部分である。
‘ 必要な参照設定: Microsoft Project 16.0 Object Library
‘ 必要に応じて Microsoft XML, v6.0 等を追加すること
Public Sub SyncProjectCalendar(ByVal jsonPath As String)
Dim projApp As MSProject.Application
Dim baseCal As MSProject.Calendar
Dim exps As MSProject.Exceptions
Dim holiday As Variant
‘ プロセス間通信のオーバーヘッドを抑えるため、既存インスタンスに接続
Set projApp = Application
On Error GoTo ErrHandler
‘ “標準”カレンダーをターゲットとする
Set baseCal = projApp.ActiveProject.BaseCalendars(“標準”)
Set exps = baseCal.Exceptions
‘ JSONパース処理(ここでは簡略化のため配列を想定)
‘ 実際にはADODB.Streamでファイルを読み込み、JSONライブラリでパースする
Dim holidays As Variant
holidays = GetHolidaysFromExternalSource(jsonPath)
‘ メモリリークを避けるため、既存の休日例外を一度クリアするケースもあるが、
‘ 実務では差分更新(Delta Update)を推奨する
For Each holiday In holidays
‘ 休日設定の追加(既存の例外と重複しないようロジックを組むこと)
‘ Type:=pjExceptionTypeWorking とすると稼働日設定になるため注意
exps.Add Type:=pjExceptionTypeDay, Start:=holiday, Finish:=holiday
Next holiday
CleanExit:
‘ 明示的なオブジェクト解放
Set exps = Nothing
Set baseCal = Nothing
Set projApp = Nothing
Exit Sub
ErrHandler:
Debug.Print “Error: ” & Err.Description
Resume CleanExit
End Sub
—
3. チーフアーキテクトからの警鐘:パフォーマンスと整合性
メモリ最適化の極意
VBAはガベージコレクションが強力ではない。`MSProject.Exceptions`のようなコレクション操作を行う際、`For Each`ループ内で大量のオブジェクト生成を行うと、ヒープ領域を圧迫する。ループが数千件に及ぶ場合は、一定回数ごとに `DoEvents` を挟み、Windowsのメッセージループを回してメモリ解放の機会を与えることが、システムクラッシュを防ぐ定石だ。
レガシー環境との共存
もし貴殿の環境が古いMSPバージョン(Project 2010以前)であれば、JSONライブラリの導入は困難だろう。その場合、XMLを `MSXML2.DOMDocument` でパースするのが最も安定する。XMLのパス指定には必ず `XPath` を使用し、ノードの列挙にはメモリ効率の高い `IXMLDOMNodeList` を用いること。
システム間連携の勘所
休日マスターをCSVやExcelで管理している現場も多いが、JSON/XMLでの一元管理を強く推奨する。理由は「構造化」にある。年度ごとの祝日変更や、地域ごとの稼働日設定を、`isWorkingDay` プロパティと組み合わせて階層的に保持できるからだ。
—
4. 結び:自動化の先にあるもの
コードを書き、APIを叩き、MSPを支配する。それは単なる業務効率化ではない。プロジェクトの計画という「生き物」に、現実という名の息吹を吹き込む作業だ。
自動化スクリプトは、一度書けば終わりではない。OSのアップデート、MSPのパッチ適用、そして外部API仕様の変更。それらに耐えうる「堅牢なコード」こそが、真のエンジニアの証明である。
貴殿のプロジェクトが、正確なカレンダーと共に定時で完遂されることを願う。技術は、常に正確であるべきだ。
