【テクニカル・上級編】Project VBAでExcelからデータをインポートする:ADOとFSOを組み合わせた高速データ連携術 – Project VBA解析バイブル

スポンサーリンク

Project VBAを掌握せよ:ADO/FSOによる「脱・セル操作」の高速データ連携術

多くのエンジニアがProject VBAの深淵に足を踏み入れ、まず絶望するのはその「絶望的なまでの描画同期の遅さ」だ。`For Each Task In ActiveProject.Tasks` でセルを一つずつ叩くコードを書いていないか? それは、高速道路を徒歩で歩くようなものだ。

今日は、ExcelからProjectへ数千行のタスクを一瞬で流し込む、アーキテクトレベルの戦術を伝授する。

1. なぜ「セル操作」が死を招くのか

Project VBAの `Task.Name = …` や `Task.Start = …` といったプロパティ代入は、内部で再計算エンジンをキックする。行数が増えるほど、UIの再描画と依存関係の再計算がオーバーヘッドとなり、処理時間は指数関数的に増大する。

これを回避する唯一の解は、「Excel上のデータをADOでメモリ上のRecordsetに展開し、中間オブジェクトを介さずに一気にProjectへプッシュする」ことだ。

2. アーキテクチャの要:ADOとFSOのハイブリッド構成

ファイルシステムへのアクセスは `Scripting.FileSystemObject (FSO)` に任せ、データ構造の解析と保持には `ADODB.Recordset` を用いる。特に `Recordset` は、メモリ上にテーブル構造を仮想的に構築できるため、配列を直接操作するよりも型安全かつ高速にデータをハンドリングできる。

極限のデータインポート実装例

以下に、実戦でそのまま使えるテンプレートを提示する。

‘ 参照設定: Microsoft ActiveX Data Objects 6.1 Library
‘ 参照設定: Microsoft Scripting Runtime
Option Explicit

Public Sub ImportExcelToProject()
Dim rs As ADODB.Recordset
Dim tsk As Task
Dim fso As FileSystemObject
Dim filePath As String

‘ 1. FSOでファイル存在確認(安全第一)
Set fso = New FileSystemObject
filePath = “C:\Data\ProjectData.xlsx”
If Not fso.FileExists(filePath) Then Exit Sub

‘ 2. ADOでデータをメモリへロード(SQLで抽出条件を絞るのがコツ)
Set rs = GetExcelDataAsRecordset(filePath)

‘ 3. Projectの再計算を抑制(パフォーマンスの要)
Application.Calculation = pjManual

On Error GoTo Cleanup

‘ 4. 高速イテレーション
Do Until rs.EOF
‘ 既存タスクとの突合はIDや一意なフラグで行うこと
Set tsk = ActiveProject.Tasks.Add(rs.Fields(“TaskName”).Value)
tsk.Start = rs.Fields(“StartDate”).Value
tsk.Duration = rs.Fields(“Duration”).Value

rs.MoveNext
Loop

Cleanup:
‘ 5. 明示的なメモリ解放(VBAのGCを信用しない)
Application.Calculation = pjAutomatic
If Not rs Is Nothing Then
rs.Close
Set rs = Nothing
End If
Set fso = Nothing
End Sub

3. シニアエンジニアが意識すべきメモリ最適化

VBAのガーベジコレクションは「非常に気まぐれ」だ。大規模なデータ連携を行う際、以下の鉄則を守るだけで安定性が劇的に変わる。

  • オブジェクトの明示的解放: `Set obj = Nothing` は儀式ではない。特に `ADODB.Connection` や `Recordset` は、スコープを抜けてもメモリを占有し続ける傾向がある。必ず `Close` メソッドと対で記述せよ。
  • イベントの抑制: `Application.EnableEvents = False` を検討せよ。Projectの計算イベントが連鎖的に発生すると、スタックオーバーフローや予期せぬ中断を招く。
  • Windows APIの活用: 数万行を超える場合、`CoTaskMemAlloc` を用いたメモリ管理が必要になるケースもある。VBAの限界を感じたら、躊躇なく `Kernel32.dll` の `Sleep` で描画スレッドに呼吸をさせる等の小細工を挟むのも、現場の知恵だ。

4. レガシー環境での保守性

このコードの強みは、ExcelのUIに依存していないことにある。もしExcel側でデータ構造が変わっても、SQLクエリ(`SELECT FROM [Sheet1$]`)を調整するだけで対応可能だ。

「綺麗なコード」とは、将来の仕様変更に対して最小のコストで追従できるコードを指す。Project VBAを扱う際は、「Projectはあくまでデータベースであり、Excelはインターフェースである」という分離の思想を忘れてはならない。

結びに代えて

ツールを使いこなすのではない。ツールがメモリとCPUをどう消費しているかを想像し、それを制御するのだ。Project VBAにおけるパフォーマンスチューニングは、まさにこの「内部挙動の可視化」に他ならない。

君たちの目の前にあるタスクリストは、単なる表ではない。エンジニアとしての矜持を示すキャンバスだ。効率化の極致を追求する、その姿勢こそがシステムを救う。

健闘を祈る。

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