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

スポンサーリンク

ExcelからProjectへ:低速なセル操作を撲滅し、ADO/FSOで「0.1秒」の壁を突破する

Project VBAを扱うエンジニアが最初に直面する壁。それは「Excelのセルを一つずつ読み込み、ProjectのTaskオブジェクトに値を代入する」という、あまりに素朴で、かつ致命的に遅い実装です。

数千行のタスクを回した時、画面がフリーズし、砂時計が回り続けるのを見て「VBAは遅い」と嘆くのはもう終わりにしましょう。それはVBAが遅いのではなく、あなたの設計が「往復ビンタ」をしているからです。

今回は、ADO(ActiveX Data Objects)でExcelをデータベースとして叩き、FSO(FileSystemObject)で堅牢なパス管理を行い、配列処理で一気にProjectへ流し込む。この「実務レベルの高速化アーキテクチャ」を伝授します。

なぜセル操作(Range)は悪手なのか

`Worksheets(“Sheet1”).Cells(i, 1).Value` をループ内で叩く行為は、COMインターフェースを介したオーバーヘッドをループ回数分だけ発生させます。さらにProject側で `Task.Name = …` と叩けば、その度に再計算や描画更新が走り、パフォーマンスは崩壊します。

プロの設計は「データは一括でメモリに載せる」「Projectへの書き込みは最小限にする」のが鉄則です。

プロダクションコード:高速インポートの極意

このコードは、ExcelファイルをADOで接続し、SQLで必要なデータのみを抽出して配列としてメモリに展開します。その後、ProjectオブジェクトモデルのTaskコレクションに対して、必要最小限のアクセスで反映させます。

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

Sub ImportExcelToProject_HighSpeed()
Dim conn As Object, rs As Object
Dim fso As New FileSystemObject
Dim filePath As String
Dim strConn As String, strSQL As String
Dim taskData As Variant
Dim tsk As Task

filePath = “C:\Projects\ProgressData.xlsx”

‘ 1. FSOでファイル存在確認(必須の堅牢性)
If Not fso.FileExists(filePath) Then
MsgBox “ファイルが見つかりません”, vbCritical
Exit Sub
End If

‘ 2. ADOによるExcel接続(HDR=YESでヘッダー行を認識)
Set conn = CreateObject(“ADODB.Connection”)
Set rs = CreateObject(“ADODB.Recordset”)

strConn = “Provider=Microsoft.ACE.OLEDB.12.0;Data Source=” & filePath & _
“;Extended Properties=””Excel 12.0 Xml;HDR=YES;IMEX=1″”;”

conn.Open strConn
‘ SQLで必要な列のみを高速抽出
strSQL = “SELECT TaskName, Duration, StartDate FROM [Sheet1$A1:C1000]”
rs.Open strSQL, conn

‘ 3. GetRowsで全データをメモリ上の配列へ一括転送
If Not rs.EOF Then
taskData = rs.GetRows
End If

rs.Close: conn.Close

‘ 4. Projectへの書き込み(計算モードを一時停止するとさらに高速)
Application.Calculation = pjManual

Dim i As Long
For i = 0 To UBound(taskData, 2)
Set tsk = ActiveProject.Tasks.Add(taskData(0, i))
tsk.Duration = taskData(1, i)
tsk.Start = taskData(2, i)
Next i

Application.Calculation = pjAutomatic
MsgBox “同期完了”
End Sub

この設計のアーキテクチャ的利点

1. ADOによるデータ抽象化

Excelを「ファイル」として開くのではなく、「データベース」として扱うことで、必要な範囲のデータだけをSQLで抜き出せます。これにより、Excelを開くコストを排除し、読み込み時間を劇的に短縮します。

2. `GetRows` メソッドの魔力

`GetRows` はレコードセットを二次元配列に変換します。VBAにおいて、セルアクセスと配列アクセスでは、処理速度に100倍以上の開きがあります。メモリ上で完結する処理を増やすことこそが、エンジニアの腕の見せ所です。

3. 計算モードの制御

`Application.Calculation = pjManual` を忘れてはいけません。Projectはタスクが追加されるたびに依存関係を再計算します。最後に一度だけ計算させることで、インポート処理のボトルネックを完全に除去します。

開発現場へのアドバイス:保守性を高めるために

このコードをそのままコピペして終わりにしてはいけません。以下の「防衛的プログラミング」を実装に組み込んでください。

  • データ型の明示: Excel側の数値型が文字列として認識されるケースが多いです。`CDate()` や `CDbl()` で型変換を確実に行うこと。
  • 例外処理: `On Error GoTo` を入れ、ADO接続失敗時に確実に `conn.Close` が呼ばれるようにしてください。接続が残るとExcelファイルがロックされ、ユーザーから「ファイルが開けない」という苦情が飛んできます。
  • パスの動的管理: ファイルパスをコードに直書きせず、`ThisProject.Path` や定数で管理し、環境が変わっても動くように設計しましょう。

VBAは、単なるスクリプト言語ではありません。オブジェクトモデルを理解し、メモリとリソースを支配下に置くことで、世界で最も強力な自動化エンジンへと化けます。

次は、タスクの進捗率を条件付きで更新するロジックを組み込み、真の「同期システム」へと昇華させてみてください。あなたの手元で、業務の風景が変わるはずです。

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