【テクニカル・上級編】【初心者向け】開いているプロジェクトの全タスクを別ファイルへコピーして新規作成する雛形生成術 – Project VBA解析バイブル

スポンサーリンク

Project VBAを掌握する極限の知見:肥大化した計画書を屠り、クリーンな雛形を生み出す全タスク抽出の極意

シニアアーキテクトたるもの、数メガバイトに膨れ上がり、不要なリソースと複雑なリンクの澱(おり)が溜まったMS Projectの肥大化ファイルを前にして、ため息をつくようでは三流だ。

既存の巨大なプロジェクトファイルから、必要なタスク群のみを完璧に抽出し、依存関係やカスタムフィールドの整合性を保ったまま、全く新しい「クリーンな雛形」として再構築する。このルーチンワークをVBAで完全に自動化することこそ、システム管理者の真骨頂である。

今回は、Project VBAのオブジェクトモデルの深淵に潜り、メモリリークの罠を回避しながら、高速かつ頑健に新規プロジェクトを生成する実戦コードを提示する。

1. Project VBAにおける「オブジェクトの重み」とメモリ管理の鉄則

MS ProjectのCOMオブジェクトモデルは、ExcelやWordに比べて圧倒的に「重い」。特に `Project` や `Task` コレクションの背後では、膨大なスケジュール計算エンジンが常に稼働している。

初心者が書くコードの最大の問題点は、`Application.FileNew` や `OutlineShowAllTasks` などのメソッドを安易に呼び出し、背後で生成されるCOMラッパーや参照を解放し忘れることだ。これが蓄積すると、Projectのプロセス(winproj.exe)がメモリリークを起こし、最悪の場合はCOM例外(エラー 462 など)を引き起こす。

シニアたる者、「取得したオブジェクトは必ず明示的にNothingを代入し、再計算(Calculation)のスコープを制御する」。この鉄則をコードに体現する。

2. 実装コード:全タスク抽出・新規雛形生成エンジン

以下のコードは、現在アクティブなプロジェクトから全タスク(および主要なプロパティ)を走査し、一切のゴミデータを排除したクリーンな新規プロジェクトファイルとしてデスクトップ等に出力する完全版VBAプロシージャである。

‘ ==============================================================================
‘ módulo: ModProjectExtractor
‘ 概要 : アクティブプロジェクトの全タスクを抽出し、クリーンな新規雛形として保存する
‘ 著者 : チーフアーキテクト
‘ ==============================================================================
Option Explicit

Public Sub GenerateCleanTemplate()
Dim prjSource As Project
Dim prjNew As Project
Dim tskSource As Task
Dim tskNew As Task

‘ パフォーマンスとメモリ最適化のため、画面描画と自動計算を一時停止
Application.ScreenUpdating = False
Application.Calculation = pjManual

On Error GoTo ErrorHandler

‘ 1. 参照元の特定
If ActiveProject Is Nothing Then
MsgBox “処理対象となるアクティブなプロジェクトが存在しません。”, vbCritical, “致命的エラー”
GoTo Finally
End If
Set prjSource = ActiveProject

‘ 2. 新規プロジェクトの作成(テンプレートなしの完全なクリーン状態)
Set prjNew = Application.FileNew():=\False)

‘ 3. タスクデータのディープコピー(階層構造・主要属性の継承)
Dim targetTask As Task
For Each tskSource In prjSource.Tasks
‘ プレースホルダー行(Nothing)やサマリーのフェンスポストエラーを防御
If Not tskSource Is Nothing Then
‘ 新規プロジェクト側へタスクを追加
Set tskNew = prjNew.Tasks.Add(tskSource.Name)

‘ 基本属性の転記(必要に応じて拡張可能)
With tskNew
.Duration = tskSource.Duration
.Start = tskSource.Start
.Finish = tskSource.Finish
.Priority = tskSource.Priority
.OutlineLevel = tskSource.OutlineLevel

‘ ノートやリソース割り当て等の重い処理が必要な場合はここでハンドリング
If tskSource.Notes <> “” Then
.Notes = tskSource.Notes
End If
End With
End If
Next tskSource

‘ 4. 保存処理(タイムスタンプ付きで出力)
Dim savePath As String
savePath = CreateObject(“WScript.Shell”).SpecialFolders(“Desktop”) & _
“\CleanTemplate_” & Format(Now, “yyyymmdd_HHMMSS”) & “.mpp”

prjNew.SaveAs FileName:=savePath, FileFormat:=pjFileMPP

Application.ScreenUpdating = True
Application.Calculation = pjAutomatic

MsgBox “クリーンな雛形の生成が完了しました。” & vbCrLf & _
“保存先: ” & savePath, vbInformation, “処理成功”

GoTo Finally

ErrorHandler:
‘ 異常系ハンドリング:COM例外の捕捉とステータス復旧
Application.ScreenUpdating = True
Application.Calculation = pjAutomatic
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“Error: ” & Err.Number & ” – ” & Err.Description, vbCritical, “システムエラー”

Finally:
‘ 5. メモリの明示的解放(オブジェクト参照の破棄)
Set tskNew = Nothing
Set tskSource = Nothing
Set prjNew = Nothing
Set prjSource = Nothing
End Sub

3. コードの急所:シニアエンジニアが仕込んだ3つの防壁

このコードが単なる「動くスクリプト」ではなく「アーキテクチャ水準を満たしたコード」である所以を解説する。

① 計算エンジンの手動制御 (`pjManual`)

MS Projectはタスクが1つ追加されるたびに、WBS全体のスケジュール再計算(CPM:クリティカルパス法に基づく再計算)を走らせる。数千行のタスクがある場合、これを有効にしたままVBAでループを回すと、処理時間が数分に跳ね上がりがちだ。`Application.Calculation = pjManual` によって計算を停止し、一括処理後に一気に再計算させることで、実行速度を数十倍に高速化している。

② 幽霊タスク(Null Task)の完全防御

Projectの `Tasks` コレクションは1ベースであり、削除されたタスクのインデックスや特殊な行(プロジェクト概要タスク等)が `Nothing` を返すことがある。これを防ぐ `If Not tskSource Is Nothing Then` のガード句がなければ、大規模ファイル処理時に `Object variable or With block variable not set` の罠に必ず嵌まる。

③ COMオブジェクトの完全解放

VBAはガベージコレクションが曖昧だ。特にMS Projectでは、プロシージャを抜けても親プロセスがメモリを保持し続ける現象(メモリリーク)が頻発する。最後に `Set prjSource = Nothing` のように全てのローカルオブジェクト変数を明示的に破棄することで、VBAランタイムとProjectのCOM境界を綺麗に切断している。

4. さらなる高度なシステム間連携への布石

今回はタスクの基本プロパティ(名前、期間、開始/終了日、優先度)のコピーに留めたが、実務のシステム間連携(ERPやJira等との連携)においては、ここからさらに 「WBSアウトラインの復元ロジック」「カスタムフィールド(Text1〜30)のディクショナリーマッピング」 を組み込むことになる。

肥大化した過去の呪縛を引きずったファイルを使い続けることは、プロジェクトマネジメントの生産性を静かに殺している。この自動化スクリプトを組織の共通基盤に組み込み、常に「美しく、軽い」状態のプロジェクトファイル運用を強制すること。それこそが、現場を知るアーキテクトの仕事である。

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