【入門編】【実務中級者向け】FSOとWScript.Shell環境変数の組み合わせによる「%APPDATA%」配下のログ自動一括収集 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク
スポンサーリンク

脱・初心者!環境変数とFSOを操り、動的なファイル収集ツールを構築する

「自分のPCでは動くのに、同僚のPCに持っていくと動かない……」

もしあなたが今、そんな壁にぶつかっているとしたら、おめでとうございます。あなたは今、単なる「コードの書き写し」から、真の「ソフトウェアエンジニアリング」への入り口に立っています。

プロの現場では、パスを `C:\Users\Tanaka\AppData\…` のように直接書き込む(ハードコーディングする)ことは、禁忌中の禁忌です。なぜなら、ユーザー名が変わればそのコードは一瞬でゴミに変わるからです。

今日は、VBScriptの強力な武器であるWScript.Shellによる環境変数の解決と、FileSystemObject (FSO) によるファイル操作を組み合わせ、どんなユーザー環境でもスマートに動作する「ログ一括収集ツール」を構築する方法を伝授します。

ここをクリアすれば、VBScriptの基本はバッチリですよ。さあ、一緒に見ていきましょう。

1. なぜ「環境変数」が必要なのか?

Windowsの世界には、ユーザーごとに異なる「お決まりの場所」があります。
例えば、アプリケーションの設定やログが格納される `%APPDATA%` フォルダ。これは、ログインしているユーザーによってパスが劇的に変わります。

  • ユーザーAの場合: `C:\Users\UserA\AppData\Roaming`
  • ユーザーBの場合: `C:\Users\UserB\AppData\Roaming`

この違いを吸収するのが、環境変数の展開(ExpandEnvironmentStrings)です。これを使わずにパスを指定するのは、地図を持たずに知らない街を歩くようなものです。

2. 武器の紹介:WScript.Shell と FileSystemObject

今回のミッションを完遂するために、2つの強力なオブジェクトを使い分けます。

① WScript.Shell(翻訳者)

このオブジェクトの役割は、`%APPDATA%` という「記号」を、実際の `C:\Users\…\AppData\Roaming` という「実体のあるパス」に翻訳することです。`ExpandEnvironmentStrings` メソッドがその鍵となります。

② FileSystemObject / FSO(職人)

パスが判明したあと、実際に「フォルダがあるか確認する」「フォルダを作る」「ファイルをコピーする」といった実務を行うのがFSOです。ファイルシステムという広大な大地を操作するための、最も信頼できる道具箱です。

3. 実践:ログ自動収集スクリプト

それでは、具体的なコードを見ていきましょう。
このスクリプトは、「特定のアプリのログフォルダを探し出し、デスクトップに日付付きのフォルダを作って、そこにログをすべて集約する」という動きをします。

' ==========================================================================
' ログ自動一括収集スクリプト
' 概要: %APPDATA% 配下の特定アプリログを、デスクトップへ集約する
' ==========================================================================

Option Explicit ' 変数の宣言を強制(スペルミス防止の鉄則!)

' オブジェクトの宣言
Dim objShell, objFSO
Dim strAppDataPath, strDesktopPath, strTargetLogPath, strDestFolder
Dim strAppName, strTimestamp, objFolder, objFile

' 設定値(ここを変更するだけで使い回せます)
strAppName = "MyAwesomeApp" ' 対象とするアプリ名(フォルダ名)
strTimestamp = Year(Date) & Month(Date) & Day(Date) & "_" & Hour(Now) & Minute(Now)

' --- 1. オブジェクトの生成 ---
Set objShell = CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")

' --- 2. 環境変数の動的解決(ここがエンジニアの腕の見せ所!) ---
' %APPDATA% を実際のパスに変換
strAppDataPath = objShell.ExpandEnvironmentStrings("%APPDATA%")
' %USERPROFILE% を使ってデスクトップへのパスを生成
strDesktopPath = objShell.ExpandEnvironmentStrings("%USERPROFILE%") & "\Desktop"

' 収集対象のパス(例: %APPDATA%\MyAwesomeApp\Logs)
strTargetLogPath = strAppDataPath & "\" & strAppName & "\Logs"

' 保存先のパス(例: デスクトップ\Collected_Logs_20231027_1430)
strDestFolder = strDesktopPath & "\Collected_Logs_" & strTimestamp

' --- 3. メイン処理 ---

' エラーハンドリングの開始(予期せぬエラーで止まらないように)
On Error Resume Next

' A. 収集元フォルダが存在するか確認
If Not objFSO.FolderExists(strTargetLogPath) Then
    MsgBox "エラー: ログフォルダが見つかりません。" & vbCrLf & strTargetLogPath, vbCritical, "収集失敗"
    WScript.Quit
End If

' B. 保存先フォルダの作成
If Not objFSO.FolderExists(strDestFolder) Then
    objFSO.CreateFolder(strDestFolder)
End If

' C. ファイルのコピー処理
Set objFolder = objFSO.GetFolder(strTargetLogPath)

Dim count
count = 0

For Each objFile In objFolder.Files
    ' ファイルをコピー(Trueは「同名ファイルがあれば上書き」の指示)
    objFile.Copy strDestFolder & "\" & objFile.Name, True
    
    If Err.Number = 0 Then
        count = count + 1
    Else
        ' 個別のファイルコピーに失敗した場合のログ(デバッグ用)
        ' WScript.Echo "失敗: " & objFile.Name & " (" & Err.Description & ")"
        Err.Clear
    End If
Next

' エラーハンドリングの終了
On Error GoTo 0

' --- 4. 結果報告 ---
If count > 0 Then
    MsgBox "成功! " & count & " 個のログを以下に集約しました。" & vbCrLf & strDestFolder, vbInformation, "完了"
Else
    MsgBox "コピーできるファイルがありませんでした。", vbExclamation, "通知"
End If

' --- 5. 後片付け(オブジェクトの解放) ---
' ライフサイクルを意識して、使い終わったオブジェクトは明示的に解放するのがプロの作法
Set objFile = Nothing
Set objFolder = Nothing
Set objFSO = Nothing
Set objShell = Nothing

4. プロの視点:ここが「差」がつくポイント

コードをただ動かすだけでなく、なぜこのように書いたのか。その「意図」を理解することが、中級者へのステップアップです。

① `Option Explicit` の魔力

スクリプトの冒頭にあるこの一行。これは「すべての変数を必ず宣言してから使いなさい」という命令です。これがないと、`strPath` と書くべきところを `strPathe` と打ち間違えても、VBScriptは新しい変数として勝手に認識してしまい、原因不明のバグを生みます。「ミスを事前に防ぐ」のは、プログラミングにおいて最も重要な技術の一つです。

② エラーハンドリング `On Error Resume Next`

ファイル操作は、常に「失敗する可能性」を孕んでいます。ファイルが使用中だったり、権限がなかったり……。
`On Error Resume Next` を使うことで、エラーが発生してもスクリプトを強制終了させず、次の処理へ進めることができます。ただし、「エラーが起きたら `Err.Number` を確認する」というセットの動きを忘れないでください。

③ オブジェクトのライフサイクル(解放)

コードの最後で行っている `Set objFSO = Nothing`。
VBScriptはガベージコレクション(自動メモリ回収)機能を持っていますが、大規模なツールや長時間動かすツールを作る場合、明示的にオブジェクトを解放する癖をつけておきましょう。これは「メモリのリソースを適切に管理する」という、エンジニアとしての美しい規律です。

まとめ:次はどんなツールを作りますか?

今回のコードで、あなたは「環境に依存しない、汎用性の高いツール」の作り方を学びました。

1. WScript.Shell で環境変数を解決し、パスの不確実性を排除する。
2. FSO でファイルシステムの操作を確実に行う。
3. エラー処理とオブジェクト解放 で、堅牢なプログラムにする。

この3ステップさえマスターすれば、次に作るツールはもっと複雑で、もっと便利なものになるはずです。

「マクロの記録」の卒業、おめでとうございます。ここからが、あなたのエンジニアとしての本当の旅の始まりですよ!

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