【実務・中級編】【中級者向け】タスクの「完了率」に応じて依存関係のリンクを自動的に「実績」として保護する制御法 – Project VBA解析バイブル

スポンサーリンク

Project VBAの深淵:タスクの「実績保護」を自動化するアーキテクチャ設計

プロジェクト管理において、VBAでタスク依存関係を操作している諸君。単に`Task.Predecessors`を書き換えるだけのスクリプトで満足していないだろうか?

「完了したタスクのリンクが後から勝手に書き換わっていた」——これは大規模プロジェクトにおける最大級のアンチパターンだ。タスクが完了(%完了=100%)した時点で、その依存関係は「歴史的な実績」として封印されねばならない。

今回は、Project VBAのオブジェクトモデルを逆手に取り、完了したタスクの依存関係を「読み取り専用」としてガードする、堅牢な制御ロジックを伝授する。

—

1. なぜ「ガード」が必要なのか?(設計思想)

VBAによる自動化で最も恐ろしいのは、再帰的な依存関係の再計算や、うっかりとしたループ処理によるデータの汚染だ。特に、`Task.Predecessors` プロパティは強力だが、一度書き込むと元の状態には戻せない。

プロの設計原則:

  • イミュータブル(不変)な実績: 完了(100%)したタスクは、いかなる自動化スクリプトからも「編集不可」にする。
  • 防御的プログラミング: ロジック内で判定するのではなく、タスクのプロパティ(`Flag`や`CustomField`)を利用して、UIレベルの制御と同期させる。

—

2. 実装コード:完了タスクの依存関係保護

以下のコードは、Projectのタスクを走査し、`PercentComplete`が100%のタスクに対して、依存関係の書き込みを制限するためのトリガーを設ける仕組みだ。

‘ ———————————————————
‘ Module: TaskGuardManager
‘ 完了したタスクの依存関係を「実績」として保護する
‘ ———————————————————
Option Explicit

Public Sub ProtectCompletedTasks()
Dim tsk As Task
Dim proj As Project
Set proj = ActiveProject

‘ パフォーマンス向上のため、計算を一時停止
Application.Calculation = pjManual

On Error GoTo ErrorHandler

For Each tsk In proj.Tasks
If Not tsk Is Nothing Then
‘ 100%完了しているタスクを特定
If tsk.PercentComplete = 100 Then
‘ フラグフィールド(Flag1)を保護フラグとして使用する運用を推奨
‘ 実際に書き込みを制御する場合は、このフラグをチェックするロジックを
‘ 全ての依存関係操作スクリプトに組み込むことが重要
tsk.Flag1 = True

‘ 必要に応じてタスクのロック状態を制御
‘ (注:Projectには純粋なRead-Onlyプロパティは存在しないため、
‘ 自作のバリデーション関数を経由させる設計が必須)
Debug.Print “Protected Task: ” & tsk.Name
End If
End If
Next tsk

Application.Calculation = pjAutomatic
Exit Sub

ErrorHandler:
Application.Calculation = pjAutomatic
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
End Sub

‘ — 依存関係を書き込む際のバリデーション関数 —
‘ この関数を全ての書き込み処理の前段に置くこと
Public Function CanEditDependencies(tsk As Task) As Boolean
If tsk.Flag1 = True Then
MsgBox “エラー: タスク ‘” & tsk.Name & “‘ は完了済みのため、依存関係の変更は禁止されています。”, vbExclamation
CanEditDependencies = False
Else
CanEditDependencies = True
End If
End Function

—

3. 実務で「バグ」を生ませないための3つの鉄則

① 「計算の自動化」を制御せよ

`Application.Calculation = pjManual` を使わずに数千行のタスクをループさせれば、Projectはタスクを更新するたびに再計算を行い、処理速度は劇的に低下する。大規模な自動化では、「更新時」ではなく「一括反映時」に計算させるのが鉄則だ。

② 外部連携は「中間テーブル」を経由させよ

ExcelやDBからタスク情報を読み込んで依存関係を更新する場合、「直接Projectに流し込む」のは避けるべきだ。
一度VBA内のコレクション(`Scripting.Dictionary`等)に展開し、矛盾がないかバリデーションを通してから、最後に一括で`Task.Predecessors`へ書き込む。このバッファ構造こそが、データ破損を防ぐ唯一の策である。

③ プロパティの「副作用」を知る

`Task.Predecessors`に文字列を渡して設定する際、区切り文字やリンクの種類(FS, SS等)の解釈は環境に依存する。可能であれば、`TaskLink`オブジェクトを個別に生成・管理する手法をとることで、複雑な依存関係の解析を最小限に抑えることができる。

—

結論:コードは「契約」である

今回紹介した`CanEditDependencies`のようなバリデーション関数は、単なるヘルパーではない。これは「完了したタスクには手を触れない」という、開発チームとプロジェクト管理者の間の契約そのものだ。

自動化エンジニアの腕の見せ所は、いかに複雑な処理を書くかではない。「いかにして予期せぬ変更を防ぎ、システムを安定稼働させるか」という保守の視点にある。

諸君、まずは自身のプロジェクトで「Flag1」を保護フラグとして活用し、明日からの運用を変えてみてほしい。それが、伝説の自動化エンジニアへの第一歩だ。

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