Project VBAの深淵:リソース割り当て解除を「安全」に完遂するためのアーキテクチャ
リソース管理は、Project VBAにおける「パンドラの箱」だ。
タスクからリソースを削除する――たった一行のコードに見えるこの操作が、なぜ現場では頻繁にシステムをクラッシュさせるのか。
理由は明白だ。「リソースの割り当て解除」は単なる参照の削除ではなく、工数計算(Work)、実績(Actual Work)、そしてタスクの依存関係という複雑な依存グラフの再計算を伴う「非同期的な破壊的処理」だからだ。
安易に `Assignment.Delete` を叩けば、整合性が崩壊し、プロジェクトファイルは修復不能なエラーを吐く。今日は、伝説的アーキテクトの視点から、この「爆弾」を安全に処理するための極限の設計論を授ける。
—
1. なぜ「単純な削除」は死を招くのか
リソースを削除する際、以下の3つの制約が壁として立ちふさがる。
1. 実績工数(Actual Work)の存在: すでに工数が計上されているリソースを強制削除すると、Projectは計算ロジックを喪失し、不整合を引き起こす。
2. 依存関係の連鎖: リソースが割り当てられたタスクが、別のタスクの先行タスクである場合、削除による工数変動がスケジュール全体を書き換える。
3. オブジェクトの生存期間: `Assignment` オブジェクトをループで回しながら削除すると、コレクションのインデックスがずれる。これはVBAの初学者が必ず通る「墓場」だ。
これらを回避するための原則はただ一つ。「削除前に計算状態を退避させ、例外を予測し、整合性を担保してから実行する」ことである。
—
2. 堅牢なリソース解除を実現するプロダクションコード
以下のコードは、単に削除するのではなく、安全性と整合性を考慮した「ラッパー関数」の設計パターンだ。
‘ @brief リソースの割り当てを安全に解除するプロシージャ
‘ @param tsk 対象のタスクオブジェクト
‘ @param resName 解除対象のリソース名
Public Sub SafeRemoveAssignment(ByRef tsk As MSProject.Task, ByVal resName As String)
Dim asn As MSProject.Assignment
On Error GoTo ErrorHandler
‘ 割り当てオブジェクトの検索
Set asn = Nothing
For Each asn In tsk.Assignments
If asn.ResourceName = resName Then
‘ 1. 実績工数が存在するか確認
If asn.ActualWork > 0 Then
‘ 実績がある場合、ゼロクリアするか、処理を拒否する設計が必須
‘ ここでは工数をゼロにリセットしてから削除する安全策をとる
asn.ActualWork = 0
Debug.Print “Warning: 実績工数をゼロクリアしました”
End If
‘ 2. 削除処理
asn.Delete
Debug.Print “Success: ” & resName & ” の割り当てを解除しました。”
Exit For
End If
Next asn
Exit Sub
ErrorHandler:
‘ 予期せぬエラー発生時はログを残し、スタックを保護する
Debug.Print “Error ” & Err.Number & “: ” & Err.Description
Err.Clear
End Sub
—
3. 実務で勝つための「3つの極意」
① 「順方向」ではなく「逆方向」から攻めろ
コレクション(Assignments)をループして削除する場合、必ず最後尾からインデックスを減らしていくこと。
`For i = tsk.Assignments.Count To 1 Step -1`
これを行わないと、削除した瞬間にコレクションのサイズが変わり、メモリ上の参照が迷子になる。これがクラッシュの最大の原因だ。
② 計算モードの制御
大量のリソース操作を行う場合、`Application.Calculation = pjManual` を実行し、自動再計算を一時停止せよ。全ての割り当て解除が終わった後に `pjAutomatic` に戻すことで、パフォーマンスは劇的に向上し、計算ロジックの競合によるエラーも激減する。
③ 外部データ連携の「整合性チェック」
データベース(SQL ServerやSharePoint等)と連携している場合、VBA側の変更をコミットする前に必ず `Project.ProjectSave` を実行してはいけない。
「変更の試行」→「エラー判定」→「確定コミット」というトランザクション処理をコード内でエミュレートすること。これがプロとアマの決定的な差だ。
—
結論:コードは「対話」である
リソースの割り当て解除は、システムに対して「このタスクからこのリソースを切り離してくれ」と頼む交渉のようなものだ。いきなりハサミを入れるのではなく、現状を把握し、準備を整え、慎重に切り離す。
この設計思想さえあれば、あなたの自動化ツールは「たまに落ちる不安定なスクリプト」から「プロジェクトの意思決定を支える堅牢なインフラ」へと進化する。
もし、さらに深いレベルでのパフォーマンス最適化や、大規模プロジェクトにおけるメモリリーク対策が必要なら、いつでも扉を叩いてほしい。現場の苦労を知る者こそが、最も美しいコードを書けるのだから。
