【実務・中級編】【中級者向け】CSVから読み込んだ依存関係を、タスクの「名前」をキーに動的マッピングしてリンクを張る – Project VBA解析バイブル

スポンサーリンク

泥臭い「ID依存」を捨てろ。Project VBAでタスク名をキーにする「動的依存関係構築」の極意

VBAでMicrosoft Projectを制御する際、多くのエンジニアが陥る罠がある。それは、インポート元のCSVとプロジェクトファイルの「ID」を同期させようとすることだ。

「IDは挿入や削除で簡単にズレる」。実務でこれを知らない者は、自動化ツールを組んだ翌日に崩壊したスケジュールを泣きながら修正する羽目になる。

真のプロフェッショナルは、「不変なもの(名前)」をキーに「流動的なもの(ID)」を特定するという設計思想を持つ。今回は、CSVから読み込んだタスク名を探索し、動的に先行タスク(Predecessors)をリンクさせる、堅牢で保守性の高いロジックを伝授しよう。

—

1. なぜ「ID」をキーにしてはいけないのか

プロジェクト管理において、タスクIDは単なる「現在の行番号」に過ぎない。行の入れ替えやソートが発生すれば、IDは一瞬で無意味になる。

一方で「タスク名」は、プロジェクトが続く限り一意であるべき(あるいは一意に管理すべき)ID的な存在だ。我々が書くべきは、「名前でタスクオブジェクトを特定し、そのIDを抽出してリンクを張る」という、抽象度の高いマッピングロジックである。

—

2. 堅牢なインポートロジックの設計方針

この自動化ツールには、以下の3つの鉄則を課す。

1. Dictionaryオブジェクトによる探索コストの削減: 全タスクを毎回ループで回すのは愚策だ。初回に名前とIDをDictionaryにキャッシュし、O(1)で検索せよ。
2. エラーハンドリングの徹底: 「先行タスクが見つからない」場合、プログラムを止めずにログを吐き出し、プロセスを完走させる。
3. リンクの重複防止: 既にリンクが存在する場合の重複排除を考慮する。

—

3. 実践コード:名前ベースの動的依存関係構築

以下は、CSV(タスク名, 先行タスク名)を読み込み、Project上のタスクへリンクを反映させるプロシージャだ。

‘ 必要な参照設定: Microsoft Project 16.0 Object Library
‘ Microsoft Scripting Runtime (Dictionary用)

Public Sub ImportDependenciesFromCSV(csvPath As String)
Dim proj As Project: Set proj = ActiveProject
Dim dictTasks As Object: Set dictTasks = CreateObject(“Scripting.Dictionary”)

‘ 1. 名前とIDのキャッシュ(高速化の要)
Dim t As Task
For Each t In proj.Tasks
If Not t Is Nothing Then
If Not dictTasks.Exists(t.Name) Then
dictTasks.Add t.Name, t.ID
End If
End If
Next t

‘ 2. CSV読み込みとリンク構築
Dim fileNum As Integer: fileNum = FreeFile
Dim lineData As String, parts() As String

Open csvPath For Input As #fileNum
Line Input #fileNum, lineData ‘ ヘッダー読み飛ばし

Do Until EOF(fileNum)
Line Input #fileNum, lineData
parts = Split(lineData, “,”)

Dim taskName As String: taskName = parts(0)
Dim predName As String: predName = parts(1)

‘ 3. 動的マッピング
If dictTasks.Exists(taskName) And dictTasks.Exists(predName) Then
Dim targetTask As Task: Set targetTask = proj.Tasks(dictTasks(taskName))
Dim predID As Long: predID = dictTasks(predName)

‘ リンク設定(既にリンクがある場合はスキップ等のロジックをここに)
targetTask.TaskDependencies.Add proj.Tasks(predID)
Else
Debug.Print “警告: タスクが見つかりません -> ” & taskName & ” / ” & predName
End If
Loop

Close #fileNum
MsgBox “依存関係の構築が完了しました。”
End Sub

—

4. プロダクション環境への導入アドバイス

このコードを実務で運用する際、以下の点に注意せよ。

  • タスク名の正規化: CSVとProject上のタスク名で、全角・半角の揺れや、末尾のスペースが残ることがある。`Trim(StrConv(name, vbNarrow))` 等で読み込み時に正規化する関数を挟むのが定石だ。
  • トランザクションの意識: 大量データを扱う場合、`Application.ScreenUpdating = False` を活用せよ。Projectの再計算ロジックが走るたびに描画を更新すると、処理時間が指数関数的に増大する。
  • 循環参照の回避: 依存関係を自動構築すると、ループ状のリンク(A→B→A)が生まれる可能性がある。Projectの標準機能で警告が出るが、ツール側でも事前にトポロジカルソートのチェックを入れるのが、アーキテクトとしての矜持だ。

最後に:VBAを「自動化の呪い」にしないために

「動けばいい」コードは、半年後の自分を殺す。今回紹介したDictionaryによるキー検索は、データ量が増えてもパフォーマンスが劣化しない、非常にスケーラブルな手法だ。

IDに依存せず、論理的な名前で紐解く。このアプローチこそが、複雑なプロジェクトを制御するための唯一の解である。さあ、このコードを武器に、手作業による地獄のスケジュール修正から自らを解放してくれ。

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