【実務・中級編】リソースの「割り当て」情報をJSONで出力し、Webアプリと連携するデータ基盤 – Project VBA解析バイブル

スポンサーリンク

【Project VBA極限活用】MS Projectの「リソース割り当て」をJSON化し、モダンWebフロントエンドへ直結させるアーキテクチャ

こんにちは。チーフアーキテクトの私だ。
これまで数々の巨大プロジェクトの裏側で、Microsoft Project(以下、MS Project)と基幹システム、あるいはモダンなWebダッシュボードとのデータ連携基盤を構築してきた。

現場の担当者から「MS Projectで組んだリソースの割り当てやコストの状況を、社内のWebアプリやBIツールでリアルタイムに共有したい」という相談をよく受ける。
その際、多くのエンジニアがやりがちなのが、Excelを介した泥臭いCSVエクスポートや、COMオブジェクトを何重にもループさせる非効率で重たいVBAコードの乱立だ。

ハッキリ言おう。MS Projectのデータ構造を理解せずに行き当たりばったりで書いたVBAは、大規模プロジェクトを開いた瞬間にメモリリークを起こし、Excelごとフリーズする。

今回は、Project VBAのオブジェクトモデルの「重み」を熟知したプロだけが書ける、リソース割り当て情報を美しく構造化されたJSONとして出力し、Webアプリケーションへシームレスに連携するための堅牢な基盤構築手法を伝授する。

—

1. なぜ「リソース割り当て」の連携は難解なのか?

MS Projectのデータモデルは、リレーショナルデータベースのそれとは大きく異なり、極めて複雑な階層構造を持っている。

  • Task(タスク) と Resource(リソース) は「Assignment(割り当て)」という中間テーブル(オブジェクト)を介して多対多で結ばれている。
  • さらに、時間軸に沿った工数(Work)やコスト(Cost)は、単にプロパティを1つ叩くだけでは取得できず、キャッシュや計算コンテキストのロードを意識する必要がある。

これを外部のWebアプリ(React, Vue, あるいはPython/Node.jsのバックエンドなど)で利用しやすい形にするためには、VBA側で完全にフラットかつ自己完結したJSONツリーに変換してあげる必要がある。外部にパースの苦労を押し付けてはならない。

—

2. 堅牢なJSON生成におけるアーキテクチャ上の注意点

1. 外部ライブラリ(JScript/FileSystemObject)の安全な利用
VBA単体には標準のJSONパーサー/ビルダーが存在しない。よく外部の巨大なJSONライブラリをImportする者がいるが、配布やバージョン管理の観点からリスキーだ。Windows環境であれば、`ScriptControl`やJSON文字列の直接組み立て(または簡易的な自製エスケープ関数)で十分対応できる。今回は依存関係をゼロにするため、手動構築+安全な文字列エスケープ方式を採用する。
2. オブジェクトのライフサイクルとパフォーマンス
`ActiveProject.Assignments` を不用意に全件スキャンすると、プロジェクトの規模によっては数秒〜数十秒の硬直を招く。`For Each` を回す際のオブジェクト参照のオーバーヘッドを最小限に抑えるコード構造が必須だ。
3. 文字コード(UTF-8)の担保
VBAの `ADODB.Stream` を用いて、BOM付き/BOMなしのUTF-8でファイル出力する。これができていないと、日本語リソース名がWeb側で文字化けして地獄を見る。

—

3. 【プロダクションコード】リソース割り当てJSONエクスポートVBA

以下のコードを、そのままあなたのMS ProjectのVBAモジュールに貼り付けてほしい。
実務でそのまま耐えうる、エラーハンドリングと文字コード制御を完備した最高峰のコードだ。

Option Explicit

‘ ==============================================================================
‘ 処理名: ExportResourceAssignmentsToJson
‘ 概要 : プロジェクト内の全リソース割り当て情報を走査し、
‘ Webアプリ連携用のJSONファイルとしてUTF-8で出力する。
‘ ==============================================================================
Public Sub ExportResourceAssignmentsToJson()
Dim prj As Project
Set prj = ActiveProject

‘ エラーハンドリングの徹底
On Error GoTo ErrorHandler

Dim jsonBuffer As String
jsonBuffer = BuildAssignmentsJson(prj)

‘ 出力ファイルパスの指定(デスクトップに出力)
Dim filePath As String
filePath = CreateObject(“WScript.Shell”).SpecialFolders(“Desktop”) & “\resource_assignments.json”

‘ UTF-8でファイルに書き出す
Call WriteTextToFile(filePath, jsonBuffer, “UTF-8”)

MsgBox “リソース割り当て情報のJSONエクスポートが完了しました。” & vbCrLf & _
“保存先: ” & filePath, vbInformation, “インテグレーション基盤”
Exit Sub

ErrorHandler:
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“Error: ” & Err.Description, vbCritical, “致命的なエラー”
End Sub

‘ ==============================================================================
‘ 内部関数: 割り当て情報を走査してJSON文字列を構築
‘ ==============================================================================
Private Function BuildAssignmentsJson(ByVal prj As Project) As String
Dim assn As Assignment
Dim sb As String
Dim isFirst As Boolean

‘ JSON配列の開始
sb = “[” & vbCrLf
isFirst = True

‘ 各アサインメント(割り当て)をループ
For Each assn In prj.Assignments
‘ リソースが割り当てられていない空のアサインメントや、サマリータスクは除外
If Not assn.Resource Is Nothing Then
If Not assn.Task.Summary Then

If Not isFirst then
sb = sb & “,” & vbCrLf
End If

sb = sb & ” {”
sb = sb & “””” & “assignment_id” & “””: ” & assn.UniqueID & “,”
sb = sb & “””” & “task_id” & “””: ” & assn.Task.UniqueID & “,”
sb = sb & “””” & “task_name” & “””: “”” & EscapeJsonString(assn.Task.Name) & “””,”
sb = sb & “””” & “resource_id” & “””: ” & assn.Resource.UniqueID & “,”
sb = sb & “””” & “resource_name” & “””: “”” & EscapeJsonString(assn.Resource.Name) & “””,”
sb = sb & “””” & “work_hours” & “””: ” & (assn.Work / 60) & “,” ‘ 分単位を時間に変換
sb = sb & “””” & “cost” & “””: ” & assn.Cost & “,”
sb = sb & “””” & “start_date” & “””: “”” & Format(assn.Start, “yyyy-mm-dd”) & “”””
sb = sb & “}”

isFirst = False
End If
End If
Next assn

sb = sb & vbCrLf & “]”
BuildAssignmentsJson = sb
End Function

‘ ==============================================================================
‘ ユーティリティ: JSON文字列のエスケープ処理(最低限のサニタイズ)
‘ ==============================================================================
Private Function EscapeJsonString(ByVal val As String) As String
Dim result As String
result = val
result = Replace(result, “\”, “\\”)
result = Replace(result, “”””, “\”””)
result = Replace(result, vbCrLf, ” “)
result = Replace(result, vbCr, ” “)
result = Replace(result, vbLf, ” “)
EscapeJsonString = result
End Function

‘ ==============================================================================
‘ ユーティリティ: ADODB.Stream を使った文字コード指定ファイル出力
‘ ==============================================================================
Private Sub WriteTextToFile(ByVal filePath As String, ByVal content As String, ByVal charset As String)
Dim stream As Object
Set stream = CreateObject(“ADODB.Stream”)

With stream
.Type = 2 ‘ adTypeText
.charset = charset
.Open
.WriteText content
.SaveToFile filePath, 2 ‘ adSaveCreateOverWrite
.Close
End With

Set stream = Nothing
End Sub

—

4. この設計が「プロの仕事」である理由

1. 工数(Work)の単位補正
MS Projectの内部データにおいて、`Work` プロパティの基本単位は「分(Minutes)」で保持されている。これをそのまま出力するとWeb側で「1人日=480時間」といった大惨事になるため、コード内で `/ 60` を行い、直感的な時間単位へ正規化してJSONに載せている。
2. サマリータスクの除外
プロジェクト管理上、親階層であるサマリータスクにもリソースが集計値として割り当てられることがある。これをそのまま出力すると工数が二重計上(ダブルカウント)されるため、`If Not assn.Task.Summary Then` によって実タスク(Leaf Task)のみを抽出している。これができていないシステムは、BIツールでの集計時に必ず破綻する。
3. ADODB.Streamによるエンコーディング制御
標準の `Open “path” For Output` を使うとシフトJIS(CP932)で出力され、モダンなWebAPIやSPA(React等)で受け取った際に文字化けの温床になる。`ADODB.Stream` を用いて強制的にUTF-8(BOMなしが望ましい場合は別途調整)で吐き出すことで、下流のWebシステム側でパーサエラーが起きる余地を断っている。

—

5. Webアプリケーション連携への展開

このVBAによってデスクトップに出力された `resource_assignments.json` は、以下のような形でモダンなWebフロントエンドやバックエンドにそのままインプットできる。

[
{
“assignment_id”: 102,
“task_id”: 12,
“task_name”: “詳細設計書レビュー”,
“resource_id”: 3,
“resource_name”: “シニアアーキテクトA”,
“work_hours”: 16.0,
“cost”: 160000,
“start_date”: “2023-11-01”
}
]

例えば、社内のRPAやタスクスケジューラ(Windowsタスク)から定期的にこのマクロをサイレント実行(`/m` オプション等を使用)させ、出力されたJSONをクラウドストレージやAPIサーバーへ自動アップロードさせれば、「人間の手作業が一切介在しない、リアルタイム・リソースマネジメント基盤」が完成する。

総括

VBAは、古い言語とやゆされることがある。しかし、それは書き手の設計思想が古い場合の話だ。
オブジェクトモデルの本質を突いたメモリ効率の良い走査、下流システムの仕様に配慮したデータ正規化、そして堅牢なエラーハンドリング。これらを網羅したVBAコードは、現代のモダンなWebインフラストラクチャとも堂々と渡り合える。

現場の非効率をあなたの手で駆逐し、真に洗練された自動化アーキテクチャを構築してほしい。

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