【実務・中級編】【中級者向け】FSOを活用したプロジェクトファイル検索と一括オープンツール – Project VBA解析バイブル

スポンサーリンク

Project VBAを掌握せよ:FSOによるプロジェクトファイル一括制御の極意

プロジェクト管理の現場において、数十、数百の`.mpp`ファイルを個別に開いてステータスを確認・更新する……そんな「化石のような手作業」で消耗していないだろうか。

Project VBAを扱うエンジニアとして、私は断言する。「ファイル操作を自動化できないプロジェクト管理は、管理とは呼べない」と。

今日は、`FileSystemObject (FSO)`を用いた再帰的なファイル検索と、Project Applicationを制御する堅牢な一括処理の実装手法を授ける。単に動くだけのコードではない。本番環境で「例外を吐かずに確実に仕事を完遂する」ためのプロの設計論だ。

1. なぜ「Dir関数」ではなく「FSO」なのか

VBA初心者はよく`Dir`関数でファイルをループさせるが、これは拡張性が皆無だ。

  • 再帰処理の限界: サブフォルダの階層が深くなるたびにロジックが破綻する。
  • 状態管理: `Dir`は内部でポインタを保持するため、入れ子になったループ処理で容易に暴走する。

対して`FileSystemObject (FSO)`はオブジェクト指向的であり、ファイル操作を「オブジェクト」として扱う。これにより、堅牢で保守性の高い再帰処理が可能になる。

2. 堅牢な一括処理アーキテクチャ

本番環境で運用するツールには、以下の3原則が必須だ。

1. 疎結合な設計: ファイル検索ロジックと、個別のプロジェクト処理(開く・保存・ベースライン設定等)を分離する。
2. エラーハンドリングの徹底: 1つのファイルが破損していても、処理を止めない。
3. リソースの解放: `Project.Application`を起動しっぱなしにするのはメモリリークの温床。処理単位で確実に閉じる。

3. 実装:再帰的検索とプロジェクト制御のプロダクションコード

以下のコードは、指定ディレクトリ以下の全`.mpp`ファイルを再帰的に検索し、処理を行うテンプレートだ。

Option Explicit

‘ 必要な参照設定: Microsoft Scripting Runtime

Public Sub ProcessAllProjects()
Dim fso As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)

‘ 処理対象のルートディレクトリ
Dim targetPath As String
targetPath = “C:\Projects\TargetFolder”

‘ 再帰処理の開始
Call RecursiveSearch(fso.GetFolder(targetPath), fso)

MsgBox “全プロジェクトの処理が完了しました。”, vbInformation
End Sub

Private Sub RecursiveSearch(folder As Object, fso As Object)
Dim subFolder As Object
Dim file As Object

‘ 現在のフォルダ内のファイルを処理
For Each file In folder.Files
If LCase(fso.GetExtensionName(file.Path)) = “mpp” Then
Call ProcessProject(file.Path)
End If
Next

‘ サブフォルダを再帰的に探索
For Each subFolder In folder.SubFolders
Call RecursiveSearch(subFolder, fso)
Next
End Sub

Private Sub ProcessProject(filePath As String)
Dim projApp As MSProject.Application
Dim proj As MSProject.Project

On Error GoTo ErrorHandler

‘ Projectアプリケーションを個別に制御(非表示で高速化)
Set projApp = New MSProject.Application
projApp.Visible = False

‘ ファイルを開く(ReadOnlyモード等、要件に合わせて変更)
If projApp.FileOpen(filePath, ReadOnly:=False) Then
Set proj = projApp.ActiveProject

‘ — ここに業務ロジックを記述 —
‘ 例: ベースラインの保存
‘ proj.SaveBaseline BaselineNumber:=pjBaseline
‘ ——————————-

proj.Close SaveChanges:=pjSave
End If

Set proj = Nothing
projApp.Quit
Set projApp = Nothing
Exit Sub

ErrorHandler:
‘ エラーログをテキストファイル等に出力するのがプロの作法
Debug.Print “エラー発生: ” & filePath & ” – ” & Err.Description
If Not projApp Is Nothing Then projApp.Quit
End Sub

4. プロフェッショナルへのアドバイス

ファイルロックとパフォーマンス

大量のファイルを処理する場合、`projApp.Visible = False`は必須だ。しかし、これを行うと「ファイルが読み取り専用で開かれています」というダイアログが背後で停滞し、プログラムがハングアップすることがある。`projApp.DisplayAlerts = False`を併用し、ダイアログを強制的に閉じる設定を忘れるな。

データベース連携の罠

もし、この処理の結果をExcelやSQL Serverに書き出すなら、「1ファイル処理するごとに接続を切る」な。DBへのコネクションは重い。処理の冒頭でコネクションを張り、最後で閉じる。そして、ファイル処理中のデータはコレクションや配列に保持し、最後に一括でコミットする。これがパフォーマンスを最大化する鍵だ。

最後に

コードを書くことは、単なる作業ではない。そのコードが将来の自分、あるいはチームメンバーの時間をどれだけ節約するかを想像することだ。「動いた」で満足するな。「誰が保守しても壊れない」設計こそが、我々エンジニアの誇りであるべきだ。

さあ、このコードを武器に、プロジェクト管理という名の迷宮を攻略してほしい。健闘を祈る。

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