【テクニカル・上級編】【中級者向け】プロジェクト保存時の整合性チェック:保存前にタスクの未完了を確認する – Project VBA解析バイブル

スポンサーリンク

プロジェクトの「整合性」を殺すな:BeforeSaveイベントによる鉄壁のガードレール実装

Project VBAを扱うエンジニア諸君。君たちのプロジェクトファイルは「生きたデータ」か、それとも単なる「ゴミの集積場」か。

プロジェクトマネジメントにおいて、保存操作は単なるデータの永続化ではない。それは「現在のプロジェクトの状態を確定させる」という、極めて重大なコミットメントだ。しかし、現場では平然と「未完了タスクが残ったまま」「ベースラインが乖離したまま」の状態で保存され、翌朝の進捗会議で悲劇が繰り返される。

今日は、MS Projectのイベントドリブン構造を逆手に取り、データ品質を強制的に担保する「BeforeSave」の極致を伝授する。

なぜ「BeforeSave」でなければならないのか

通常の保存ボタンが押された瞬間、Projectはメモリ上の状態を物理ファイルへ書き出す準備に入る。この「書き出し直前」のフックポイントこそが、システム管理者にとっての聖域だ。

ここで処理を割り込めば、「不完全なデータの保存を物理的に遮断」できる。警告メッセージを出すだけのアマチュア的な実装は捨てろ。`Cancel = True` を叩き込み、プロセスを中断させる。これが真のガードレールだ。

実装:ProjectBeforeSave イベントの核心

以下のコードは、`ThisProject` モジュールに記述することで機能する。ここで重要なのは、単なるチェックではなく、COMオブジェクトのライフサイクル管理と、意図しないメモリリークの排除だ。

‘ ThisProject モジュールに配置
Private Sub Project_BeforeSave(ByVal pj As Project, ByVal SaveAsUi As Boolean, Cancel As Boolean)
‘ メモリ最適化と堅牢性のためのオブジェクト参照
Dim tsk As Task
Dim isInvalid As Boolean: isInvalid = False

‘ プロジェクトの整合性チェックロジック
‘ ここでは「未完了かつ期限を過ぎたタスク」を保存拒否のトリガーとする
For Each tsk In pj.Tasks
If Not tsk Is Nothing Then
‘ サマリタスクを除外する等のビジネスロジックはここで厳密に定義する
If Not tsk.Summary Then
If tsk.PercentComplete < 100 And tsk.Finish < Now() Then isInvalid = True Exit For End If End If End If Next tsk ' 整合性違反時のガードレール実行 If isInvalid Then ' Windows API経由での警告音出力(要: User32.dll) ' GUIの単なるメッセージボックス以上の緊急性をオペレーターに伝える Call MessageBeep(0) MsgBox "【警告】プロジェクトの整合性が崩れています。" & vbCrLf & _ "未完了の遅延タスクが存在するため、保存をキャンセルしました。" & vbCrLf & _ "進捗を更新するか、ベースラインを再設定してください。", vbCritical, "システム統合ガードレール" ' 核心部:保存処理の物理的遮断 Cancel = True End If ' 明示的なオブジェクト解放(VBAにおいては重要ではないが、大規模開発時の習慣として推奨) Set tsk = Nothing End Sub

チーフアーキテクトの視点:極限のチューニング

1. Windows APIによる「強制力」

単なる `MsgBox` だけでは、忙しい管理者はEnterキーを連打して無視するだろう。`User32.dll` の `MessageBeep` を組み合わせることで、OSレベルの警告音を鳴らし、意識的な中断を強いる。

If VBA7 Then
Private Declare PtrSafe Function MessageBeep Lib “user32” (ByVal uType As Long) As Long
Else
Private Declare Function MessageBeep Lib “user32” (ByVal uType As Long) As Long
End If

2. メモリとパフォーマンスの境界線

`For Each tsk In pj.Tasks` は、タスク数が数千件規模になるとパフォーマンスのボトルネックになる。数万件規模のエンタープライズ・プロジェクトであれば、`pj.Tasks` を直接回すのではなく、Filterオブジェクトを一時的に生成し、該当するタスクのみを抽出してループさせるべきだ。

3. システム間連携の罠

このガードレールを導入すると、外部のバッチスクリプト等から「自動保存」を行っている場合にエラーが発生する可能性がある。その場合は `SaveAsUi` 引数を判定し、手動操作時のみチェックを走らせる、あるいは特定のアカウント(サービスアカウント)時にはチェックをバイパスする等のロジックを必ず組み込め。

最後に:自動化とは「制約」である

自動化とは、自由を与えることではない。「正しい状態」以外を許容しないための制約を与えることだ。

Project VBAを操る者は、単に自動で動くコードを書くのではなく、プロジェクトという巨大な生体を守るための「規律」をコードに落とし込まなければならない。このガードレールを実装した瞬間から、君のプロジェクトデータは「ゴミの山」から「信頼できる経営資産」へと昇華されるはずだ。

妥協のないコードを、書け。

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