【Project VBA極限攻略】保存時の整合性チェックで「ゴミデータ」の流入を物理的に遮断せよ
プロジェクト管理において、最も恐ろしいのは「データが正しく入力されていないこと」ではない。「不完全なデータが、さも完了したかのように保存され、後続のKPI集計を汚染すること」だ。
現場のPMがExcelのピボットテーブルで月次報告を作成する際、数件のタスクの「実績未入力」によって数字がズレる……この手戻りのコストを、君はいくらと見積もっている?
今日は、`BeforeSave`イベントを使い、プロジェクトファイルが保存される瞬間に「未完了タスク」を検知し、保存処理を強制キャンセルする「ガードレール」の実装を伝授する。
—
1. なぜ「運用ルール」ではなく「システム制御」が必要なのか
多くの現場では、「保存前に未入力がないか確認してください」という手順書を配布する。だが、信じてはいけない。人間は必ずミスをする。「システムが保存を拒絶する」という物理的な制限こそが、最高品質のデータを担保する唯一の手段だ。
非効率な設計の典型
- メッセージボックスを乱発する: ユーザーの作業フローを中断し、ストレスを与えるだけの設計。
- 保存後にチェックする: すでに汚染されたファイルが保存された後では遅い。
我々が目指すべきは、「不整合があるなら、そもそも外に出さない(保存させない)」という不可逆的な防御だ。
—
2. 実装の核心:`Project_BeforeSave` のフック
Project VBAにおいて、イベントを制御するには `ThisProject` モジュールを使う。ここでのポイントは、`Cancel` 引数を確実に制御することだ。
プロダクションコード:整合性ガードレール
以下のコードを `ThisProject` モジュールに配置せよ。
‘ ———————————————————
‘ Project_BeforeSave Event
‘ 整合性チェックを通過しない限り、保存を物理的に遮断する
‘ ———————————————————
Private Sub Project_BeforeSave(ByVal pj As Project, ByVal SaveAsUi As Boolean, Cancel As Boolean)
Dim tsk As Task
Dim errorCount As Long
‘ 監視対象:完了していないにも関わらず、実績コストが0のタスクを異常と見なす
‘ 実際の業務要件に合わせて条件式は拡張可能
errorCount = 0
For Each tsk In pj.Tasks
‘ 概要タスクは除外、かつ未完了のタスクを抽出
If Not tsk Is Nothing Then
If Not tsk.Summary Then
If tsk.PercentComplete < 100 Then
' ここで「本来あるべきはずの実績値」がないかチェック
If tsk.ActualWork = 0 Then
errorCount = errorCount + 1
End If
End If
End If
End If
Next tsk
' 整合性エラーがある場合の処理
If errorCount > 0 Then
‘ 保存処理をキャンセル(Cancel = True)
Cancel = True
MsgBox “【保存エラー】” & vbCrLf & _
“未入力のタスクが ” & errorCount & ” 件検出されました。” & vbCrLf & _
“実績を入力してから再度保存してください。”, vbCritical, “データ整合性チェック”
End If
End Sub
—
3. アーキテクトの視点:堅牢性を高める3つの鉄則
このコードをただコピペするだけでは、真のエンジニアとは言えない。現場で事故を起こさないための「深層の知見」を共有する。
1. 処理速度への配慮
`pj.Tasks` の全走査は、タスク数が多い大規模プロジェクトではパフォーマンスに影響する。もしタスクが数千件規模になるなら、フィルター機能(`TaskFilter`)や `Select` を使わず、オブジェクトへの直接アクセスを維持しつつ、不要なUI更新を避ける工夫が必要だ。
2. データベース連携時の落とし穴
もしこのプロジェクトファイルをSQL ServerやProject Onlineと同期させている場合、`BeforeSave` をキャンセルすると、サーバー側との同期プロセスも巻き込まれる。「どこまでがローカルの保存で、どこからがサーバーへのコミットか」の境界を意識し、同期エラー時に備えたログ出力(テキストファイルへの書き出しなど)を併用することを推奨する。
3. 保守性のための「例外設定」
現場からは必ず「緊急時には保存させてくれ」という声が上がる。その場合、環境変数や特定の隠しフラグ(例:`CustomField` に特定の文字列を入れた場合のみチェックをスキップする等)を設けるのがスマートだ。ただし、「その例外ログを誰が監視するか」というガバナンスとセットで実装すること。
—
最後に:ツールは「文化」を変える
コードを書くことは、単なる自動化ではない。組織の「データの扱い方」という文化を書き換える行為だ。
このガードレールを導入すれば、プロジェクトメンバーは「保存しようとすると怒られるから、先に入力しておこう」という思考に強制的にシフトする。これこそが、アーキテクトが提供すべき真の価値である。
君のビルドしたシステムが、今日もどこかの現場の「データ汚染」を未然に防いでいることを願う。実装で詰まったら、またここへ戻ってきなさい。
