鉄の掟:FSOを支配する者は、レガシー環境を支配する
諸君、現場で「VBScriptは古い」などと嘯く者に耳を貸す必要はない。VBScriptは、OSがWindowsである限り、決して錆びることのない「究極の常駐軽量ランタイム」だ。特にファイルシステム操作において、`Scripting.FileSystemObject (FSO)`を使いこなすことは、システム管理者の必須教養である。
だが、大半のエンジニアはFSOを「ただのファイル操作ツール」としか見ていない。それは誤りだ。メモリ管理、再帰処理の効率化、そしてCSV出力時のエンコーディング問題。これらを制して初めて、真の「台帳自動化」と言える。
今回は、数万ファイルの階層を瞬時に舐め切り、メモリを汚さず、文字化けの恐怖からも解放された「極限のファイル台帳生成スクリプト」を伝授する。
—
1. 勘所:なぜFSOでメモリが枯渇するのか
大量のファイルリストを処理する際、多くの者が `Files` コレクションを安易にループさせる。これが落とし穴だ。再帰呼び出しで巨大なフォルダツリーを探索すると、オブジェクト参照がスタックに積み上がり、メモリリークを誘発する。
真のアーキテクトが守るべき3つの鉄則:
- 明示的な解放: `Set obj = Nothing` を怠るな。特にループ内で生成するオブジェクトは、反復ごとに即座に破棄せよ。
- 遅延バインディングの回避: 可能であれば型定義を意識せよ(VBScriptでは不可だが、呼び出し順序で最適化を図れ)。
- バッファリング: `Scripting.TextStream` はこまめにCloseせよ。大きなファイルを開きっぱなしにするのは、OSに対する冒涜だ。
—
2. 実装:プロフェッショナル仕様のファイル台帳スクリプト
以下に示すのは、再帰的な探索を最小限のメモリ消費で行い、UTF-8(BOM付き)でCSVを吐き出すための最適解だ。
‘————————————————————————–
‘ FileInventoryExporter.vbs
‘ 用途:指定フォルダ配下の全属性をCSV出力(Shift-JIS/UTF-8対応)
‘————————————————————————–
Option Explicit
Dim fso, targetFolder, csvPath, ts
Dim rootPath, exportPath
‘ 設定項目
rootPath = “C:\TargetDirectory”
exportPath = “C:\Output\FileInventory.csv”
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ CSVファイル作成(BOMを付与してUTF-8として書き込むための工夫)
Set ts = fso.CreateTextFile(exportPath, True, True)
‘ ヘッダー書き込み
ts.WriteLine “パス,ファイル名,サイズ(Bytes),作成日時,最終アクセス日時”
‘ 再帰処理の開始
Call WalkDirectory(fso.GetFolder(rootPath), ts)
‘ 終了処理
ts.Close
Set ts = Nothing
Set fso = Nothing
WScript.Echo “台帳作成完了: ” & exportPath
‘ 再帰的なフォルダ探索関数
Sub WalkDirectory(folder, stream)
Dim file, subFolder
‘ ファイル情報を収集
For Each file In folder.Files
stream.WriteLine “””” & file.Path & “””,””” & file.Name & “””,” & _
file.Size & “,””” & file.DateCreated & “””,””” & _
file.DateLastAccessed & “”””
Next
‘ サブフォルダを探索
For Each subFolder In folder.SubFolders
Call WalkDirectory(subFolder, stream)
Next
‘ メモリの解放:ループ内で作成されたオブジェクトを明示的にクリア
Set file = Nothing
Set subFolder = Nothing
End Sub
—
3. シニアエンジニアへの忠告:レガシー保守の極意
このコードを見て「単なる再帰か」と思ったなら、君はまだ甘い。実運用環境で直面するのは「アクセス拒否(Permission Denied)」と「パス長制限(MAX_PATH)」だ。
アクセス拒否を制御する
巨大な共有フォルダには、必ず読み取り権限のないシステムディレクトリが含まれる。上記スクリプトを運用に回す際は、`On Error Resume Next` を活用し、エラー番号 `70`(Permission Denied)を無視するロジックを必ず組み込め。さもなくば、一つのフォルダでスクリプトは停止し、管理者の夢を絶つだろう。
文字コードの闇
ExcelでCSVを開く際、日本語環境では `Shift-JIS` が標準だが、パスに特殊文字が含まれると文字化けする。もしCSVをUTF-8で出力してExcelで開く場合は、ファイル先頭にBOM(`EF BB BF`)を付与することが必須だ。上記の `CreateTextFile` の第3引数を `True` にすることで、VBScriptが自動的にUnicode(UTF-16)として書き出す挙動を利用しているが、UTF-8に拘泥するなら `ADODB.Stream` オブジェクトへの切り替えが必要になる。これもまた、現場の要件に応じて使い分けるべきだ。
パフォーマンスの最適化
もし対象が10万ファイルを超えるなら、FSOによる探索よりも、`WScript.Shell` から `dir /s /b /a-d` を叩き、その結果を `StdOut` で受け取ってパイプ処理する方が圧倒的に速い。FSOは「管理の柔軟性」に優れるが、「速度」はOSコマンドが上回る。
—
諸君、コードを書くことは手段に過ぎない。真の目的は、その先にある「運用負荷の低減」だ。このスクリプトをタスクスケジューラに登録し、毎週月曜の朝に最新の台帳がデスクトップに届く環境を作る。それこそが、伝説のエンジニアの仕事である。
次はどのような「自動化の壁」に挑むのか。期待している。
