【Project VBA】リソース割り当てを「破壊」せずに「浄化」する:極限のクリーンアップ・アーキテクチャ
プロジェクト計画の変更は、現場にとって日常茶飯事だ。しかし、そのたびに手作業でリソースの割り当てを解除(削除)しているようでは、プロのエンジニアとは呼べない。
特にMicrosoft ProjectのVBA(Project Object Model)における「割り当て(Assignment)」の操作は、安易にループを回すとメモリリークや予期せぬインデックスのズレを誘発する。今回は、プロジェクトの健全性を保つための「安全かつ高速なクリーンアップ・ロジック」を伝授する。
—
1. なぜ「単純なループ」で事故が起きるのか
多くのジュニアエンジニアは、以下のようなコードを書いて自爆する。
‘ 【悪い例:やってはいけない】
For Each A In ActiveProject.Assignments
If A.Resource.Name = “不要なリソース” Then A.Delete
Next
なぜこれが致命的なのか? コレクションの反復処理中に要素を削除すると、インデックスの整合性が崩壊し、削除漏れやRuntime Errorが発生するからだ。
プロの現場では、「逆順ループ(Backwards Iteration)」が鉄則である。後ろから削除すれば、インデックスのズレは後続の要素に影響しない。これが鉄則だ。
—
2. 本質的なクリーンアップ・ロジック
以下に、実務環境でそのまま導入可能な「堅牢な割り当て削除ツール」を提示する。エラーハンドリングと、処理対象を明確にするためのフィルタリングを組み込んでいる。
‘ プロジェクト内の特定リソース割り当てを安全に一括削除する
Sub SafeCleanupAssignments(ByVal targetResourceName As String)
Dim tsk As Task
Dim asn As Assignment
Dim count As Long
On Error GoTo ErrorHandler
‘ プロジェクト全体(タスク単位)で走査する
For Each tsk In ActiveProject.Tasks
If Not tsk Is Nothing Then
‘ 割り当ての逆順走査(Delete時は必須のテクニック)
For count = tsk.Assignments.Count To 1 Step -1
Set asn = tsk.Assignments(count)
‘ 条件に合致するか判定
If asn.ResourceName = targetResourceName Then
‘ ログ出力(デバッグ用)
Debug.Print “削除対象: ” & tsk.Name & ” – ” & asn.ResourceName
‘ 削除実行
asn.Delete
End If
Next count
End If
Next tsk
MsgBox “クリーンアップ完了。該当するリソースの割り当てを解除しました。”, vbInformation
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラー発生: ” & Err.Description, vbCritical
End Sub
—
3. 設計の勘所:なぜこの構造なのか
このコードが「プロダクションレベル」である理由は3点ある。
1. タスク単位のスコープ: `ActiveProject.Assignments` ではなく、`Task.Assignments` を叩いている。これにより、プロジェクトの構造を維持したまま、局所的な変更を確実に実行できる。
2. 逆順ループの徹底: 前述の通り、インデックスの再計算コストをゼロにするための最適解だ。
3. Nothingチェック: Project VBA特有の「サマリータスク」や「削除済みタスク」がオブジェクトモデル上に残るケースを想定し、Nullチェックを挟んでいる。これを怠ると、大規模プロジェクトほどクラッシュする。
—
4. 実務への応用と注意点
外部データソースとの連携について
もしExcelやSQL Serverからリソース情報を取得して削除判定を行う場合、VBA内で頻繁にDB接続を開閉してはならない。リソースIDや名前のリストを一度ArrayやCollectionに格納し、メモリ上で突き合わせること。I/O(入出力)の回数は、パフォーマンスと安定性に直結する。
パフォーマンスの最適化
プロジェクトの規模が数万行を超える場合、`Application.ScreenUpdating = False` を活用せよ。Projectの描画更新を止めるだけで、数分かかる処理が数秒に短縮されることもある。
アーキテクトからの助言
「自動化」とは、ただ楽をすることではない。「人間が手作業で行う際に発生しうるヒューマンエラーを、プログラムの構造によって排除すること」である。
今回提供したロジックは、あくまで土台だ。君のプロジェクトの運用ルールに合わせて、ログの出力先をテキストファイルにしたり、削除前に確認ダイアログを出すなどの「ガードレール」を追加してほしい。
コードは嘘をつかない。君が書いたロジックが、プロジェクトの品質を左右するのだ。健闘を祈る。
