【入門編】WBSの階層構造を維持したまま特定タスク群を別ファイルへ切り出すモジュール開発 – Project VBA解析バイブル

スポンサーリンク

こんにちは、現場の最前線でProject VBAを操るチーフアーキテクトです。

Microsoft Project(以下、MS Project)を使いこなしていると、必ずぶつかる壁があります。それは「肥大化しすぎたプロジェクトファイルの分割管理」です。

数千タスクに及ぶ巨大なスケジュールを一つのファイルで管理するのは、パフォーマンス面でも運用面でも限界があります。「この特定の工程(WBS)だけを切り出して、協力会社に渡したい」「別ファイルとして独立させたい」――そんな要望を受けたとき、あなたならどうしますか?

単なるコピー&ペーストでは、大切に育てた「階層構造(WBS)」が崩れ、タスク間の「依存関係(リンク)」がパズルのようにバラバラになってしまいます。

今日は、Project VBAの真髄である「オブジェクトの階層構造」と「依存関係の再構築」をテーマに、プロの現場でもそのまま通用する「タスク切り出しモジュール」の設計思想を伝授しましょう。ここをクリアすれば、Project VBAの基本はバッチリですよ。

1. MS Projectの「魂」は階層構造(OutlineLevel)にある

MS ProjectがExcelと決定的に違うのは、タスクが単なる行ではなく、「親子関係(Hierarchy)」を持っている点です。

タスクを別ファイルに切り出す際、最も重要なプロパティは以下の2つです。

  • OutlineLevel: そのタスクが何階層目にあるか(1, 2, 3…)
  • Predecessors: 先行タスクとの繋がり(依存関係)

タスクを新しいプロジェクトに「移植」する場合、この `OutlineLevel` を正しく再現しないと、サマリータスク(太字のまとめタスク)がただの一般タスクになってしまいます。

2. 失敗しないための「切り出し」アルゴリズム

初心者が陥りやすいミスは、「選択したタスクを上から順にコピーするだけ」で済ませようとすることです。これでは依存関係のIDがズレてしまい、スケジュールが崩壊します。

プロのエンジニアは、以下のステップでコードを組みます。

1. ターゲットの特定: 切り出したいタスク群を配列やコレクションに保持する。
2. 構造の複製: 新規ファイルを作成し、`OutlineLevel` を維持したままタスクを生成する。
3. IDの再マッピング: 元のファイルのタスクIDと、新しいファイルのタスクIDの「対応表」を作る。
4. 依存関係の復元: 対応表を元に、新しいファイル内で先行タスクをリンクし直す。

3. 【実践】WBS階層維持・タスク切り出しモジュール

それでは、具体的なコードを見ていきましょう。このコードは、現在選択しているタスク群を新しいプロジェクトファイルへ抽出し、階層構造を維持するものです。

Option Explicit

‘ ==========================================================================
‘ Module: TaskExtractor
‘ Description: 選択されたタスクを階層構造を維持したまま別ファイルへ切り出す
‘ ==========================================================================

Public Sub ExtractSelectedTasksToNewProject()
Dim sourceProj As Project
Dim targetProj As Project
Dim tsk As Task
Dim selTasks As Tasks
Dim newTsk As Task
Dim taskMap As Object ‘ 元IDと新タスクの対応を保持

Set sourceProj = ActiveProject

‘ 1. 選択範囲のチェック
On Error Resume Next
Set selTasks = ActiveSelection.Tasks
On Error GoTo 0

If selTasks Is Nothing Then
MsgBox “切り出したいタスクを選択してください。”, vbExclamation
Exit Sub
End If

‘ 高速化のため計算を一時停止
Application.Calculation = pjManual
ScreenUpdating = False

‘ 2. 新規プロジェクトの作成
Set targetProj = Projects.Add
Set taskMap = CreateObject(“Scripting.Dictionary”)

‘ 3. タスクのコピー(構造の維持)
Dim i As Long
For Each tsk In selTasks
If Not tsk Is Nothing Then
‘ 新規プロジェクトにタスクを作成
Set newTsk = targetProj.Tasks.Add(Name:=tsk.Name)

‘ 基本プロパティのコピー
‘ ※OutlineLevelを直接書き込むことで階層を強制維持します
newTsk.OutlineLevel = tsk.OutlineLevel
newTsk.Duration = tsk.Duration
newTsk.Start = tsk.Start
newTsk.Finish = tsk.Finish

‘ IDの対応関係を保存(後で依存関係を張るため)
taskMap.Add tsk.ID, newTsk
End If
Next tsk

‘ 4. 依存関係(リンク)の再構築
‘ ※選択範囲内での依存関係のみを復元します
Dim sourceTsk As Task
Dim pred As TaskDependency

For Each sourceTsk In selTasks
If Not sourceTsk Is Nothing Then
For Each pred In sourceTsk.TaskDependencies
‘ 先行タスクが今回の抽出対象に含まれているか確認
If taskMap.Exists(pred.From.ID) Then
‘ 新しいプロジェクト内でリンクを張る
targetProj.Tasks(taskMap(sourceTsk.ID).ID).LinkPredecessors _
Tasks:=targetProj.Tasks(taskMap(pred.From.ID).ID), _
LinkType:=pred.Type, _
Lag:=pred.Lag
End If
Next pred
End If
Next sourceTsk

‘ 設定を戻す
Application.Calculation = pjAutomatic
ScreenUpdating = True

MsgBox “タスクの切り出しが完了しました!” & vbCrLf & _
“階層構造と選択範囲内の依存関係を維持しています。”, vbInformation
End Sub

4. プロの視点:ここが「掌握」のポイント

このコードには、単なるリファレンスには載っていない「現場の知恵」がいくつか込められています。

① OutlineLevelの直接操作

通常、MS ProjectのGUIで階層を作るには「インデント」ボタンを押しますが、VBAでは `newTsk.OutlineLevel = tsk.OutlineLevel` と直接数値を代入できます。これにより、複雑なループ処理を組まなくても、瞬時に元のWBS構造を再現できるのです。

② DictionaryオブジェクトによるIDマッピング

MS ProjectのタスクIDは、タスクが追加・削除されるたびに変動します。
切り出し先のファイルではIDが変わってしまうため、`Dictionary`(連想配列)を使って「元のID 〇番は、新しいファイルでは △番」という対応表を作るのが、依存関係を崩さないための鉄則です。

③ ScreenUpdating と Calculation の制御

大規模プロジェクトでは、タスクを一つ追加するたびに全体のスケジュール再計算が走り、動作が非常に重くなります。`Application.Calculation = pjManual` で計算を止め、最後に一括で計算させる。これが「動かないマクロ」を「爆速ツール」に変える魔法です。

5. 初学者が陥りやすいエラーと対策

1. 「Nothing」へのアクセス:
Projectでは、空白行も「Task」としてカウントされることがありますが、その実体は `Nothing` です。`If Not tsk Is Nothing Then` というチェックを怠ると、すぐにランタイムエラーが発生します。
2. サマリータスクの期間:
サマリータスクの期間(Duration)をVBAで無理やり書き込もうとすると、エラーになる場合があります。サマリータスクは配下のタスクによって自動計算されるものだからです。上記のコードではシンプルにしていますが、実戦では「子タスクがあるかどうか」を判定するロジックを加えるとより堅牢になります。

結び:Project VBAを操るあなたへ

MS Projectの自動化は、Excel VBAよりも「データの整合性」に対してシビアです。しかし、今回学んだ「階層(OutlineLevel)」と「依存関係(Dependencies)」の仕組みさえマスターすれば、どんなに複雑なプロジェクト管理も自由自在に操れるようになります。

まずは、小さなプロジェクトでこのコードを試してみてください。「マクロの記録」では絶対に到達できない、オブジェクト構造を掌握したエンジニアだけの景色が見えてくるはずです。

もし途中で分からなくなったら、いつでもこの場所に戻ってきてください。Project VBAの道は奥深いですが、一歩ずつ進めば必ずあなたの強力な武器になります。

応援していますよ!

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