【環境依存の脱却】ScriptFullNameとGetParentFolderNameを用いたポータブルな相対パス解決テクニック
業務自動化の現場において、VBScriptは今なおインフラの裏側やレガシーなバッチ処理の要として静かに、しかし強烈な存在感を放っている。
しかし、多くの開発現場でいまだに散見されるのが、「ハードコーディングされたパス」の呪縛だ。
‘ 【アンチパターン】絶対にやってはいけないハードコーディング
Set file = fso.OpenTextFile(“C:\Users\Admin\Desktop\Project\config.ini”, 1)
このコードを書いた瞬間、そのスクリプトは「作成者のPCの、特定のフォルダ」という環境依存の檻に閉じ込められる。担当者が変わり、共有サーバーに移動し、あるいはフォルダ名を少し変えただけで、エラーコード `800A0035`(ファイルが見つかりません)が容赦なく吐き出される。
プロフェッショナルな自動化エンジニアであれば、スクリプトは「どこに置いても自律して動作する(ポータブルであること)」が大原則だ。今回は、FSO(FileSystemObject)の真価を引出し、環境依存を完全に排除するパス解決の極意を伝授する。
—
1. なぜ「カレントディレクトリ(`”.”`)」に頼ってはいけないのか?
VBScript初心者が陥る罠の一つに、`CurrentDirectory` や相対パスの単純指定がある。
‘ 危険な書き方
Set file = fso.OpenTextFile(“config.ini”, 1)
一見すると「同じフォルダにあるんだから動くだろう」と思いがちだが、これは大きな間違いだ。
VBScriptを実行する際のカレントディレクトリは、「スクリプトが置いてある場所」とは限らない。 コマンドプロンプトから別の場所で実行された場合や、ショートカット経由、タスクスケジューラからの実行では、カレントディレクトリは全く別の場所(System32など)を指してしまう。
結果として、ファイルが見つかったり見つからなかったりする、極めて不安定な「不具合の爆弾」が爆誕する。
—
2. 解決の鍵:`ScriptFullName` と `GetParentFolderName` のシナジー
この問題を一刀両断するのが、WScriptオブジェクトの `ScriptFullName` と、FileSystemObjectの `GetParentFolderName` の組み合わせだ。
- `WScript.ScriptFullName`
- 現在実行中の `.vbs` ファイル自身のフルパスを、実行時のカレントディレクトリに左右されることなく絶対に正確に取得する。
- `FSO.GetParentFolderName(path)`
- 渡されたパスからファイル名を除外り、親フォルダのパスだけを正確に抽出する。
この2つを結合させることで、「スクリプトが今どこに存在するか」という絶対的な真実を起点としたパスを動的に生成できる。
—
3. 【プロダクションコード】堅牢なパス解決テンプレート
実際の業務ツールでそのまま使える、保守性と安全性に振り切ったコードパターンを提示する。設定ファイルやログフォルダを確実に同階層に捉えるための決定版だ。
Option Explicit
‘ =====================================================================
‘ ツール名: ポータブル・パス解決テンプレート
‘ 概要 : スクリプトの実行場所に依存せず、同階層のリソースにアクセスする
‘ =====================================================================
Sub Main()
Dim fso, scriptDir, configPath, logDir
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ 1. 自身の絶対パスから「親フォルダ(実行場所)」を完全特定する
scriptDir = fso.GetParentFolderName(WScript.ScriptFullName)
‘ 2. 基準フォルダを起点に、相対的なパスを結合(BuildPathを使用)
configPath = fso.BuildPath(scriptDir, “config.ini”)
logDir = fso.BuildPath(scriptDir, “logs”)
‘ 3. 実行前バリデーション(存在チェック)
If Not fso.FileExists(configPath) Then
MsgBox “致命的なエラー: 必須設定ファイルが見つかりません。” & vbCrLf & _
“パス: ” & configPath, vbCritical, “起動中止”
Exit Sub
End If
‘ 4. ログ用フォルダがなければ自動生成する(自己修復機能)
If Not fso.FolderExists(logDir) Then
fso.CreateFolder(logDir)
End If
‘ — ここから実際の業務ロジック —
Call ProcessWorkflow(fso, configPath, logDir)
Set fso = Nothing
End Sub
Sub ProcessWorkflow(fso, configPath, logDir)
‘ 設定ファイルの読み込み例
Dim configFile
Set configFile = fso.OpenTextFile(configPath, 1) ‘ ForReading
MsgBox “設定ファイルを正常にロードしました。” & vbCrLf & _
“処理を継続します。”, vbInformation, “実行中”
configFile.Close
Set configFile = Nothing
End Sub
‘ エントリポイントの呼び出し
Call Main()
—
4. プロが教える設計上の極意と注意点
上記のコードには、単にパスを結合するだけではない、実務で生き残るための知見が凝縮されている。
① 文字列結合に `&` を使わず `BuildPath` を使え
パスを繋ぐ際、`scriptDir & “\config.ini”` と書くエンジニアが多いが、これはバグの温床だ。もし `scriptDir` の末尾に既にバックスラッシュ(`\`)が含まれていた場合、`C:\\config.ini` のような不正なパスになり、FSOが沈黙する。
`fso.BuildPath(path1, path2)` は、スラッシュの有無を自動でハンドリングして正しいパスを構築する。必ずこれを使うべきだ。
② 「フェイルファスト(Fail Fast)」の原則
スクリプトが走り出した後、中盤でファイルが見つからずにエラーで落ちる設計は最悪だ。
処理の初期段階(今回で言えば `Main` の冒頭)で必要なファイルの存在をチェックし、足りなければ即座にユーザーへ明確なメッセージを出して終了させる。これがプロの設計である。
③ フォルダの「自己修復(Self-Healing)」
データ出力先やログ保存用のフォルダは、環境構築時に人間が手動で作らせてはならない。
スクリプト側で `FolderExists` を確認し、なければ `CreateFolder` で自動生成するロジックをコード内に内包させる。これにより、「フォルダを作り忘れた」というくだらない問い合わせをゼロにできる。
—
総括
VBScriptのようなレガシーな言語を扱うときほど、エンジニアの「設計の差」が如実に現れる。
ハードコーディングという悪習を断ち切り、`ScriptFullName` と `GetParentFolderName` を使いこなすことで、あなたの書く自動化ツールは「どこに持って行っても壊れない、極めて頑丈なモジュール」へと生まれ変わる。
環境依存からの完全なる脱却——今日からそのコードを書き換えよう。
