VBScriptを掌握せよ:外部ツール不要、Shell.ApplicationによるZIP圧縮・解凍の極意
業務自動化の現場において、「7-ZipやWinRARをインストールできない」という制約は、情シス部門が敷く堅牢なセキュリティポリシー下では日常茶飯事だ。しかし、ここで諦めるのは二流のエンジニアである。
Windows標準の `Shell.Application` オブジェクトを使いこなせば、外部依存ゼロで堅牢なアーカイブ処理を実装できる。今回は、単にコードを提示するのではなく、「なぜこの設計が実務で耐えうるのか」という本質的な観点から、プロダクション環境でも通用する実装テクニックを伝授する。
—
1. Shell.Applicationの「闇」と「正解」
多くの初心者が犯すミスは、圧縮処理に `CopyHere` メソッドを使用する際、非同期処理であることを考慮せずスクリプトを即座に終了させてしまうことだ。
`Shell.Application` のコピー操作はバックグラウンドで行われる。スクリプトが即座に終了すると、ZIP生成途中でプロセスが強制終了し、破損した0バイトのZIPファイルが残る。これが「動いたり動かなかったりする」というバグの正体だ。
我々は、ファイルの存在確認と、処理完了までの「ウェイト」を厳密に制御する必要がある。
—
2. 実務向け実装:堅牢なZIP圧縮コード
以下のコードは、単なるコピペコードではない。指定ディレクトリをZIP化し、処理が完了するまで待機する排他制御の概念を組み込んでいる。
‘ — 堅牢なZIP圧縮関数 —
Sub CreateZip(targetFolder, zipFilePath)
Dim shellApp, fso, zipFile
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set shellApp = CreateObject(“Shell.Application”)
‘ 空のZIPファイルを生成(ヘッダー情報を書き込む)
If Not fso.FileExists(zipFilePath) Then
Dim header: header = Chr(80) & Chr(75) & Chr(5) & Chr(6) & String(18, 0)
Set zipFile = fso.CreateTextFile(zipFilePath, True)
zipFile.Write header
zipFile.Close
End If
‘ 圧縮処理:CopyHereでディレクトリ内を格納
‘ 4+16+1024 は「進捗ダイアログ非表示」「エラーダイアログ非表示」「ファイルを上書きしない」等のオプション
shellApp.NameSpace(zipFilePath).CopyHere shellApp.NameSpace(targetFolder).Items, 4 + 16 + 1024
‘ 重要:圧縮完了を待機するためのループ(ファイルサイズが安定するまで待つ)
Do While shellApp.NameSpace(zipFilePath).Items.Count = 0
WScript.Sleep 500
Loop
Set shellApp = Nothing
Set fso = Nothing
End Sub
—
3. 実務で「絶対に踏んではいけない」地雷
① パスの絶対指定
VBScriptにおいて相対パスは「実行時のカレントディレクトリ」に依存する。タスクスケジューラから実行する場合、カレントディレクトリが `System32` になり、予期せぬ場所へZIPが生成されることが多い。`WScript.ScriptFullName` から親フォルダを取得し、常にフルパスで指定する癖をつけろ。
② ファイルロックの競合
データベース連携やログ収集を行う際、書き込み中のファイルをZIP化しようとすれば当然例外が発生する。`On Error Resume Next` で誤魔化すのではなく、`fso.GetFile(path).Size` を定期的にチェックし、ファイルがロックされていないことを確認してから処理に回すのがプロの流儀だ。
③ 文字コードの罠
`Shell.Application` は非常に優秀だが、ファイル名に特殊なマルチバイト文字が含まれる場合、希に化けることがある。ファイル名には極力ASCII文字を使用するか、どうしても必要な場合は事前にリネーム処理を挟む設計にすべきだ。
—
4. なぜ今、VBScriptなのか
「今はPythonやPowerShellの時代だ」という声は聞こえる。しかし、VBScriptには「環境を汚さない」という圧倒的な優位性がある。 インストール権限が不要、DLLの依存関係に頭を悩ませる必要もない。
このコードをただのスクリプトとして終わらせるな。
1. ログ出力: 処理開始と終了をテキストファイルに残す。
2. 例外処理: `Err.Number` を監視し、エラー発生時は即座に管理者へ通知する。
3. 設定の外部化: パスや閾値を `.ini` や `.json` で切り出す。
これらを組み合わせれば、VBScriptは立派な「エンタープライズ級の自動化ツール」へと進化する。
現場の課題を技術で解決する。それがエンジニアの矜持だ。
次に自動化すべきルーチンワークを、今すぐこのコードで過去のものにしてやれ。
