こんにちは!Microsoft Projectの裏側に広がる深淵な世界へようこそ。
普段はExcelマクロで留まりがちなVBAですが、Microsoft Project(MSP)のオブジェクトモデルを掌握すると、プロジェクト管理の自動化という新しい扉が開かれます。
今回は、上級者への登竜門である「WBSの階層構造をJSON形式にシリアライズし、Webダッシュボードと連携するAPI開発」をテーマにお届けします。
「マクロの記録」が全く通用しないProject VBAの世界ですが、ここをクリアすれば、あなたも立派なアーキテクトの仲間入りです。優しく、そして本質的に解説していきますので、一緒に一歩ずつ進んでいきましょう!
—
1. なぜProject VBAで「JSON出力」なのか?
現代のプロジェクト管理において、Microsoft Project標準のガントチャートだけでは物足りないシーンが増えています。
「全社向けの軽量なWebダッシュボードでリアルタイムにタスクの進捗を共有したい」
「ReactやVue.jsを使ったモダンなフロントエンドで、自作のガントチャートを描画したい」
そんなとき、Projectのタスクデータ(WBSの階層、前提条件、依存関係)を綺麗に構造化したJSONに変換し、Web APIへプッシュする仕組みがあれば、夢が広がりますよね。
しかし、Excelと違ってProject VBAには「標準のJSONパーサー」や「階層構造を簡単に保持するツリー構造オブジェクト」がありません。だからこそ、オブジェクトのライフサイクルとインデントの仕組みを正しく理解した者だけが書ける、知的なコードが必要になるのです。
—
2. Project VBAの基礎:タスク階層(WBS)とアウトラインの罠
まずは、Projectのデータ構造における最大のポイントを押さえましょう。
Excelの行とは異なり、MSPのタスク(`Task`オブジェクト)は「アウトラインレベル(OutlineLevel)」と「ID / UniqueID」を持っています。
- OutlineLevel: タスクの深さ(1が最上位プロジェクト、2がサマリーや大タスク、3以降が子タスク…)
- UniqueID: タスクが削除・追加されても変わらない不変のID。依存関係(先行タスク)を結ぶ際に絶対必要になります。
ここで初心者が陥りがちエラーの代表格がこれです。
> ⚠️ 陥りやすいエラー:配列の順序を無視してループを回してしまう
> Webで階層構造(ツリービュー)を表現する場合、親タスクの配下に子タスクが正しくネスト(内包)されている必要があります。単にタスクを上から順に舐めるだけでは、JSONの親子関係が崩壊します。
—
3. 実装コード:WBSをJSONにシリアライズするVBAエンジン
お待たせしました。ここからが本題です。
アクティブなプロジェクトの全タスクを走査し、WBSの階層構造、進捗率、そして依存関係(Predecessors)を綺麗に保持したJSON文字列を生成するプロフェッショナルなVBAコードを公開します。
そのままVBE(Visual Basic Editor)に貼り付けて実行できるように、詳細なコメントを添えています。
‘ ==============================================================================
‘ モジュール名: modWwwDashboardExporter
‘ 概要: Microsoft ProjectのWBS階層と依存関係をJSONにシリアライズする
‘ ==============================================================================
Option Explicit
Public Sub ExportWbsToJson()
Dim t As Task
Dim json As String
Dim fso As Object
Dim ts As Object
Dim filePath As String
‘ 出力先のパス(デスクトップの wbs_data.json)
filePath = CreateObject(“WScript.Shell”).SpecialFolders(“Desktop”) & “\wbs_data.json”
‘ JSONのルート配列を開始
json = “[” & vbCrLf
Dim isFirst As Boolean
isFirst = True
‘ プロジェクト内の全タスクを走査
For Each t In ActiveProject.Tasks
‘ 削除されたタスクや空行を除外
If Not t Is Nothing Then
If t.Name <> “” Then
If Not isFirst then
json = json & “,” & vbCrLf
End If
isFirst = False
‘ タスクオブジェクトをJSONの1オブジェクト(文字列)に変換
json = json & BuildTaskJson(t)
End If
End If
Next t
‘ JSONのルート配列を閉じる
json = json & vbCrLf & “]”
‘ ファイルとして書き出し(UTF-8で保存するのが実務では望ましいですが今回は簡易的にTextStreamを使用)
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set ts = fso.CreateTextFile(filePath, True, True) ‘ Unicode(UTF-16)形式で保存
ts.Write json
ts.Close
MsgBox “WBSのJSONエクスポートが完了しました!” & vbCrLf & filePath, vbInformation, “成功”
End Sub
‘ ——————————————————————————
‘ 関数名: BuildTaskJson
‘ 概要: 個別のTaskオブジェクトからJSONの断片を生成する
‘ ——————————————————————————
Private Function BuildTaskJson(ByVal t As Task) As String
Dim taskJson As String
Dim predecessorsStr As String
‘ 先行タスク(依存関係)の取得処理
predecessorsStr = GetPredecessorsString(t)
‘ JSONフォーマットの構築(エスケープ処理は簡易化)
taskJson = ” {” & vbCrLf & _
” “”id” & “””: ” & t.UniqueID & “,” & vbCrLf & _
” “”name” & “””: “”” & EscapeJson(t.Name) & “””,” & vbCrLf & _
” “”outlineLevel” & “””: ” & t.OutlineLevel & “,” & vbCrLf & _
” “”start” & “””: “”” & Format(t.Start, “yyyy-mm-dd”) & “””,” & vbCrLf & _
” “”finish” & “””: “”” & Format(t.Finish, “yyyy-mm-dd”) & “””,” & vbCrLf & _
” “”percentComplete” & “””: ” & t.PercentComplete & “,” & vbCrLf & _
” “”milestone” & “””: ” & LCase(CStr(t.Milestone)) & “,” & vbCrLf & _
” “”predecessors” & “””: “”” & predecessorsStr & “””” & vbCrLf & _
” }”
BuildTaskJson = taskJson
End Function
‘ ——————————————————————————
‘ 関数名: GetPredecessorsString
‘ 概要: タスクの依存関係(前提条件)を安全に文字列化する
‘ ——————————————————————————
Private Function GetPredecessorsString(ByVal t As Task) As String
Dim predLink As TaskDependency
Dim result As String
result = “”
On Error Resume Next
For Each predLink In t.TaskDependencies
If result <> “” Then result = result & “, ”
result = result & predLink.From.UniqueID
Next predLink
On Error GoTo 0
GetPredecessorsString = result
End Function
‘ ——————————————————————————
‘ 関数名: EscapeJson
‘ 概要: JSONの構文を壊す文字(ダブルクォーテーション等)をエスケープする
‘ ——————————————————————————
Private Function EscapeJson(ByVal str As String) As String
str = Replace(str, “\”, “\\”)
str = Replace(str, “”””, “\”””)
EscapeJson = str
End Function
—
4. コードの解説:ここがエンジニアの腕の見せ所
上記のコードで、特に注目してほしいポイントを解説します。
1. `ActiveProject.Tasks` の安全な走査
Projectのタスクコレクションは、途中に空行や削除されたタスクが含まれることがあります。`If Not t Is Nothing` と `If t.Name <> “”` でヌルポインタやゴミデータの混入を防ぐのが、実務で壊れないプログラムを書く鉄則です。
2. 依存関係(`TaskDependencies`)のトラッキング
ガントチャートをWeb側(例: `Frappe Gantt` や `DHTMLX Gantt` など)で描画する際、「どのタスクが終わったらこのタスクが始まるか」という矢印(依存関係)が命になります。`t.TaskDependencies` をループで回し、先行タスクの `UniqueID` を抽出することで、Web側で完全なネットワーク図・ガントチャートが再現可能になります。
3. エラーハンドリングのスコープ管理(`On Error Resume Next`)
依存関係が設定されていないタスクに対して `t.TaskDependencies` を叩くとエラーが発生するため、ピンポイントでトラップを張って安全にスルーしています。
—
5. Webダッシュボード(API)へ連携する次のステップ
このVBAによってデスクトップに出力された `wbs_data.json` をどう活かすか?
ここから先はモダンなWeb開発の領域です。
- VBAから直接C#やNode.jsのAPIエンドポイントへPOSTする
(VBA内で `MSXML2.ServerXMLHTTP.6.0` を使えば、作成したJSONを社内のWebサーバやクラウド(AWS/Azure等)のAPIへ直接送信できます!)
- Webフロントエンドでの読み込み
JavaScriptでこのJSONを受け取り、ガントチャートライブラリに流し込むだけで、美しいリアルタイム・プロジェクトダッシュボードが完成します。
—
まとめ
今回は「WBSの階層構造をJSON形式にシリアライズし、Webダッシュボードと連携するAPI開発」という、一歩進んだテーマでお届けしました。
最初は難しく感じるProject VBAのオブジェクトモデルも、「階層(OutlineLevel)」と「識別子(UniqueID)」の概念さえ掴んでしまえば、Excelマクロよりもは遥かにダイナミックで強力な自動化の武器になります。
ここをクリアしたあなたなら、もう「マクロの記録」に頼る必要はありません。ぜひご自身のプロジェクト管理業務や、社内システムの連携に応用してみてくださいね。
それでは、快適なVBAライフを!バッチリ応援しています!
