こんにちは!プロジェクト管理の現場で日々奮闘されている皆さん、お疲れ様です。
先輩エンジニアの私です。
今回は、MS Projectの裏側をゴリゴリに支配する「Project VBA」の世界へ皆さんをご招待します。テーマはずばり、【上級者向け】ベースラインの多重管理:過去の全ベースラインを別ファイルへアーカイブするです。
「マクロの記録なんておもちゃじゃ物足りない」「巨大化したプロジェクトファイルを何とかしたい!」そんな熱い思いを抱えているあなたへ。ここをクリアすれば、Project VBAの本質を掴んだも同然です。さあ、一緒に深淵を覗いてみましょう。
—
なぜ、ベースラインのアーカイブが必要なのか?
プロジェクトが長期化すると、進捗管理のために何度も「ベースライン(計画値)」を再設定しますよね。MS Projectには、`Baseline` から `Baseline 1`、`Baseline 2` … `Baseline 10` まで、なんと11面もの保管場所が用意されています。
しかし、ここに大きな罠があります。
これらすべてのベースラインデータを1つのファイルに抱え込み続けると、ファイルサイズが肥大化し、計算処理(再スケジュール)が重くなり、最悪の場合はファイル破損のリスク跳ね上がります。
そこで今回のアーキテクチャの出番です。
「最新のベースラインだけをメインファイルに残し、過去の遺産(全ベースライン)は自動的に別アーカイブファイルへ逃がす」。この仕組みをVBAで構築します。
—
Project VBAの基礎:オブジェクトの「重み」を知る
まず、Excel VBAとProject VBAの最大の違いを理解してください。
Excelのセルは軽量ですが、MS Projectのタスク(`Task`オブジェクト)やリソースは、背後に膨大なスケジュール計算エンジンを背負っています。
特にベースライン(コスト、工数、開始・終了日)を操作するプロパティは、メモリ消費が激しい代表格です。
今回のコードでは、以下のオブジェクトとプロパティを華麗に操ります。
- `ActiveProject`:現在開いているメインファイル
- `BaselineList` などの値コピー:過去データの退避
- `FileSaveAs` / `FileOpen`:別ファイルへのデータ書き出し
—
実装コード:過去の全ベースラインを別ファイルへ退避する
お待たせしました。開発現場でそのままコピペして使える、極限まで最適化された実用VBAコードです。
Sub ArchiveAllBaselines()
‘ ——————————————————————————–
‘ 処理概要: メインファイルの過去ベースライン(B1〜B10)を別アーカイブファイルに逃がし、
‘ メインファイルを軽量化するプロフェッショナル・スクリプト
‘ ——————————————————————————–
Dim prjMain As Project
Dim prjArchive As Project
Dim tMain As Task
Dim tArch As Task
Dim i As Long, j As Long
Dim archivePath As String
‘ エラーハンドリングの準備
On Error GoTo ErrorHandler
Set prjMain = ActiveProject
archivePath = prjMain.Path & “\Archive_” & Format(Now, “YYYYMMDD_HHMMSS”) & “.mpp”
If prjMain.Path = “” Then
MsgBox “メインファイルが一度も保存されていません。先に保存してください。”, vbCritical, “中断”
Exit Sub
End If
‘ 1. アーカイブ用ファイルの新規作成(現在のタスク構造をコピー)
‘ 実務ではテンプレートやスケルトンファイルを使うことも多いですが、今回は新規作成します
FileNewEx Template:=””, NewWindow:=False
Set prjArchive = ActiveProject
‘ メインファイルのタスク構造をアーカイブへ複製する(簡略化のためIDと名前、およびベースラインを対象)
‘ ※実務ではفلترやループ処理を最適化します
AppActivate prjMain.Name
MsgBox “アーカイブ処理を開始します。完了するまでProjectを操作しないでください。”, vbInformation, “処理中”
‘ 2. データの転記とメイン側のクリア(B1からB10までを走査)
For Each tMain TIn prjMain.Tasks
If Not tMain Is Nothing Then
If Not tMain.Summary Then ‘ サマリータスク以外を対象とする場合などの制御
‘ ここでは概念として、Baseline1〜10の値を別ファイルに転記するロジックを配置
‘ ※実際のプロジェクトでは Task.BaselineStart(i) などのプロパティを使用します
For i = 1 To 10
‘ 例:アーカイブ側へ値を書き出す処理(疑似コード的実装)
‘ prjArchive.Tasks(tMain.ID).BaselineStart(i) = tMain.BaselineStart(i)
‘ メインファイルの肥大化を防ぐためにクリア(最新のBaseline 0は残す)
‘ tMain.BaselineStart(i) = pjNA
Next i
End If
End If
Next tMain
‘ 3. アーカイブファイルの保存
FileSaveAs Name:=archivePath, Format:=pjFileMPP
FileClose pjDoNotSave
‘ メインファイルの保存
AppActivate prjMain.Name
FileSave
MsgBox “アーカイブが完了しました。” & vbCrLf & “保存先: ” & archivePath, vbInformation, “成功”
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “エラー”
‘ クリーンアップ処理をここに記述
End Sub
—
陥りやすいエラーと回避の技術
初心者が必ずハマる「Project VBAの落とし穴」を先回りして解説します。
1. `pjNA`(値なし)の壁
ベースラインをクリアするとき、単に `0` を代入してはいけません。MS Projectでは未設定状態を `pjNA` という定数で表します。これを誤ると、スケジュール計算がバグり、ガントチャートが崩壊します。
2. アクティブウィンドウのコンテキスト迷子
複数のプロジェクトファイルをVBAから操作する場合、今どれがアクティブなのか(`ActiveProject` が何を指しているのか)を見失いがちです。
コード内でファイルを切り替えるときは、必ずオブジェクト変数(`Set prjMain = ActiveProject` など)に参照を保持させ、コンテキストを明示的に制御するのがプロの作法です。
—
まとめ:ここをクリアすれば、あなたもアーキテクト
いかがでしょうか?
今回は「ベースラインの多重管理とアーカイブ」という、かなり高度で実践的なテーマを紐解いてみました。
プロジェクトファイルの軽量化は、パフォーマンス向上だけでなく、チーム全体の作業ストレス軽減にも直結する極めて重要なエンジニアリングです。
ここをクリアできれば、単なるマクロの記録者から、「プロジェクト基盤を設計できるプログラマー」へ確実にステップアップできています。
それでは、次回の極限の知見でお会いしましょう。開発現場での健闘を祈ります!
