【テクニカル・上級編】【上級者向け】Project Server/Online環境におけるチェックアウト・チェックインのAPI制御 – Project VBA解析バイブル

スポンサーリンク

孤高のアーキテクトが説く、Project Online/Serverにおける「チェックアウトの呪縛」を解く極意

Project Online(PWA)環境でVBAを使い、プロジェクトを自動制御しようとした際、多くのエンジニアが「読み取り専用でしか開けない」「他のユーザーがチェックアウトしています」というエラーに阻まれ、膝を屈する。

これはProjectのデータモデルが、クライアントサイドのローカルファイルではなく、サーバー上の「チェックアウト=排他制御」を前提としたWebサービスアーキテクチャで構築されていることに起因する。PSI(Project Server Interface)やCSOMを介してこの壁を突破するには、単なるメソッド呼び出しを超えた「状態の遷移」への深い理解が必要だ。

今日は、その泥沼から脱出し、システム連携を堅牢にするための極限の知見を授ける。

1. チェックアウト状態の「非同期的な罠」

Project Serverでは、チェックアウト状態は単なるフラグではない。サーバー側で保持されている「セッションのロック」である。`ProjectOpen` メソッドを実行した際、裏側では `CheckOut` が走るが、ネットワークの遅延や前回の強制終了により、サーバー側で「Ghost Lock(亡霊のロック)」が発生することが多々ある。

VBAからこれを制御する場合、「状態の確認(CheckStatus)」→「必要な場合の強制解放(ForceCheckIn)」→「処理」→「明示的なチェックイン(CheckIn)」という一連のライフサイクルを厳密に管理せねばならない。

2. 強制チェックインを実現する実装ロジック

以下は、CSOMをラップしたラッパーライブラリやPSIエンドキャストを利用する際、最も信頼性の高いアプローチだ。VBAから呼び出す場合、COMラッパーを通じて以下のロジックを実装する。

‘ 伝説的なチーフアーキテクトによる、強制チェックインの論理構成(概念実装)
‘ ※実際の実装にはPSIのQueueCheckInProjectメソッドを叩くラッパーが必要となる

Public Sub ForceReleaseProject(ByVal projectGuid As String)
Dim projContext As Object ‘ プロジェクトコンテキスト

On Error GoTo ErrorHandler

‘ 1. プロジェクトの現在のチェックアウト状態を確認
If IsProjectCheckedOut(projectGuid) Then
‘ 2. 万が一、自プロセス外でロックされている場合はPSIへForceCheckInを要求
‘ QueueCheckInProject(GUID, force:=True) を実行する
‘ このとき、非同期キューの完了を待機するためのポーリング処理を挟むのが定石
Call ExecuteForceCheckIn(projectGuid)

‘ 3. 状態遷移の安定を待つための待機処理
‘ プロセス間通信のラグを考慮し、Sleepよりもタイマーによるポーリングを推奨
DoEvents
Application.Wait (Now + TimeValue(“0:00:03”))
End If

Exit Sub

ErrorHandler:
‘ メモリリークを避けるため、オブジェクトの明示的解放はFinallyブロックの如く記述する
‘ Set projContext = Nothing
Err.Raise Err.Number, “ForceReleaseProject”, “チェックイン制御に失敗: ” & Err.Description
End Sub

3. メモリとリソースの最適化:地獄を見ないための鉄則

VBAにおいて、Projectのオブジェクトモデルは非常に重い。特に `Project.Application` や `Project.Project` オブジェクトを安易にグローバル変数として保持すると、COM参照カウントの不整合から「ゾンビプロセス」が生成される。

  • 明示的Nothingの強制: プロシージャの終了時には、必ず `Set obj = Nothing` を行う。特に `Project` インスタンスをループ内で生成・破棄する場合は、VBAのガベージコレクションを待たず、メモリを即時解放する意識を持つこと。
  • イベントハンドラの解除: `WithEvents` でのイベント制御を行っている場合、必ず `Terminate` イベントやエラーハンドラ内で `Set obj = Nothing` を実行し、イベントシンクを断つこと。これを怠ると、ExcelやProjectがバックグラウンドで生き続け、次回のチェックイン試行時に「別のインスタンスが使用中」と判定される。

4. システム間連携における「境界防衛」

PWA環境で外部システムからProjectを操作する場合、「チェックアウトの保持時間は最小限に」というのが不変の鉄則だ。

大規模なバッチ処理を行う際、一括でチェックアウトして長時間処理を回すのは、他のユーザーの生産性を奪うだけでなく、サーバーのタイムアウトによって「永久ロック」を招くリスクがある。

  • 推奨アーキテクチャ:

1. バッチ開始時にプロジェクトをチェックアウト。
2. 変更点はメモリ上のオブジェクトで完結させ、最後の一瞬で `ProjectSave`。
3. `ProjectClose` を呼ぶと同時に `CheckIn` を即座に発行する。

アーキテクトからの助言

「自動化」とは、単に手作業をコードに置き換えることではない。サーバーの負荷、ネットワークの状態、そして「他の誰かがそこにいる」という環境要因を予見し、いかなる異常系においてもシステムが整合性を保てるように設計することだ。

もし貴殿が、チェックアウトのトラブルに辟易しているのなら、それはコードが悪いのではなく、「状態管理の哲学」が欠けている証拠である。まずは、自身のコードが生成したオブジェクトの墓場(メモリ上の未解放インスタンス)を掃除するところから始めてほしい。

真の自動化エンジニアは、コードの行数ではなく、システムの静寂を愛するものである。

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