【VBScript】FileSystemObject (FSO) を極める!ファイル・フォルダの安全な存在確認と作成・削除の実践パターン
みなさん、こんにちは!業務自動化の世界へようこそ。
Excelマクロ(VBA)の「マクロの記録」から一歩踏み出し、Windowsの標準環境である WSH(Windows Script Host) 上で動き回るVBScriptの世界に足を踏み入れたあなた。素晴らしい挑戦です!
VBScriptでファイルやフォルダを自由自在に操れるようになると、日常のデータ整理、ログ収集、定期バックアップといった地味で危険な手作業が一瞬で自動化できるようになります。
そして、そのファイル操作の中心に君臨するのが `Scripting.FileSystemObject`(通称:FSO) です。
今回は、単なるリファレンスの丸暗記ではなく、「なぜそう書くのか」「プロの現場ではどうエラーを防いでいるのか」という本質的な知見まで含めて、優しく丁寧に解説していきますね。ここをクリアすれば、VBScriptの基本はバッチリですよ!
—
1. FileSystemObject(FSO)の基本構造とライフサイクル
VBScriptでファイルシステムを操作するとき、最初に呼び出す「万能のツールボックス」がFSOです。
FSO生成のイメージ
イメージしてみてください。あなたのデスクトップ上に、OSのファイル管理機能と直接対話できる「伝説の執事(FSO)」を一人召喚するようなものです。
[ あなたのスクリプト ]
│
│ CreateObject(“Scripting.FileSystemObject”)
▼
┌─────────────────────────────────┐
│ FileSystemObject (執事) │
│ ├─ FolderExists / FileExists │ (存在確認)
│ ├─ CreateFolder / CreateTextFile│ (作成)
│ └─ DeleteFolder / DeleteFile │ (削除)
└─────────────────────────────────┘
│
▼
[ Windowsのファイルシステム (HDD/SSD) ]
COMオブジェクトのライフサイクル(生成と解放)
VBScriptにおいて、FSOのような外部コンポーネント(COMオブジェクト)を扱うときは、「生成(生)」と「解放(死)」を明示的に意識することがプロへの第一歩です。
Option Explicit ‘ 変数の明示的宣言を強制(凡ミスを無くすプロの嗜み)
‘ 1. オブジェクト変数の宣言
Dim fso
‘ 2. FSOのインスタンス化(召喚)
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ — ここでファイル操作を行う —
‘ 3. オブジェクトの破棄(解放)
Set fso = Nothing
VBScriptはスクリプト終了時に自動的にメモリを解放してくれますが、明示的に `Set fso = Nothing` と書く癖をつけておきましょう。長時間動く自動化プログラムにおいて、メモリリーク(メモリが解放されずに残り続ける現象)を防ぐ大切な作法です。
—
2. 【鉄則】「存在確認」なき操作は爆死のもと
初心者が最も陥りやすいエラー、それが「対象が存在しない(あるいは既に存在する)ことによる実行時エラー」です。
- フォルダを作成しようとしたのに、すでに同名フォルダが存在する ➔ エラー!
- ファイルを削除しようとしたのに、対象ファイルが存在しない ➔ エラー!
自動化スクリプトが夜間にひっそり動いているとき、こんなエラーで止まってしまったら悲しいですよね。だからこそ、操作の直前には必ず「存在確認」を挟むのが鉄則(ベストプラクティス)です。
存在確認メソッドの二大巨頭
- `fso.FolderExists(フォルダパス)` : フォルダが存在すれば `True`、なければ `False`
- `fso.FileExists(ファイルパス)` : ファイルが存在すれば `True`、なければ `False`
—
3. 実践:安全なファイル・フォルダ作成&削除のフルコード
それでは、開発現場でそのままコピペして使える「安全対策万全の標準コード」を見てみましょう。
以下のコードは、フォルダやファイルの存在を事前にチェックし、競合や非存在エラーを回避しながら作成・削除・ログ書き込みを行う完璧なフローです。
Option Explicit
‘ ——————————————————————-
‘ メイン処理
‘ ——————————————————————-
Dim fso
Dim targetFolderPath, targetFilePath
‘ FSOオブジェクトの生成
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ 操作対象のパスを定義(実行しているスクリプトと同じ場所の「TestFolder」)
Dim currentDir
currentDir = fso.GetAbsolutePathName(“.”) ‘ カレントディレクトリの取得
targetFolderPath = fso.BuildPath(currentDir, “TestFolder”)
targetFilePath = fso.BuildPath(targetFolderPath, “SampleLog.txt”)
WScript.Echo “=== ファイル操作自動化処理を開始します ===”
‘ — 1. フォルダの安全な作成 —
CreateFolderSafely fso, targetFolderPath
‘ — 2. ファイルの安全な作成とテキスト書き込み —
CreateAndWriteFileSafely fso, targetFilePath, “自動化スクリプトからのメッセージです。”
‘ 一時停止(動作確認用メッセージ)
MsgBox “フォルダとファイルを作成しました。” & vbCrLf & _
“OKを押すと、安全な削除処理に進みます。”, vbInformation, “確認”
‘ — 3. ファイルの安全な削除 —
DeleteFileSafely fso, targetFilePath
‘ — 4. フォルダの安全な削除 —
DeleteFolderSafely fso, targetFolderPath
‘ 後片付け(メモリ解放)
Set fso = Nothing
WScript.Echo “=== すべての処理が安全に完了しました ===”
‘ ——————————————————————-
‘ サブルーチン群(安全な操作パターン)
‘ ——————————————————————-
‘ 【安全なフォルダ作成】
Sub CreateFolderSafely(fsoObj, folderPath)
‘ 事前チェック:フォルダが既に存在するか?
If fsoObj.FolderExists(folderPath) Then
WScript.Echo “[スキップ] フォルダは既に存在します: ” & folderPath
Else
‘ 存在しない場合のみ作成
fsoObj.CreateFolder(folderPath)
WScript.Echo “[成功] フォルダを作成しました: ” & folderPath
End If
End Sub
‘ 【安全なファイル作成・書き込み】
Sub CreateAndWriteFileSafely(fsoObj, filePath, textContent)
Dim textStream
‘ Overwrite引数をTrueにすることで、存在する場合は上書き作成
‘ ForWriting = 2, Create = True
Set textStream = fsoObj.CreateTextFile(filePath, True, False)
textStream.WriteLine “書き込み日時: ” & Now()
textStream.WriteLine “内容: ” & textContent
textStream.Close ‘ 開いたストリームは必ず閉じる!
Set textStream = Nothing
WScript.Echo “[成功] ファイルを作成・更新しました: ” & filePath
End Sub
‘ 【安全なファイル削除】
Sub DeleteFileSafely(fsoObj, filePath)
‘ 事前チェック:ファイルが存在するか?
If fsoObj.FileExists(filePath) Then
‘ 第2引数を True にすると「読み取り専用ファイル」でも強制削除できる
fsoObj.DeleteFile filePath, True
WScript.Echo “[成功] ファイルを削除しました: ” & filePath
Else
WScript.Echo “[スキップ] 削除対象のファイルが存在しません: ” & filePath
End If
End Sub
‘ 【安全なフォルダ削除】
Sub DeleteFolderSafely(fsoObj, folderPath)
‘ 事前チェック:フォルダが存在するか?
If fsoObj.FolderExists(folderPath) Then
‘ 第2引数を True にすると「中身が入っている/読み取り専用」でも強制削除
fsoObj.DeleteFolder folderPath, True
WScript.Echo “[成功] フォルダを削除しました: ” & folderPath
Else
WScript.Echo “[スキップ] 削除対象のフォルダが存在しません: ” & folderPath
End If
End Sub
—
4. プロの視点:陥りやすい罠(エラー)と回避テクニック
上記のコードには、プロが現場で必ず組み込む「ノウハウ」が凝縮されています。初心者がハマりがちな3つの罠と、その回避法を解説しますね。
罠①:パス結合の罠(文字列連結 `\` の罠)
パスを結合するとき、`folderPath & “\” & fileName` のように `\` を手動で繋いでいませんか?
もし `folderPath` の末尾に最初から `\` が入っていたら、`C:\Test\\File.txt` のように二重スラッシュになってしまい、不具合の原因になります。
★回避テクニック:
`fso.BuildPath(親パス, 子パス)` メソッドを使いましょう!`\` の有無を自動で判定し、常に正しいパス文字列を生成してくれます。
罠②:読み取り専用属性(ReadOnly)による削除エラー
普通に `fso.DeleteFile(filePath)` を実行したとき、そのファイルが「読み取り専用」に設定されていると、VBScriptは 「書き込み違反(エラー 70)」 を起こしてストップしてしまいます。
★回避テクニック:
`fso.DeleteFile filePath, True` のように、第2引数(Force)に `True` を指定します。これで読み取り専用属性が付いていても強制的に削除してくれます(フォルダ削除の `DeleteFolder` も同様です)。
罠③:開いたままのファイル(ロック)の罠
`CreateTextFile` や `OpenTextFile` で開いたファイルストリーム(`textStream`)を `.Close` し忘れると、ファイルがロックされた状態になります。その直後に `DeleteFile` を呼ぶと、Windowsに拒否されてエラーになります。
★回避テクニック:
ファイルを開いたら、「使い終わったら即 `.Close` して `Set Nothing`」。この対(ペア)の意識を徹底しましょう!
—
5. さらにワンランク上へ!万全のエラーハンドリング
存在チェックをしていても、権限不足(アクセス拒否)やファイルロックなど、どうしても防ぎきれない例外が発生することがあります。そうした現場の猛者に必須のテクニックが `On Error Resume Next` による制御です。
‘ エラーが発生してもスクリプトを強制終了させず、次の行へ進める宣言
On Error Resume Next
‘ 削除を実行
fso.DeleteFile targetFilePath, True
‘ エラーが発生したか判定
If Err.Number <> 0 Then
WScript.Echo “【警告】ファイルの削除に失敗しました。”
WScript.Echo “エラー番号: ” & Err.Number
WScript.Echo “エラー詳細: ” & Err.Description
Err.Clear ‘ エラー情報をクリア
Else
WScript.Echo “ファイルの削除に成功しました。”
End If
‘ エラー制御を通常状態(エラー発生で停止)に戻す
On Error GoTo 0
`On Error Resume Next` は強力ですが、コード全体に効かせっぱなしにすると「どこでエラーが起きたか分からない」暗黒状態に陥ります。「危険な処理の直前に有効化し、処理が終わったらすぐに `On Error GoTo 0` で解除する」 のが熟練エンジニアの流儀です。
—
6. まとめ
お疲れ様でした!今回の要点を振り返ってみましょう。
1. FSOの生成と解放: `CreateObject` で呼び出し、最後は `Set Nothing` で閉じる。
2. パスの安全な結合: `\` の直手打ちではなく `fso.BuildPath` を使う。
3. 事前チェックの徹底: 作成前・削除前に必ず `FolderExists` / `FileExists` を挟む。
4. 強制削除オプション: 削除処理には `Force = True` を指定して属性の罠を回避する。
5. 例外の局所管理: 予期せぬエラーには `On Error Resume Next` をピンポイントで適用する。
ここまでの理解ができれば、VBScriptにおけるファイル操作の基礎・土台は完璧に固まりました!
マクロの自動記録から抜け出し、スクリプトの構造とエラーハンドリングを意識できるようになると、プログラミングは一気に楽しくなります。
ぜひ今回のコードを手元の環境(`.vbs` ファイルとして保存)で動かしてみて、その快適さを体感してみてくださいね。応援しています!
