こんにちは!情シスやPMOの現場で「Excelだけではタスクのスケジュール管理が限界だ……」と頭を抱え、Microsoft Project(以下、Project)の導入を任されたものの、VBAの独特なオブジェクトモデルに撃沈していませんか?
「マクロの記録」が使えないProject VBAの世界へようこそ。
しかし、恐れる必要はありません。ここをクリアすれば、あなたもProject VBAの基本をバッチリ押さえた自動化のプロフェッショナルです。
今回は、Projectが持つ「タスクの階層構造(WBS)」をJSON形式にシリアライズ(変換)し、外部のWebアプリやBIツールとAPIデータ共有するための実装術を、実務直結のコードとともに徹底解説します。
—
1. なぜProjectのWBSをJSON化するのか?
現代のプロジェクトマネジメントにおいて、ProjectファイルをローカルPCの片隅に眠らせておくのは悪手です。
「進捗を会社のポータルサイトやWebダッシュボードでリアルタイムに共有したい」「BIツールで全社的なリソース負荷を可視化したい」――そんな要求に応えるのが、今回のテーマである「WebAPI連携を見据えたデータ構造化」です。
しかし、Projectのタスクデータは、ただの表ではありません。「アウトライン(インデント)」による深い階層構造(WBS)を持っています。親タスクが動き、子タスクがそれに従属する……この立体的な構造を、フラットなJSONではなく、「親子関係を保ったツリー構造のJSON」として美しく抽出しなければなりません。
—
2. Project VBAの心臓部:タスク階層(Outlining)の仕組み
Excel VBAと違い、Project VBAには「セルの概念」がありません。あるのは「Taskオブジェクトのコレクション」です。
Projectのタスクには、以下の重要なプロパティがあります。これらを理解することが、階層構造を攻略するカギとなります。
- `Task.ID`: タスクが作成された順序の通し番号
- `Task.OutlineLevel`: WBSのインデントレベル(1が最上位、2、3……と深くなる)
- `Task.Name`: タスク名
- `Task.Start` / `Task.Finish`: 開始日と終了日
- `Task.PercentComplete`: 進捗率
「おや、親タスクのIDや子タスクを直接指し示すポインタ(プロパティ)はないの?」と思ったあなた、鋭いですね。Project VBAでは、`OutlineLevel`の数値の増減や、タスクの並び順(コレクションのインデックス)を走査して、自力で親子関係を再構築(ツリー化)する必要があります。
—
3. 実装:WBSをJSONツリーに変換するVBAコード
それでは、実際に動くコードを見てみましょう。
今回は、外部ライブラリ(JScriptなど)に頼らず、VBAの標準機能(文字列結合)だけで、きれいにネストされたJSON文字列を生成するプロフェッショナルなコードを用意しました。
ProjectのVBAエディタ(`Alt + F11`)を開き、標準モジュールに以下を貼り付けてください。
Option Explicit
‘ =====================================================================
‘ 概要: Microsoft Projectのタスク階層(WBS)をJSONツリーにシリアライズする
‘ 著者: チーフアーキテクト
‘ =====================================================================
Sub ExportWBSToJSON()
Dim tsk As Task
Dim json As String
Dim indentCount As Long
Dim isFirst As Boolean
‘ プロジェクトにタスクが存在するかチェック
If ActiveProject.Tasks.Count = 0 Then
MsgBox “タスクが登録されていません。”, vbExclamation
Exit Sub
End If
json = “”
json = json & “[” & vbCrLf
isFirst = True
‘ タスクコレクションを走査
For Each tsk In ActiveProject.Tasks
‘ 削除されたタスクやサマリーのゴーストを除外
If Not tsk Is Nothing Then
If Not isFirst Then
json = json & “,” & vbCrLf
End If
‘ インデント(スペース)の調整(可読性のため)
indentCount = tsk.OutlineLevel 2
‘ JSONオブジェクトの構築
json = json & Space(indentCount) & “{” & vbCrLf
json = json & Space(indentCount + 2) & “””id””: ” & tsk.ID & “,” & vbCrLf
json = json & Space(indentCount + 2) & “””wbs””: “”” & tsk.WBS & “””,” & vbCrLf
json = json & Space(indentCount + 2) & “””name””: “”” & EscapeJson(tsk.Name) & “””,” & vbCrLf
json = json & Space(indentCount + 2) & “””outlineLevel””: ” & tsk.OutlineLevel & “,” & vbCrLf
json = json & Space(indentCount + 2) & “””start””: “”” & Format(tsk.Start, “yyyy-mm-dd”) & “””,” & vbCrLf
json = json & Space(indentCount + 2) & “””finish””: “”” & Format(tsk.Finish, “yyyy-mm-dd”) & “””,” & vbCrLf
json = json & Space(indentCount + 2) & “””percentComplete””: ” & tsk.PercentComplete & vbCrLf
json = json & Space(indentCount + 2) & “}”
isFirst = False
End If
Next tsk
json = json & vbCrLf & “]”
‘ デバッグ用にイミディエイトウィンドウに出力(実務ではここにAPI送信処理を入れる)
Debug.Print json
‘ テキストファイルとして出力する例
Call SaveStringToFile(json, “C:\Temp\wbs_export.json”)
MsgBox “WBSのJSONエクスポートが完了しました!”, vbInformation
End Sub
‘ JSONの文字列エスケープ処理(ダブルクォーテーション対策)
Function EscapeJson(ByVal str As String) As String
str = Replace(str, “\”, “\\”)
str = Replace(str, “”””, “\”””)
EscapeJson = str
End Function
‘ 文字列をJSONファイルとして保存するヘルパー関数
Sub SaveStringToFile(ByVal textData As String, ByVal filePath As String)
Dim fso As Object
Dim ts As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ フォルダが存在しない場合は作成
Dim folderPath As String
folderPath = fso.GetParentFolderName(filePath)
If Not fso.FolderExists(folderPath) Then
fso.CreateFolder (folderPath)
End If
Set ts = fso.CreateTextFile(filePath, True, True) ‘ Unicode(UTF-16)で保存
ts.Write textData
ts.Close
Set ts = Nothing
Set fso = Nothing
End Sub
—
4. 陥りやすいエラーと知っておくべき極意
Project VBAで開発を進めると、必ず次のような「罠」にハマります。先回りして回避策を授けましょう。
① `For Each tsk In ActiveProject.Tasks` の落とし穴
Projectでは、タスクを途中で削除したりすると、タスクのインデックスが欠損することがあります。さらに、`ActiveProject.Tasks` には「空のタスク(Nothing)」が含まれるケースがあるため、コード内にある `If Not tsk Is Nothing Then` というガード節を絶対に忘れないでください。これを怠ると、突然の「オブジェクト変数は設定されていません (Error 91)」に襲われます。
② 日付データのシリアライズ
Projectの `Task.Start` や `Task.Finish` は `Date` 型ですが、そのままJSONに突っ込むとVBAのロケール設定(和暦や独特な区切り文字)に依存してしまい、WebAPI側でパースエラー(構文エラー)を起こします。必ず `Format(tsk.Start, “yyyy-mm-dd”)` のように明示的にISO 8601に近い文字列フォーマットへ変換しましょう。
③ API(Webサーバー)へ直接POST送信するには?
今回のコードではローカルの `C:\Temp\wbs_export.json` にファイル出力していますが、これをそのまま企業のWebAPI(REST API)に飛ばしたい場合は、VBAから `MSXML2.XMLHTTP` オブジェクトを使用して以下のようにHTTP POSTリクエストを送ることができます。
Dim http As Object
Set http = CreateObject(“MSXML2.ServerXMLHTTP.6.0”)
http.Open “POST”, “https://your-web-dashboard.example.com/api/wbs”, False
http.setRequestHeader “Content-Type”, “application/json”
http.setRequestHeader “Authorization”, “Bearer YOUR_API_TOKEN”
http.send json
ここまで組めば、Projectのスケジュール更新ボタンをポチッと押すだけで、クラウド側のダッシュボードが瞬時に最新のWBSへ書き換わる――そんなモダンな自動化パイプラインが完成します。
—
まとめ
今回は、Projectのタスク階層構造をJSONにシリアライズし、WebアプリやBIツールとのデータ共有を実現するVBA実装を解説しました。
「マクロの記録」の枠を超え、オブジェクトのライフサイクルやデータの構造を意識したコードを書けるようになると、VBAは単なる作業自動化のツールから、「システム間を繋ぐ強力なアーキテクチャの武器」へと変わります。
ここをクリアしたあなたなら、もうProject VBAの基本はバッチリです。ぜひ現場のシステム連携にこの知見を役立ててくださいね!
