【Project VBAを掌握する極限の知見】Active Directory直結:リソースの「コストセンター」自動同期アーキテクチャ
開発プロジェクトのリーダーたるもの、リソース管理における「コストセンター(部署情報)」のメンテナンス地獄にいつまでも付き合ってはならない。
組織変更、人事異動、新規アサイン。その度にMicrosoft Project(以下、MSP)のリソースプールを開き、手作業でコストセンターや部署名をポチポチと入力する……。そんな前時代的な作業は、エンジニアのリソースの無駄遣いだ。人間がやるべき仕事ではない。
今回は、VBAとVBScript(ADSI)を巧みに組み合わせ、Active Directory(AD)から最新の組織情報を直接吸い上げ、MSPのリソースカスタムフィールドへ完全自動同期するプロダクション品質の連携スクリプトを伝授する。
「なぜ手動更新がリスクなのか」「VBA単体ではなぜADを叩けないのか」というアーキテクチャの急所を押さえつつ、明日から現場でそのまま使える堅牢なコードを公開しよう。
—
1. なぜ「手動更新」と「VBA単体のADアクセス」は悪手なのか?
実務でよくある失敗パターンを先に叩いておく。
罠その1:リソース情報の属人化と陳腐化
プロジェクトマネージャーがExcelやMSPに手動でコストセンターを入力している現場では、必ず情報が古びる。監査の際、「このリソースの原価はどの部署に帰属するのか」を追跡できず、プロジェクトの収支管理が崩壊する原因となる。
罠その2:VBAから直接Active Directory(ADSI/LDAP)を叩く愚行
「VBAの `CreateObject(“ADODB.Connection”)` や `GetObject(“LDAP://…”)` を使えばVBAだけで完結するのでは?」と思ったそこのあなた。甘い。
Office 365環境やモダンなセキュリティポリシーが適用されたセキュアな企業ネットワークにおいて、VBAから直接LDAPクエリを投げると、セキュリティソフトの検知、認証エラー、あるいはタイムアウトによるExcel/MSPのフリーズを引き起こす確率が跳ね上がる。
【極限の解】VBScriptを仲介させたプロセス分離アーキテクチャ
堅牢性を極めるプロは、VBAから直接外部ネットワークやOS基盤へ重い処理を投げない。
「VBAからAD検索用のVBScriptを動的に生成・実行し、その標準出力(または一時ファイル)をVBAが安全に回収する」という、プロセス分離モデルを採用する。これにより、MSPのセッションを守りつつ、確実かつ高速なAD連携を実現できる。
—
2. 全体アーキテクチャと実装のポイント
今回構築する仕組みの流れはこうだ。
1. MSP側(VBA): リソースプールから登録されているリソースの「氏名」または「メールアドレス」を抽出。
2. 仲介側(VBScript): VBAから渡された識別子をもとに、Active Directory(LDAP)へバインドし、`department`(部署)や `co`(コストセンター属性)を安全に取得。
3. MSP側(VBA): 取得した文字列を、MSPのリソースカスタムフィールド(例:`Text1` や `CostCenter`)へ書き込む。
この一連の流れを、エラーハンドリングを網羅したプロダクションコードとして実装する。
—
3. 実装コード:完全自動同期モジュール
以下のコードを、Microsoft ProjectのVBE(Visual Basic Editor)の標準モジュールにそのまま貼り付けてほしい。
プロダクション・VBAコード
Option Explicit
‘ ==============================================================================
‘ 処理名 : SyncResourceCostCenterFromAD
‘ 概要 : Active Directoryからリソースの部署・コストセンター情報を取得し、
‘ MSPのリソースカスタムフィールド(Text1)へ自動同期する。
‘ 前提 : MSPのリソースシートに「名前」または「電子メール」が入力されていること。
‘ ==============================================================================
Public Sub SyncResourceCostCenterFromAD()
Dim res As Resource
Dim wscriptPath As String
Dim tempFile As String
Dim fso As Object
Dim ts As Object
Dim shell As Object
Dim ldapAccount As String
Dim costCenterInfo As String
Dim updatedCount As Long
On Error GoTo ErrorHandler
‘ 実行確認
If ActiveProject.Resources.Count = 0 Then
MsgBox “リソースが登録されていません。”, vbExclamation, “AD同期エラー”
Exit Sub
End If
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set shell = CreateObject(“WScript.Shell”)
‘ 一時VBScriptファイルのパスを生成(ユーザーのテンポラリフォルダを利用)
tempFile = fso.GetSpecialFolder(2) & “\GetADInfo_” & Format(Now, “yyyymmddhhmmss”) & “.vbs”
updatedCount = 0
‘ プロジェクト内の全リソースを走査
For Each res In ActiveProject.Resources
‘ リソースが有効(名前が存在し、コストリソース等ではない一般リソース)か判定
If Not res Is Nothing Then
If res.Name <> “” And res.Type = pjResourceTypeCodeWork Then
‘ ここではリソースの「電子メール(Email Address)」をAD検索のキーとする
‘ ※メールアドレスがない場合は「名前(Name)」をCN/DisplayNameとして検索するロジックに変更可能
ldapAccount = res.EmailAddress
If ldapAccount <> “” Then
‘ 1. ADから情報を取得するためのVBScriptを動的生成
Call GenerateVBScript(tempFile, ldapAccount)
‘ 2. VBScriptを実行し、結果を一時テキストファイルに出力させる
Dim resultFile As String
resultFile = fso.GetSpecialFolder(2) & “\ADResult.txt”
‘cscriptでバッチ実行(ウィンドウを非表示にするため 0, True)
shell.Run “cscript //nologo ” & Chr(34) & tempFile & Chr(34) & ” > ” & Chr(34) & resultFile & Chr(34), 0, True
‘ 3. 結果ファイルからコストセンター情報を読み取る
If fso.FileExists(resultFile) Then
Set ts = fso.OpenTextFile(resultFile, 1)
If Not ts.AtEndOfStream Then
costCenterInfo = Trim(ts.ReadAll)
End If
ts.Close
‘ 4. MSPのリソースカスタムフィールド(Text1)に書き込み
If costCenterInfo <> “” And costCenterInfo <> “NOT_FOUND” Then
‘ Text1をコストセンター格納先として利用
res.Text1 = costCenterInfo
updatedCount = updatedCount + 1
End If
‘ 結果ファイルを削除
fso.DeleteFile resultFile, True
End If
‘ 一時VBScriptを削除
If fso.FileExists(tempFile) Then fso.DeleteFile tempFile, True
End If
End If
End If
Next res
MsgBox “Active Directoryとの同期が完了しました。” & vbCrLf & _
“更新されたリソース数: ” & updatedCount & ” 件”, vbInformation, “同期完了”
CleanUp:
On Error Resume Next
If fso.FileExists(tempFile) Then fso.DeleteFile tempFile, True
Set ts = Nothing
Set fso = Nothing
Set shell = Nothing
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“Error: ” & Err.Description, vbCritical, “致命的エラー”
Resume CleanUp
End Sub
‘ ==============================================================================
‘ 補助プロシージャ : AD検索用VBScriptの動的生成
‘ ==============================================================================
Private Sub GenerateVBScript(ByVal filePath As String, ByVal email As String)
Dim fso As Object
Dim ts As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set ts = fso.CreateTextFile(filePath, True, False) ‘ ASCII形式で出力
‘ VBScriptのコードを記述(ADSIを用いたLDAP検索)
ts.WriteLine “On Error Resume Next”
ts.WriteLine “Dim conn, cmd, rs”
ts.WriteLine “Set conn = CreateObject(“”ADODB.Connection””)”
ts.WriteLine “Set cmd = CreateObject(“”ADODB.Command””)”
ts.WriteLine “conn.Provider = “”ADsDSOObject”””
ts.WriteLine “conn.Open “”Active Directory Provider”””
ts.WriteLine “Set cmd.ActiveConnection = conn”
‘ メールアドレスをキーにしてActive Directoryを検索(department属性を取得例とする)
ts.WriteLine “cmd.CommandText = “”
ts.WriteLine “Set rs = cmd.Execute”
ts.WriteLine “If Not rs.EOF Then”
ts.WriteLine ” WScript.Echo rs.Fields(0).Value”
ts.WriteLine “Else”
ts.WriteLine ” WScript.Echo “”NOT_FOUND”””
ts.WriteLine “End If”
ts.WriteLine “rs.Close”
ts.WriteLine “conn.Close”
ts.Close
Set ts = Nothing
Set fso = Nothing
End Sub
—
4. 現場のリーダーが知るべき実装上の注意点
このコードを実務環境(エンタープライズ・ネットワーク)に投入する際、インフラ担当者やセキュリティ部門から突っ込まれそうなポイントをあらかじめ解説しておく。
1. 実行権限とネットワークトポロジ
当然ながら、このスクリプトを実行するクライアント端末が、社内のActive Directoryドメインコントローラー(DC)と通信できる環境(社内LANまたはセキュアなVPN接続下)にあることが大前提となる。Azure AD(Microsoft Entra ID)環境の場合は、Microsoft Graph API等へのシフトを検討すべきだが、オンプレミスAD / Hybrid AD環境であれば、このLDAPクエリ方式が最も確実で高速に動作する。
2. 属性マッピングのカスタマイジング
社内規定のADスキーマにおいて、「コストセンター」が標準の `department` 属性に入っているか、あるいは拡張属性(`extensionAttribute1` や `costCenter` など)に格納されているかは組織によって異なる。
VBScript生成部分(`GenerateVBScript`内の `cmd.CommandText`)の検索フィールド部分を、自社のスキーマに合わせて書き換えるだけで、あらゆる要件に対応可能だ。
3. MSPのカスタムフィールド設計のベストプラクティス
今回は簡便のためリソースの `Text1` フィールドをコストセンターの格納先としたが、本格運用する際はMSP側のリソースカスタムフィールドの名称を「コストセンター」に変更し、エンタープライズリソースプール(ERP)全体でグローバルに定義することを強く推奨する。
—
5. おわりに
ツール開発の本質は、「人間が手作業で行う苦痛をコードで完全に駆逐すること」に他ならない。
リソースのコストセンター同期を自動化すれば、組織変更のたびにPMが頭を悩ませる時間はゼロになり、プロジェクト原価管理の精度は劇的に向上する。
「なぜ自動化できるのに手動でやっているのか?」——その疑問を常に持ち続け、現場のシステムを自らの手でアグレッシブにハックし続けてほしい。
