Project VBAの深淵:計算エンジンを「飼い慣らす」ための排他制御戦略
Project VBAにおける最大にして最悪の敵は、計算エンジンの「暴走」だ。
開発者が最も陥りやすい罠は、全タスクを一括更新しようとして計算エンジンを無闇に叩き起こすことにある。特に「手動タスク」と「自動タスク」が混在するプロジェクトにおいて、`.Manual`プロパティを無造作に切り替えれば、依存関係の連鎖反応によりパフォーマンスは崩壊し、予期せぬ日付のズレが生まれる。
今日伝授するのは、計算エンジンを止めずに、特定のタスクだけを外科手術のように制御する「スマート・アップデート」の極意だ。
—
なぜ「計算モードの切り替え」はNGなのか
多くのエンジニアが「一括処理のために計算モードをオフにする」という手法をとる。だが、これは巨大なプロジェクトにおいて自殺行為に近い。
- 同期の喪失: `Application.Calculation = pjManual` を実行した瞬間、全ての依存関係計算が停止する。この状態でDB連携や外部ツールとの整合性を保つのは至難の業だ。
- 不整合の蓄積: 計算エンジンが停止している間に発生した整合性の欠如は、モードを戻した瞬間に「計算の雪崩」を引き起こす。これが原因不明のバグの温床となる。
極限の知見:Task.Manual プロパティの正しい制御法
計算エンジン全体を止めるのではなく、「特定のタスクの制約条件を固定し、計算エンジンに干渉させない」というアプローチを取るべきだ。
実践:安全なタスク更新の設計パターン
以下のコードは、計算エンジンを止めず、かつ特定タスクを「手動」に切り替えて値を書き込み、再度自動に戻す際のエラーハンドリングと整合性維持を考慮したプロダクションコードだ。
‘ @brief 特定タスクを安全に更新するためのラッパー関数
‘ @param tsk 対象のタスクオブジェクト
‘ @param startDate 開始日
‘ @param finishDate 終了日
Public Sub SafeUpdateTask(ByRef tsk As Task, ByVal startDate As Date, ByVal finishDate As Date)
On Error GoTo ErrorHandler
‘ 1. 計算エンジンに「このタスクは手動だ」と明示する
‘ これにより、更新中に依存関係の再計算がトリガーされるのを防ぐ
If Not tsk.Manual Then
tsk.Manual = True
End If
‘ 2. 値の更新
tsk.Start = startDate
tsk.Finish = finishDate
‘ 3. 必要に応じて自動計算へ戻す
‘ ここで計算エンジンが再評価を開始するが、対象が局所的なため影響範囲を限定できる
tsk.Manual = False
Exit Sub
ErrorHandler:
Debug.Print “Error in Task ID ” & tsk.ID & “: ” & Err.Description
‘ 異常終了時は計算エンジンを強制的に再同期させるため、念のため手動フラグを戻す
tsk.Manual = True
End Sub
プロダクション環境における3つの鉄則
1. 依存関係の「静的解析」を怠るな
計算エンジンを制御する前に、対象タスクが「先行タスク」として他の重要タスクに紐付いていないか確認せよ。もし紐付いているなら、`tsk.Manual = False` に戻した瞬間に連鎖的な日付変動が発生する。この場合、更新後に `Project.Calculate` を呼び出すのではなく、対象のタスク群をまとめて処理する「バッチ処理」へ設計を変更せよ。
2. DB/外部連携との排他制御
データベースから値を吸い上げる際、ループ処理の中で頻繁に `tsk.Manual` を叩くのは避けよ。更新用のデータセットをメモリ(配列)に一度展開し、「更新が必要なタスクのみをピンポイントで制御」するのが、パフォーマンスと安定性を両立する唯一の道だ。
3. 「計算の完了」を信じない
Projectの計算エンジンは非同期的に働くことがある。大規模な更新を行った直後に計算結果を参照すると、古い値を取得してしまうケースがある。
更新直後は必ず以下のフラグを確認する癖をつけよ。
‘ 更新後の整合性担保(計算エンジンがビジーでないことを確認)
Do While ActiveProject.IsCalculating
DoEvents
Loop
—
アーキテクトからの助言
「計算エンジンを暴走させない」とは、計算エンジンに干渉しないことではない。「どのタイミングでエンジンに計算のボールを渡すか」を制御することだ。
君たちが書くVBAは、単なるマクロではない。Projectという巨大な計算エンジンの挙動を支配する「ドライバー」であるという自覚を持て。安易な `Calculation = pjManual` に逃げるな。タスクのライフサイクルを理解し、外科手術のような精密さで制御せよ。
それが、伝説的なエンジニアへと至る唯一の道だ。
