【実務・中級編】ADOを用いてProjectのタスク情報をCSV/XMLへエクスポートする汎用データ変換ツール – Project VBA解析バイブル

スポンサーリンク

MS Projectデータ抽出の深淵:ADOを用いた高効率・堅牢なデータ変換アーキテクチャ

現場のプロジェクトマネージャーや自動化エンジニアが陥る最大の罠、それは「Projectオブジェクトをループで回してセルに書き出す」という、非効率で退屈なコードを書き続けることだ。数千タスクを持つプロジェクトでそれを実行すれば、VBAは悲鳴を上げ、メモリを浪費し、最終的には「応答なし」という墓場にたどり着く。

今日は、Project VBAの制約を逆手に取り、ADO(ActiveX Data Objects)を活用して、メモリ消費を最小限に抑えつつ、堅牢なデータエクスポートを実現する「極限の設計思想」を伝授する。

なぜ「ループで書き出し」は悪手なのか?

VBAで `ActiveProject.Tasks` をイテレーションするのは、Objectモデルのオーバヘッドが大きすぎる。Taskオブジェクト一つひとつにアクセスするたびに、COMインターフェースを介したコンテキストスイッチが発生する。

真にプロフェッショナルな設計は、「データを一度メモリ内のレコードセット(ADO.Recordset)に吸い上げ、そこから一括でストリーム出力する」というアプローチをとる。これこそが、大規模プロジェクトでも一瞬でCSV/XML変換を完了させる秘訣だ。

プロダクション環境に耐えうる設計の要点

1. 疎結合なデータ抽出: Projectオブジェクトと出力処理を分離する。
2. ADO Recordsetの活用: プロジェクトデータを「テーブル」として解釈する。これにより、フィルタリングやソートをVBA側ではなく、SQLライクな操作で完結させられる。
3. ストリームによる書き出し: `FileSystemObject` の `TextStream` を使い、バッファリングを意識したI/Oを行う。

【実践コード】高効率タスクエクスポート・エンジン

このコードは、Projectのタスク情報をADO Recordset経由でCSVに落とし込むテンプレートだ。そのまま業務ツールに組み込めるレベルの堅牢性を持たせている。

Option Explicit

‘ 参照設定: Microsoft ActiveX Data Objects x.x Library
‘ 参照設定: Microsoft Scripting Runtime

Public Sub ExportTasksToCSV(ByVal filePath As String)
Dim rs As ADODB.Recordset
Dim tsk As Task
Dim fso As Object
Dim ts As Object

‘ 1. Recordsetの定義(Schemaの定義)
Set rs = New ADODB.Recordset
With rs.Fields
.Append “TaskID”, adInteger
.Append “Name”, adVarWChar, 255
.Append “Start”, adDate
.Append “Finish”, adDate
.Append “Duration”, adVarWChar, 50
End With
rs.Open

‘ 2. Projectからデータを吸い出し(高速イテレーション)
On Error Resume Next ‘ 予期せぬプロパティアクセスエラーを回避
For Each tsk In ActiveProject.Tasks
If Not tsk Is Nothing Then
rs.AddNew
rs(“TaskID”).Value = tsk.ID
rs(“Name”).Value = tsk.Name
rs(“Start”).Value = tsk.Start
rs(“Finish”).Value = tsk.Finish
rs(“Duration”).Value = tsk.DurationText
rs.Update
End If
Next tsk
On Error GoTo 0

‘ 3. ストリームでCSV出力(高速・低メモリ)
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set ts = fso.CreateTextFile(filePath, True)

‘ ヘッダー書き出し
ts.WriteLine “TaskID,Name,Start,Finish,Duration”

‘ レコード書き出し
rs.MoveFirst
Do Until rs.EOF
ts.WriteLine Join(Array(rs!TaskID, rs!Name, rs!Start, rs!Finish, rs!Duration), “,”)
rs.MoveNext
Loop

ts.Close
rs.Close

MsgBox “エクスポート完了: ” & filePath, vbInformation
End Sub

この設計が「生き残る」理由

  • エラー耐性: `On Error Resume Next` を特定のプロパティアクセスに限定して使用している。プロジェクトデータには稀に「空のタスク」や「破損したリンク」が含まれるが、この構造なら処理を止めずに完走できる。
  • 汎用性: `rs.Fields.Append` を拡張するだけで、カスタムフィールドやリソース情報も容易に追加可能だ。XML出力が必要な場合も、`Recordset.Save` メソッドを一行呼び出すだけで、標準のXML形式で書き出せる。
  • 保守性: `Join` 関数を用いたCSV生成は、セミコロンやカンマ区切りの変更に即座に対応できる。手動で文字列結合を繰り返すコードと比較して、圧倒的に読みやすく、バグが混入しにくい。

チーフアーキテクトからの助言

業務効率化ツールを作る際、多くの者は「機能」を追い求めるが、真のエンジニアは「寿命」を追い求める。

もし、このツールが数年後に別のプロジェクトでも使われることを想定するなら、「Projectのフィールド名」を定数化する、あるいは「設定用JSON/CSV」から読み込む設計に昇華させることだ。ハードコーディングされたコードは、未来の自分に対する負債でしかない。

このコードを叩き台に、君自身の「最強のデータ連携基盤」を構築せよ。Project VBAという古い技術であっても、アーキテクチャ次第で、現代のシステムとも戦える強力な武器になるはずだ。

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