FSOに頼らない「パスの解決」:VBScriptで相対パスを絶対パスへ変換する極意
こんにちは。自動化の現場でVBScriptの泥臭い仕様と長く付き合ってきたエンジニアです。
皆さんは、ファイル操作で「相対パス(`../config.ini`など)」に泣かされたことはありませんか?通常、VBScriptでこれを扱うには`FileSystemObject`の`GetAbsolutePathName`メソッドを使うのが定石です。しかし、実行環境の制約でFSOが使えない、あるいは「パスの構造そのものを文字列としてパースしたい」という特殊な要件に直面することもあるでしょう。
今日は、あえてFSOという「魔法の杖」を置き、純粋な文字列操作だけで相対パスを絶対パスに展開するアルゴリズムを伝授します。これを知れば、パスの概念を完全に掌握できたと言っても過言ではありません。
—
なぜ「パスの解決」が難しいのか?
パスの解決とは、迷路のようなものです。「`..`(一つ上の階層)」という命令に出会うたびに、現在の階層を一つ戻る。この単純なルールを、プログラムに正確に教え込む必要があります。
陥りやすい罠は以下の通りです:
- パスの区切り文字の不一致:`/` と `\` が混在する環境への対応。
- ルートディレクトリでの誤作動:一番上の階層で `..` をしても、それ以上戻れないことを制御できるか。
- 空の要素の無視:`//` のような冗長な区切りをどう処理するか。
これらをクリアするロジックを一緒に構築しましょう。
—
実装:相対パス解決アルゴリズム
以下の関数 `ResolvePath` は、ベースとなるパスと、相対パスを受け取り、正しい絶対パスを返します。
‘ 相対パスを絶対パスに変換する関数
Function ResolvePath(basePath, relativePath)
Dim fullPath, parts, part, stack
‘ 1. 区切り文字を統一(全て\に変換)
fullPath = Replace(basePath & “\” & relativePath, “/”, “\”)
parts = Split(fullPath, “\”)
‘ 2. 結果を格納するためのスタックを用意
Set stack = CreateObject(“Scripting.Dictionary”)
Dim count : count = 0
‘ 3. パスをパースしてスタックに積み上げる
Dim i
For i = 0 To UBound(parts)
part = parts(i)
Select Case part
Case “”, “.”
‘ 空文字(冗長な区切り)や現在の階層(.)は無視
Case “..”
‘ 一つ上の階層へ戻る(スタックから削除)
If count > 0 Then
count = count – 1
stack.Remove count
End If
Case Else
‘ 通常のディレクトリ・ファイル名を積む
stack.Add count, part
count = count + 1
End Select
Next
‘ 4. スタックを結合してパスを再構築
Dim result
For i = 0 To count – 1
result = result & stack(i) & “\”
Next
‘ 末尾の\を削除して返す(空の場合はルートを返す)
If Len(result) > 0 Then
ResolvePath = Left(result, Len(result) – 1)
Else
ResolvePath = “\”
End If
End Function
‘ — 実行例 —
Dim base : base = “C:\Projects\VBScript\Scripts”
Dim rel : rel = “..\Data\.\config.txt”
WScript.Echo “絶対パス: ” & ResolvePath(base, rel)
‘ 結果: C:\Projects\VBScript\Data\config.txt
—
コードのここがポイント!
1. 「スタック」という考え方
このコードの心臓部は `Scripting.Dictionary` をスタック(積み上げ構造)として利用している点です。`..` が出てきたら、一番上に積んだ要素を `Remove` で取り除く。この「戻る」操作を明示的に行うことで、複雑な階層移動も確実に処理できます。
2. 冗長な記述を「無視」する
`Case “”, “.”` の部分です。パスの中に `//` があったり、`./` があっても、プログラムはこれらを「何もしない」と判断してスキップします。これにより、どんなに汚いパス入力でもクリーンな形に整形されます。
3. FSOに依存しない強み
外部オブジェクトに依存しないため、セキュリティ制限が厳しい環境や、WSHの権限が最小限の環境でも安定して動作します。これが、現場で生き抜くための「エンジニアの引き出し」です。
—
最後に:ここをクリアすれば、あなたはもう中級者です
パスのパースは、一見地味ですが、プログラムが「今どこにいるのか」を理解するための最も重要な基盤です。このロジックを理解できたあなたは、もうマクロの記録をなぞるだけの人ではありません。
「なぜそう動くのか」を突き詰める姿勢こそが、VBScriptという古くからの言語を操る上で最も大切な資質です。この関数をあなたのツールボックスに入れて、ぜひ現場の自動化に役立ててください。
何か不明な点や、さらに深いチューニングが必要な場合は、いつでも聞いてくださいね。一緒に最強のスクリプトを育てていきましょう!
