VBScriptの壁を越える:階層の深淵に挑む「多段フォルダ自動生成」の極意
「マクロの記録」や、ネットで見つけた断片的なコードを組み合わせて、ようやく自動化の第一歩を踏み出したあなたへ。
素晴らしい一歩です。しかし、プログラミングの道には、初心者たちが必ずと言っていいほど突き当たる「見えない壁」が存在します。その一つが、「フォルダを作ろうとしたら、エラーで止まってしまった」という問題です。
今回は、VBScriptにおけるファイル操作の要、`FileSystemObject` (FSO) の仕様を深く理解し、どんなに深い階層のフォルダ指定でも、まるで魔法のように一瞬で作り上げる「プロ仕様の関数」を一緒に構築していきましょう。
ここをクリアすれば、あなたのVBScriptは「単なる記録」から「真の自動化ツール」へと進化しますよ。
1. なぜ `CreateFolder` は失敗するのか?
まず、多くの人が陥るエラーの正体を知っておきましょう。
VBScriptでフォルダを作成する際、私たちはよく `FileSystemObject` の `CreateFolder` メソッドを使います。しかし、このメソッドには「親となるフォルダが既に存在していなければならない」という、非常に厳格なルールがあります。
失敗するシナリオの図解
例えば、あなたが `C:\Work\Project\2023\Data` というフォルダを一気に作りたいとしましょう。
- あなたの理想: 「`C:\Work\Project\2023\Data` を作って!」
- FSOの思考: 「えっ、`C:\Work\Project\2023` ってどこ? そんな場所知らないよ。じゃあ、エラー(パスが見つかりません)を出して終了するね」
このように、FSOは「一気に階段を駆け上がる」ことはできません。一段ずつ、一段ずつ、確実に足場を確認しながら登っていく必要があるのです。
2. 解決策:パスを「分解」して「再構築」する
この問題を解決するエンジニアの思考はシンプルです。
「パスをバラバラの部品(パーツ)に分解し、一つずつ存在を確認しながら、順番に組み立てていく」のです。
具体的には、以下のステップを踏みます。
1. パスを分割する: `\`(バックスラッシュ/円記号)を区切り文字として、フォルダ名をバラバラにする。
2. 土台を作る: まず、ドライブ(`C:` など)からスタートする。
3. 一歩ずつ進む: 分割したパーツを一つずつ結合していき、「その階層が存在するか?」をチェックする。
4. 足りなければ作る: 存在しなければ `CreateFolder` で作成する。存在すればそのまま次へ進む。
この「再帰的」とも言える考え方こそが、堅牢なプログラムを作るための設計思想です。
3. 実装:多段サブフォルダ自動生成関数
それでは、実際に現場でそのまま使える、美しく堅牢なコードを書いてみましょう。
' ==========================================================================
' 題名: 多段サブフォルダ自動生成関数 (CreateFolderRecursive)
' 概要: 指定されたパスの全階層をチェックし、存在しないフォルダを順次作成する。
' 引数: strPath (String) - 作成したいフルパス
' 戻り値: Boolean - 成功すれば True, 失敗すれば False
' ==========================================================================
Function CreateFolderRecursive(strPath)
Dim objFSO, arrParts, strCurrentPath, i
' FileSystemObjectの生成(オブジェクトのライフサイクル管理)
Set objFSO = CreateObject("Scripting.FileSystemObject")
' パスを "\" で分割して配列に格納
' 例: "C:\Work\Data" -> Array("C:", "Work", "Data")
arrParts = Split(strPath, "\")
' 最初の要素(ドライブ名など)を現在のパスの起点とする
' ただし、Splitの結果、先頭が空になる場合への配慮が必要
If arrParts(0) = "" Then
' パスが "\Work\Data" のように始まる場合の処理
strCurrentPath = "\"
Else
strCurrentPath = arrParts(0)
End If
' 配列の2番目(インデックス1)から順番に組み立てていく
For i = 1 To UBound(arrParts)
' 次の階層のパスを組み立てる
' strCurrentPath の末尾に "\" があるかどうかで結合方法を制御
If Right(strCurrentPath, 1) = "\" Then
strCurrentPath = strCurrentPath & arrParts(i)
Else
strCurrentPath = strCurrentPath & "\" & arrParts(i)
End If
' 【ここが核心】フォルダが存在するかチェック
If Not objFSO.FolderExists(strCurrentPath) Then
' 存在しない場合のみ、作成を実行
On Error Resume Next ' エラー発生時にスクリプトが止まらないようガード
objFSO.CreateFolder(strCurrentPath)
If Err.Number <> 0 Then
' 作成に失敗した場合(権限不足など)
WScript.Echo "Error: フォルダの作成に失敗しました -> " & strCurrentPath
CreateFolderRecursive = False
Exit Function
End If
On Error GoTo 0 ' エラーハンドリングを通常の状態に戻す
End If
Next
' すべての階層が正常に処理されたら True を返す
CreateFolderRecursive = True
' オブジェクトの解放(メモリ管理の作法)
Set objFSO = Nothing
End Function
' --- テスト実行セクション ---
Dim targetPath
' ここに作成したい深い階層のパスを指定してください
targetPath = "C:\Temp\TestProject\Level1\Level2\Level3"
WScript.Echo "処理を開始します: " & targetPath
If CreateFolderRecursive(targetPath) Then
WScript.Echo "成功: すべての階層が準備できました。"
Else
WScript.Echo "失敗: フォルダの作成中に問題が発生しました。"
End If
4. コードの深層:プロが意識している3つのポイント
このコードには、単なる「動くコード」を超えた、エンジニアとしてのこだわりが詰まっています。
① オブジェクトのライフサイクル管理
コードの最後にある `Set objFSO = Nothing`。これは、使い終わった道具(オブジェクト)を片付ける作業です。VBScriptはメモリ管理を自動で行いますが、大規模な処理や長時間動くスクリプトでは、このように明示的に「解放」することで、メモリの無駄遣いを防ぎ、システムの安定性を高めることができます。
② `On Error Resume Next` の賢い使い方
エラーが発生したとき、プログラムはパニックを起こして止まってしまいます。しかし、何でもかんでもエラーを無視するのは危険です。
今回のコードでは、「フォルダ作成という、外部環境に左右される不安定な操作」の直前だけでエラー回避を有効にし、失敗したときには即座に理由を報告して終了するように設計しています。これが「制御されたエラーハンドリング」です。
③ パスの結合における「境界線」の意識
パスを繋げる際、`\` が重複したり、逆に足りなくなったりすることはよくあります。`Right(strCurrentPath, 1) = “\”` という判定を入れることで、どのようなパス形式が来ても、常に正しいパスを維持できるようになっています。
5. まとめ:次は「ファイル操作」へ
お疲れ様でした。あなたは今、単にコマンドを並べるだけの初心者から、「システムの構造を理解して、不測の事態に備える設計者」への一歩を踏み出しました。
今回作成した `CreateFolderRecursive` 関数は、一度作ってしまえば、あなたの強力な武器になります。これからは、ファイルを保存する前にこの関数を呼び出すだけで、「フォルダがないからエラーになった」という悩みから永遠に解放されるでしょう。
「仕組みを理解し、一つずつ組み立てる。」
この考え方は、VBScriptだけでなく、PythonやJavaScript、あるいは将来あなたが学ぶどんな言語にも共通する、エンジニアにとっての「真理」です。
ここをクリアしたあなたなら、次はもっと複雑な自動化も、きっと自由に操れるようになりますよ。応援しています!
