【入門編】【上級者向け】Project VBAにおける「Undo(元に戻す)」スタックの制御とトランザクション管理の極意 – Project VBA解析バイブル

スポンサーリンク

こんにちは。Project VBAの世界へようこそ。
私は長年、数万タスクに及ぶ巨大な社会インフラプロジェクトの工程管理を、プログラムの力で支えてきたチーフアーキテクトです。

あなたが今、この記事を読んでいるということは、マクロの記録から一歩踏み出し、「いかにして安全かつ確実に、スケジュールをプログラムで制御するか」という、エンジニアとしての重要な分岐点に立っているということですね。

今日は、Project VBAにおける「Undo(元に戻す)」の制御と、擬似的な「トランザクション管理」という、上級者への登竜門とも言えるテーマについてお話ししましょう。

ここをマスターすれば、あなたの書くコードは「ただ動くマクロ」から「プロが信頼を置くシステム」へと進化します。準備はいいですか?

—

なぜProject VBAで「Undo」を気にする必要があるのか?

Excel VBAとの決定的な違い、それは「スケジュールの連鎖反応」にあります。

Microsoft Projectは、一つのタスクの開始日を変えるだけで、依存関係(プレデシッサ)を通じて数千のタスクが自動計算される「巨大な計算機」です。
もし、マクロが途中でエラーを起こして止まってしまったらどうなるでしょうか?

  • 一部のタスクだけ期間が変わっている
  • 依存関係が中途半端に切れている
  • どこの設定が書き換わったのか、もう誰も分からない

こうなると、ユーザーは「Ctrl + Z(元に戻す)」を何度も連打することになりますが、VBAの処理内容によってはUndoスタックが壊れたり、そもそも戻せなかったりすることもあります。

「失敗したら、実行前の状態に完璧に戻す」
この「トランザクション」の考え方をProject VBAに持ち込むことが、本記事のゴールです。

—

1. 処理を「一つの塊」としてUndoに登録する

通常、マクロで100個のタスクを操作すると、ProjectのUndo履歴には100個の項目が並んでしまいます。これではユーザーは混乱します。

Project VBAには、複数の操作を一つの「Undo名」としてまとめる直接的なコマンド(Excelの`Application.OnUndo`のようなもの)は存在しません。しかし、「一括処理(トランザクション)」の考え方を取り入れるための定石があります。

画面更新と再計算の停止(パフォーマンスと整合性のキモ)

大規模なWBS操作を行う際は、まず「Projectの脳」を一時的に静かにさせます。

‘ 描画と計算を止めることで、Undoスタックへの過度な負荷を減らし、速度を上げます
Application.ScreenUpdating = False
Application.Calculation = pjManual

—

2. 実践:トランザクション管理のテンプレート

エラーが発生した際に「何もしない」のではなく、「どこまでやったか」を意識した設計にします。
以下に、プロが現場で使う「安全な一括更新」の構造を示します。

Sub SafeWBSUpdate()
Dim ts As Tasks
Dim t As Task
Dim isSuccess As Boolean

‘ 1. 事前準備:エラーハンドリングの設定
On Error GoTo ErrorHandler
isSuccess = False

‘ 2. 環境の最適化
‘ 画面更新を止め、手動計算モードへ。これが「トランザクション開始」の合図です。
Application.ScreenUpdating = False
Application.Calculation = pjManual

‘ — ここからメイン処理 —
‘ 例:全タスクの依存関係を再構築するような重い処理
Set ts = ActiveProject.Tasks
For Each t In ts
If Not t Is Nothing Then
‘ ここで複雑なロジックを実行
‘ 例: t.LinkPredecessors …
End If
Next t
‘ — ここまでメイン処理 —

‘ すべて成功したらフラグを立てる
isSuccess = True

CleanExit:
‘ 3. 後処理:環境を元に戻す
Application.Calculation = pjAutomatic
Application.ScreenUpdating = True

If isSuccess Then
MsgBox “プロジェクトの更新が正常に完了しました。”, vbInformation
Else
MsgBox “エラーが発生したため、処理を中断しました。整合性を確認してください。”, vbExclamation
End If
Exit Sub

ErrorHandler:
‘ 4. エラー時の振る舞い
‘ 本当は「Application.EditUndo」を呼びたいところですが、
‘ VBAの実行エラー直後はUndoが効かない場合があるため、
‘ 重大な処理の前には「保存」を促すか、バックアップを取るのがプロの流儀です。
Debug.Print “Error: ” & Err.Description
Resume CleanExit
End Sub

—

3. 【深掘り】Undoスタックを汚さないための「依存関係」設定の極意

Project VBAで最もエラーが起きやすく、Undoを壊しやすいのが「タスクの依存関係(Dependencies)」の設定です。

初心者が陥りやすい罠は、`Task.Predecessors = “1,2”` のように文字列で直接流し込むことです。これはProject内部のパース(解析)処理を走らせるため、非常に重く、またエラー時に追跡が困難です。

解決策:TaskDependenciesコレクションを使う

より堅牢な(=Undoスタックに優しい)方法は、オブジェクトを直接操作することです。

プロのテクニック:依存関係の安全な追加

Sub AddDependencySafely(targetTask As Task, fromTask As Task)
On Error Resume Next
‘ すでにリンクがある場合はエラーになるため、安全に追加する
targetTask.TaskDependencies.Add From:=fromTask, Type:=pjFinishToStart
If Err.Number <> 0 Then
‘ 循環参照などのエラーをキャッチできる
Debug.Print “リンク失敗: ” & fromTask.Name & ” -> ” & targetTask.Name
End If
On Error GoTo 0
End Sub

—

4. ユーザーへの究極の優しさ:実行前の「スナップショット」

Projectには「チェックポイント」機能がありません。そのため、大規模な自動設定(WBSの全入れ替えなど)を行う際は、マクロの冒頭で「バックアップ(別名保存)」を自動で行う仕組みを組み込むことがあります。

これが、私が「伝説のアーキテクト」と呼ばれる所以の一つ、「戻せないなら、戻れる場所を自動で作っておく」という発想です。

Sub ExecuteMassiveChangeWithBackup()
‘ 処理前に現在の状態を一時ファイルとして保存
Dim backupPath As String
backupPath = Environ(“TEMP”) & “\Project_Backup_” & Format(Now, “yyyymmdd_hhnnss”) & “.mpp”

ActiveProject.SaveAs Name:=backupPath

‘ ここでメイン処理を実行…
‘ もし失敗したら、ユーザーに「TEMPフォルダのバックアップを開いてください」とガイドする
End Sub

—

まとめ:Project VBAを掌握するために

Project VBAの基本をマスターするとは、単にメソッドを覚えることではありません。
「Projectの再計算エンジンと、どう折り合いをつけるか」を知ることです。

1. 静止させる: `ScreenUpdating` と `Calculation` を制御する。
2. 型を守る: `Predecessors` 文字列ではなく、オブジェクト操作を行う。
3. 出口を確保する: `On Error GoTo` で必ず計算モードを元に戻す。

この3点を守るだけで、あなたのマクロの信頼性は劇的に向上します。
「ここをクリアすれば、Project VBAの基本はバッチリですよ」と自信を持って言える、そんなエンジニアへの第一歩を、今日あなたは踏み出しました。

次は、タスクの「アウトラインレベル(階層構造)」を動的に制御するテクニックでお会いしましょう。あなたのコードが、美しいスケジュールを紡ぎ出すことを願っています。

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