プロジェクトの「保存」を武器にせよ:BeforeSaveイベントによる堅牢なデータガバナンス
Project VBAを扱う多くの開発者は、`ThisProject`オブジェクトの存在を知っているだけで満足している。しかし、真のアーキテクトは「保存」という不可逆なアクションを、システム整合性を担保するための最後の砦として定義する。
今回は、単なる入力チェックを超え、プロジェクトのデータ整合性を極限まで高める`ProjectBeforeSave`イベントの設計術を伝授する。
—
1. イベントハンドラの「正しき定義」とメモリの深淵
VBAにおいて、`Class Module`を活用したイベントフックは基本だが、プロジェクトのライフサイクルを制御する場合、`ThisProject`モジュールでの実装が定石だ。しかし、ここでメモリリークや未定義の挙動を避けるための「シニアの嗜み」を忘れてはならない。
`ProjectBeforeSave`イベントは、保存がキャンセル可能であるという点において、非常に強力なフックポイントである。
‘ ThisProject モジュールに記述
Private Sub Project_BeforeSave(ByVal pj As Project, ByVal SaveAs As Boolean, Cancel As Boolean)
‘ メモリ最適化:オブジェクト参照はスコープを限定し、明示的にNothingを代入する
Dim task As Task
‘ 整合性チェックの実行
If Not ValidateProjectData(pj) Then
‘ 保存の強制キャンセル。警告を出しユーザーの修正を促す
MsgBox “データ整合性エラー:保存を中断しました。”, vbCritical, “Project Validator”
Cancel = True
End If
Set task = Nothing
End Sub
2. 工数不整合を許さない:データ整合性エンジンの実装
単なるフィールドチェックでは、Projectの多階層構造(WBS)には太刀打ちできない。重要なのは「計算結果の矛盾」を検知することだ。
以下のコードは、全タスクを走査し、親タスクと子タスクの工数に乖離がないかを検証する実用的なロジックである。
Private Function ValidateProjectData(ByVal pj As Project) As Boolean
Dim t As Task
Dim isOk As Boolean: isOk = True
‘ プロジェクトの最適化:画面更新を止める等の制御は不要だが、
‘ 大規模プロジェクトではCPUサイクルを占有するため注意が必要
For Each t In pj.Tasks
If Not t Is Nothing Then
‘ 必須項目:開始日・終了日・リソース割当のチェック
If t.Start = “NA” Or t.Finish = “NA” Then
isOk = False
Exit For
End If
‘ 階層構造の整合性チェック(カスタムロジック例)
If t.Summary = False And t.Work = 0 Then
‘ 工数未入力のタスクはエラーとみなす
isOk = False
Exit For
End If
End If
Next t
ValidateProjectData = isOk
End Function
3. Windows APIを駆使した「強制的な通知」
標準の`MsgBox`では、重要プロジェクトにおける保存失敗の深刻度が伝わらないことがある。Windows APIの`FlashWindowEx`を呼び出し、タスクバーを強制的に点滅させることで、ユーザーの注意を確実に引く。これが「システム管理者としての責務」を果たすための細部だ。
‘ API宣言は標準モジュールへ
Private Declare PtrSafe Function FlashWindowEx Lib “user32” (pfwi As FLASHWINFO) As Boolean
Private Type FLASHWINFO
cbSize As Long
hwnd As LongPtr
dwFlags As Long
uCount As Long
dwTimeout As Long
End Type
‘ 呼び出し時はウィンドウハンドル(Application.hWndAccessApp)を渡す
4. シニアエンジニアが守るべき3つの鉄則
1. 非同期処理を避ける: 保存イベント内での長時間処理は、Projectのフリーズを招く。チェック処理は軽量化を徹底し、複雑な計算は別プロセスのバッチ処理に委ねよ。
2. エラーハンドリングの徹底: `On Error GoTo`は必須だ。イベントハンドラ内で例外が発生すると、プロジェクトが保存不能になるという致命的なリスクを伴う。
3. レガシー環境への配慮: 32bit/64bit Officeの混在環境が現場では当たり前だ。`PtrSafe`属性と`LongPtr`型の利用を怠れば、システムは一瞬で崩壊する。
結論:技術は「守り」のためにある
コードを自動化するだけなら、誰にでもできる。しかし、Projectという「組織の意思決定の源泉」を守るために、保存というプロセスに介入し、エラーを握りつぶす。これこそが、VBAを極めたエンジニアにしか許されない、コードによる「統治」である。
君たちが書くコードは、単なるスクリプトではない。プロジェクトの健全性を守るためのアーキテクチャそのものであることを忘れてはならない。
