プロジェクトコスト予実管理の極致:VBAとSQL Serverを直結させるアーキテクチャの真髄
プロジェクト管理において、コストは「生き物」だ。単価(StandardRate)と実績工数の乖離をリアルタイムに把握できないシステムは、もはや死んでいるに等しい。
多くのエンジニアが「ProjectのGUIで手動入力する」という原始的な儀式に時間を溶かしているが、我々の領域ではそれは許されない。今回は、SQL Serverに蓄積されたリソース単価と実績データをVBAで吸い上げ、Projectのコストフィールドへ最短距離で書き戻す、堅牢かつ最適化された自動化アーキテクチャを提示する。
—
1. アーキテクチャの設計思想:なぜADOか
ADO(ActiveX Data Objects)を用いるのは、最もオーバーヘッドが少なく、メモリリークを制御しやすいためだ。DAOやODBC直叩きは、メモリ管理がブラックボックス化しやすく、大規模なリソーステーブルを扱う際に「沈黙のクラッシュ」を招くリスクがある。
パフォーマンスを極めるための鉄則
1. 明示的な接続解放: `Connection`および`Recordset`オブジェクトは、スコープを抜ける前に必ず`Nothing`を代入し、メモリプールを即時解放する。
2. サーバーサイドカーソルを避ける: 大量データを扱う際は、クライアントサイドカーソルでの静的アクセスを基本とし、ネットワーク往復回数を最小化する。
—
2. 実装:SQL Server連携からコスト書き込みまでの最適化コード
以下は、リソース単価を取得し、Projectの`Cost1`フィールドへ反映させるための堅牢なルーチンだ。
Option Explicit
‘ 伝説的なチーフの設計:リソース単価と実績を同期するエンジン
Public Sub SyncResourceCostData()
Dim conn As Object ‘ ADODB.Connection
Dim rs As Object ‘ ADODB.Recordset
Dim projRes As Resource
Dim strSQL As String
‘ 1. コネクションの確立(極力短期間で閉じる)
Set conn = CreateObject(“ADODB.Connection”)
conn.ConnectionString = “Provider=SQLOLEDB;Data Source=YOUR_SERVER;Initial Catalog=PMDB;Integrated Security=SSPI;”
conn.Open
‘ 2. 予実管理データの一括取得(単価と実績工数をJoin)
strSQL = “SELECT ResourceName, StandardRate, ActualWork FROM ResourceCostsView”
Set rs = conn.Execute(strSQL)
‘ 3. Projectオブジェクトの走査(イベント発生を抑制し高速化)
Application.ScreenUpdating = False
Do Until rs.EOF
On Error Resume Next
Set projRes = ActiveProject.Resources(rs.Fields(“ResourceName”).Value)
If Not projRes Is Nothing Then
‘ Cost1フィールドに実績コストを書き戻す(計算ロジックはここへ集約)
projRes.Cost1 = rs.Fields(“StandardRate”).Value rs.Fields(“ActualWork”).Value
End If
On Error GoTo 0
rs.MoveNext
Loop
‘ 4. 徹底したメモリ解放(これがシステムを安定させる鍵)
rs.Close: Set rs = Nothing
conn.Close: Set conn = Nothing
Set projRes = Nothing
Application.ScreenUpdating = True
MsgBox “コスト更新完了:予実乖離の同期が完了しました。”, vbInformation
End Sub
—
3. レガシー環境を生き抜くための「魔術」:Windows APIの活用
もし、SQL Serverとの接続でタイムアウトが頻発するような劣悪なネットワーク環境であれば、`Wininet.dll`の`InternetGetConnectedState`を叩き、通信の疎通確認をVBA側で先に行うべきだ。
また、大規模なProjectファイルで`ScreenUpdating`をオフにしてもなお重い場合は、`Application.Calculation = pjManual` を一時的に適用し、再計算のトリガーを完全に遮断せよ。Projectの計算エンジンは強力だが、書き込みのたびに全タスクを再計算する挙動は、数千行のプロジェクトでは致命的となる。
—
4. 運用上の注意:コストフィールドの「汚染」を防ぐ
Projectには`Cost`(標準機能)と`Cost1`〜`Cost10`(カスタムフィールド)がある。標準のコストフィールドは、Projectのスケジュールエンジンが自動計算するため、外部から書き込むと「計算の整合性」を破壊する可能性がある。
- 鉄則: 外部からインポートしたデータは必ず`Cost1`等のユーザー定義フィールドへ格納し、算出された差異のみをレポートさせること。
- 監査ログ: 誰が、いつ、どの値を書き換えたのかを記録するために、`Application_ProjectBeforeSave`イベントを活用し、ログ用のテーブルへ書き出す設計を推奨する。
—
結論:自動化は手段であり、目的ではない
このコードは強力だが、単なる「データ転送」に過ぎない。真の価値は、この数値を見てプロジェクトマネージャーが「いつ、どのリソースの単価を見直すべきか」という意思決定ができる環境を作ることにある。
VBAはレガシーと言われる。だが、Projectの内部データ構造をこれほど直接的に、かつ低コストでハックできる言語は他にない。メモリを管理し、リソースを解放し、OSの深淵を覗く。その姿勢こそが、我々エンジニアが守り抜くべき「職人芸」なのだ。
さあ、次は君の番だ。このスクリプトを組み込み、混沌とした予実の荒波を制御下に置け。
