【実務・中級編】複雑な依存関係を持つタスク群を、VBAで一括削除する際の整合性維持 – Project VBA解析バイブル

スポンサーリンク

Project VBAの深淵:依存関係を破壊せずにタスクを「外科手術」する技術

現場でProject VBAを扱うエンジニア諸君。プロジェクトのWBS(Work Breakdown Structure)を操作する際、最も恐ろしいのは「不整合」だ。

特にタスクの削除。UI上では単純な操作だが、背後では複雑な`TaskDependency`(依存関係)が網の目のように張り巡らされている。安易に`Task.Delete`を呼べば、残されたタスクは親を失い、スケジュールは計算不能な状態(#NAや矛盾した日付)に陥る。

今回は、この「整合性を維持したタスク削除」という外科手術を、VBAで如何にして安全かつ高速に実装するか。その極意を伝授する。

1. なぜ「単純な削除」が失敗するのか

Projectのオブジェクトモデルにおいて、タスクは単なる独立した行ではない。

  • 依存関係の断絶: 削除対象が「先行タスク(Predecessor)」になっている場合、そのリンクは即座に無効化、あるいは不正な参照となる。
  • 計算負荷の蓄積: ループ内で`Delete`を繰り返すと、都度Projectの再計算エンジンが走り、パフォーマンスが劇的に低下する。

真のアーキテクトは、「削除対象を特定し、依存関係を再ルーティングし、最後に一括削除する」という3ステップを徹底する。

2. 堅牢な実装:依存関係の再構築ロジック

以下は、ターゲットタスクを削除する前に「そのタスクを先行タスクとして持つタスク」を検出し、リンクを適切に再配置、あるいは解除するためのプロダクション・グレードのコードだ。

‘ @brief 整合性を維持しながらタスクを削除するプロシージャ
‘ @param targetTaskID 削除対象のタスクID
Public Sub SafeDeleteTask(ByVal targetTaskID As Long)
Dim proj As Project
Dim tsk As Task
Dim dep As TaskDependency
Dim succTask As Task

Set proj = ActiveProject
Set tsk = proj.Tasks.UniqueID(targetTaskID)

If tsk Is Nothing Then Exit Sub

‘ 1. 依存関係の処理:このタスクを先行タスクとしている後続タスクを探す
For Each dep In tsk.TaskDependencies
If dep.From = tsk Then
‘ ここでビジネスロジックを挟む
‘ 例: 単にリンクを削除するのか、後続タスクをその先行タスクに再接続するのか
‘ 今回は「リンクを安全に解除する」実装とする
dep.Delete
End If
Next dep

‘ 2. 本体の削除
‘ UIの再計算を抑制するために画面描画を止めるなどの工夫も有効だが、
‘ ここでは確実に削除を実行する
tsk.Delete

Debug.Print “タスク ” & targetTaskID & ” は依存関係を整理して削除されました。”
End Sub

3. 実務で「死なない」ための3つの鉄則

① UniqueID を信じろ

`Task.ID`は行番号に依存するため、削除や挿入で刻々と変化する。一方、`UniqueID`は不変だ。データベースや外部ファイル(Excel等)と連携する場合、キーとして使うべきは常に`UniqueID`である。

② 再計算のトラップを回避せよ

Project VBAにおいて、削除処理を大量に行う場合は `Application.Calculation = pjManual` を一時的に設定し、最後に一括再計算させることで、処理速度を10倍以上向上させることが可能だ。

③ 外部データ(Excel/DB)との同期

外部データからWBSを再構築する際は、必ず以下の順序を守れ。
1. 既存タスクのクリア(または論理削除)
2. タスクの新規作成(`Tasks.Add`)
3. 依存関係の再生成(タスクが全て生成された後にリンクを張る)

これらを混在させると、Projectは「まだ存在しないタスクへのリンク」を作ろうとしてエラーを吐く。これは鉄則だ。

4. アーキテクトからの提言

多くのエンジニアが陥る罠は、「VBAを単なる自動化ツール」と見なすことだ。Project VBAを扱うということは、プロジェクトという生き物の「時間構造」を直接制御しているという自覚を持て。

今回紹介した「依存関係のクリーンアップ」は、大規模プロジェクトになればなるほど重要性を増す。コードをコピペするだけでなく、なぜこの順序で実行する必要があるのか――その裏にあるオブジェクトのライフサイクルを理解してほしい。

君たちが記述するその一行が、現場のプロジェクトマネージャーの救いとなるか、それとも新たなバグの温床となるか。すべては君たちの設計思想にかかっている。

健闘を祈る。

タイトルとURLをコピーしました