【入門編】【上級者向け】プロジェクトのベースライン設定履歴を専用の管理DBへ蓄積する監査ログ機能 – Project VBA解析バイブル

スポンサーリンク

こんにちは!プロジェクトマネジメントの現場で、スケジュール変更の履歴や「誰がいつベースラインを引いたのか」が分からなくて困った経験はありませんか?

「マクロの記録」から一歩抜け出して、現場のガバナンスを強固にする仕組みを作りたいあなたへ。今回は、「プロジェクトのベースライン設定履歴を専用の管理DBへ蓄積する監査ログ機能」という、実務で即戦力になる高度なテーマを一緒に紐解いていきましょう。

ここをクリアすれば、単なるVBAの自動化を超えて、「組織のプロジェクト資産を守るアーキテクト」としての視点が手に入ります。優しく、そして本質的に解説していくので、安心してついてきてくださいね!

1. なぜベースラインの監査ログが必要なのか?

プロジェクト管理において、ベースライン(計画値)は「進捗遅延やコスト超過を測るための絶対的な基準」です。しかし、現場ではこんなことがよく起きます。

  • 「気づいたら勝手にベースラインが上書きされていて、当初の遅延が見えなくなっている…」
  • 「誰がこのスケジュール変更を承認したんだっけ?」

こうしたガバナンスの崩壊を防ぐため、「いつ、誰が、どのベースライン(Baseline〜Baseline10)を設定したか」を、Microsoft Projectの内部だけでなく、外側の専用データベース(今回は軽量なAccess、またはSQL Serverを想定)に自動で記録する仕組みを作ります。

2. Project VBAのイベント駆動とオブジェクトのライフサイクル

今回の肝となるのは、「いつその処理を走らせるか」です。
実は、MS Projectには、ユーザーが操作を行った瞬間に割り込んで処理を実行できる「イベント(Event)」という強力な仕組みが備わっています。

しかし、ここで注意が必要です。Excel VBAと違い、Project VBAではイベントをフックするために「クラスモジュール」という少し高度な仕組みを使う必要があります。

全体のアーキテクチャ

1. AppClass(クラスモジュール): Projectのイベント(ベースライン設定など)を監視。
2. Auto_Open(標準モジュール): Projectファイルを開いた瞬間に、監視クラスをアクティブ化。
3. LogToDatabase(標準モジュール): 取得したメタデータ(日時、ユーザー名、プロジェクト名)を外部DBへINSERT。

3. 実装コード:監査ログシステムの構築

それでは、実際に開発現場でそのままコピペして使えるコードを書いていきましょう。

ステップ1:イベントを捉えるクラスモジュールの作成

VBE(Visual Basic Editor)を開き、`挿入` > `クラス モジュール` を選択します。プロパティウィンドウで名前を `AppClass` に変更してください。

‘ =================================ワイズマンのクラス設計 =================================
‘ クラス名: AppClass
‘ 役割: MS Project全体のアプリケーションイベントをフックする
‘ ========================================================================================
Public WithEvents MSProjectApp As MSProject.Application

‘ ベースラインが保存(設定)される直前・直後に割り込むイベント
Private Sub MSProjectApp_ProjectBeforeBaselineSave(ByVal pj As Project, ByVal WhichBaseline As PjBaseline)
On Error GoTo ErrorHandler

Dim logUser As String
Dim logTime As Date
Dim baselineName As String

‘ 1. メタデータの収集
logUser = Environ(“USERNAME”) ‘ Windowsのログインユーザー名
logTime = Now ‘ 現在時刻
baselineName = GetBaselineNameString(WhichBaseline) ‘ 列挙体を文字列に変換

‘ 2. 専用管理DBへログを書き込むプロシージャを呼び出し
Call WriteAuditLogToDatabase(pj.Name, baselineName, logUser, logTime)

Exit Sub

ErrorHandler:
MsgBox “監査ログの記録中にエラーが発生しました: ” & Err.Description, vbCritical, “ガバナンス警告”
End Sub

‘ 略称のPjBaseline列挙体を人間が読める文字列に変換するヘルパー関数
Private Function GetBaselineNameString(ByVal wb As PjBaseline) As String
Select Case wb
Case pjBaseline: GetBaselineNameString = “Baseline”
Case pjBaseline1 To pjBaseline10: GetBaselineNameString = “Baseline ” & CStr(wb – pjBaseline + 1)
Case Else: GetBaselineNameString = “Unknown Baseline”
End Function
End Function

ステップ2:イベントを有効化する標準モジュール

次に、通常標準モジュール(`挿入` > `標準モジュール`)を追加し、プロジェクト起動時にクラスをフックするコードを書きます。名前は `basInitializer` とします。

‘ ========================================================================================
‘ 標準モジュール: basInitializer
‘ 役割: アプリケーション起動時にイベント監視をスタートさせる
‘ ========================================================================================
Public myAppEvents As AppClass

Sub Auto_Open()
‘ クラスのインスタンスを生成し、ProjectのApplicationオブジェクトを紐付ける
Set myAppEvents = New AppClass
Set myAppEvents.MSProjectApp = MsProject.Application

‘ デバッグ用(現場ではコメントアウト推奨)
‘ Debug.Print “Project Baseline 監査ログシステムが正常にロードされました。”
End Sub

ステップ3:外部DB(またはログファイル)へ永続化する処理

実務ではここにADO(ActiveX Data Objects)を使ってSQL ServerやAccessのDBへ接続するコードを記述します。今回は分かりやすく、ローカルのCSVや監査用データベーステーブルへ書き込むイメージのプロシージャを配置します。

‘ ========================================================================================
‘ 標準モジュール: basDatabaseManager
‘ 役割: 収集した監査ログを永続化ストレージへ書き込む
‘ ========================================================================================
Public Sub WriteAuditLogToDatabase(projectName As String, baselineName As String, userName As String, logTime As Date)

Dim conn As Object
Dim sql As String
Dim dbPath As String

‘ ※実運用では組織内の共有データベースパスを指定してください
dbPath = “C:\ProjectGovernance\AuditLogs.accdb”

On Error GoTo DBError

‘ ADOを用いたデータベース接続(例: Microsoft Access Database)
Set conn = CreateObject(“ADODB.Connection”)
conn.Open “Provider=Microsoft.ACE.OLEDB.12.0;Data Source=” & dbPath & “;”

‘ SQLインジェクション等を防ぐため、パラメータクエリを使うのがベストプラクティスですが、
C
sql = “INSERT INTO T_BaselineAudit (ProjectName, BaselineType, ModifiedBy, ModifiedDate) VALUES (” & _
“‘” & Replace(projectName, “‘”, “””) & “‘, ” & _
“‘” & baselineName & “‘, ” & _
“‘” & userName & “‘, ” & _
“#” & Format(logTime, “yyyy/mm/dd hh:nn:ss”) & “#);”

conn.Execute sql
conn.Close

Set conn = Nothing
Exit Sub

DBError:
‘ データベース障害でプロジェクト自体の保存や操作を妨げないよう、エラーはログに留めるかトースト通知にする
MsgBox “監査DBへの書き込みに失敗しました。IT管理者へ連絡してください。” & vbCrLf & “エラー内容: ” & Err.Description, vbExclamation
If Not conn Is Nothing Then
If conn.State = 1 Then conn.Close
Set conn = Nothing
End If
End Sub

4. 陥りやすい罠とエンジニアの知恵袋

Project VBAを実務に導入する際、初心者が必ずと言っていいほどハマる「罠」があります。ここを知っておくだけで、開発スピードが何倍も変わりますよ。

1. 「イベントが急に動かなくなった!」現象

  • 原因: VBAのエラーハンドリング中で `End` ステートメントを使用したり、予期せぬエラーでコードが強制終了すると、`WithEvents` のリンク(メモリ上の参照)が切断されます。
  • 対策: 運用時は必ずリボンに「監査システム再初期化ボタン(`Auto_Open`をマニュアル実行するマクロ)」を配置しておきましょう。

2. セキュリティセンターの設定

  • 原因: 組織のセキュリティポリシーでマクロが無効化されている、または「VBA プロジェクト オブジェクト モデルへのアクセスを信頼する」にチェックが入っていないと動きません。
  • 対策: グループポリシー(GPO)等で信頼できる場所(Trusted Locations)をあらかじめ設定しておく必要があります。

最後に:ここをクリアすれば、基本はバッチリです!

お疲れ様でした!今回は「イベント駆動」「クラスモジュール」「外部データベース連携」という、Project VBAにおける最上位のテクニックを組み合わせた監査ログ機能を見てきました。

「ただ自動化するマクロ」から、「企業のプロセスやデータを守るエンジニアリング」へ。この視点を持てたあなたなら、どんな巨大なプロジェクトの自動化要求が来ても、自信を持ってエレガントに解決できるはずです。

もし実装でつまづいたり、「こういう場合はどう書けばいい?」といった疑問があれば、いつでも先輩エンジニアに聞いてくださいね。あなたのVBAライフを、心から応援しています!

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