VBScriptを掌握せよ:ネストされたDictionaryを「フラット化」するアーキテクトの極意
VBScriptで業務自動化を設計している諸君。`Scripting.Dictionary` を深く理解しているか?
多くのジュニアエンジニアは、Dictionaryを単なる「連想配列」として使い、ネスト構造に直面した途端、場当たり的な `If…Then` の応酬でコードを汚染する。これは保守性の死を意味する。今日のテーマは、複雑な階層データを1次元の `parent.child.key` 形式へ昇華させる「再帰的フラット化」だ。
なぜこれが重要か? 設定ファイル(JSONに近い構造)やAPIレスポンスをデータベースへ投入、あるいはCSVへエクスポートする際、再帰処理を知らぬ者は、構造が変わるたびにコードを書き直す羽目になるからだ。
1. なぜ「再帰」でなければならないのか
階層の深さが不確定なデータに対し、ループで力技をしようとすると、ネストの数だけコードを深くせねばならない。それは「密結合」の極致だ。
再帰関数を使えば、コードの複雑性は「階層の深さ」ではなく「処理の単位」に依存するようになる。これにより、未知の深さを持つデータ構造に対しても、単一のロジックで対応可能になる。これが堅牢な自動化エンジニアが持つべき視点だ。
2. 実装:堅牢なフラット化アルゴリズム
以下に、プロダクション環境でも耐えうる設計のコードを示す。ポイントは「再帰呼び出し時にパスを継承する」ことだ。
‘ — FlattenDictionary.vbs —
Option Explicit
‘ 動作確認用メインルーチン
Dim rootDict, flatDict
Set rootDict = CreateObject(“Scripting.Dictionary”)
‘ ネストデータの構築
Dim childDict
Set childDict = CreateObject(“Scripting.Dictionary”)
childDict.Add “name”, “Project_Alpha”
childDict.Add “status”, “Active”
rootDict.Add “id”, 101
rootDict.Add “meta”, childDict
‘ フラット化実行
Set flatDict = CreateObject(“Scripting.Dictionary”)
Call FlattenDictionary(rootDict, “”, flatDict)
‘ 結果出力
Dim key
For Each key In flatDict.Keys
WScript.Echo key & ” = ” & flatDict(key)
Next
‘ — 再帰的フラット化関数 —
‘ 責務:ネストされたDictionaryを走査し、ドット繋ぎのキーへ変換する
Sub FlattenDictionary(objDict, prefix, ByRef targetDict)
Dim key, newKey, val
For Each key In objDict.Keys
‘ 新しいキーパスを生成(ルート階層ならそのまま、それ以外はドット連結)
If prefix = “” Then
newKey = key
Else
newKey = prefix & “.” & key
End If
Set val = Nothing ‘ 型安全のためにリセット
‘ 型判定:Dictionaryなら再帰、それ以外は値として格納
If IsObject(objDict(key)) Then
If TypeName(objDict(key)) = “Dictionary” Then
‘ 階層を深くして自分自身を再帰呼び出し
Call FlattenDictionary(objDict(key), newKey, targetDict)
Else
‘ オブジェクトがDictionary以外の場合はそのまま格納(適宜拡張)
targetDict.Add newKey, objDict(key)
End If
Else
targetDict.Add newKey, objDict(key)
End If
Next
End Sub
3. アーキテクトからの設計上の忠告
このコードを実務に組み込む際、以下の点に注意せよ。これが「動くコード」を「保守可能な資産」に変える境界線だ。
① 参照渡し(ByRef)の活用
`targetDict` を引数として渡すことで、再帰先でも同一メモリ上のDictionaryへ結果を書き込める。これはメモリ効率を最適化するテクニックであり、戻り値でDictionaryを生成してマージするような低効率な処理を避けるための必須知識だ。
② 型安全とバリデーション
VBScriptの `IsObject` は危険な場合がある。`TypeName()` を併用せよ。`Nothing` や予期せぬオブジェクトが混入した際、型チェックを怠ると実行時エラーでスクリプトが即死する。「未知のデータは常に例外を吐くもの」として設計せよ。
③ 循環参照の検知(上級者向け)
もし入力データがWeb API由来で、意図せず循環参照を持っている場合、上記のコードは無限再帰(Stack Overflow)を引き起こす。必要に応じて「処理済みのオブジェクトID」を保持するリストを追加し、再帰のガード条件として機能させる必要がある。
4. 最後に:自動化の真髄
自動化とは、単に手作業を置き換えることではない。「将来の変更を予測し、構造で解決すること」だ。
この再帰アルゴリズムを一度作ってしまえば、どんなに複雑な入れ子構造を持つJSONライクな設定ファイルが来ても、諸君は動じないはずだ。VBScriptは古い言語と言われるが、その本質を理解したエンジニアの手にかかれば、現代のシステムにおいても驚異的な威力を発揮する。
さあ、コードを書き換えろ。場当たり的な修正は捨て、再帰という「美学」を実装に落とし込むのだ。それが、プロのエンジニアの流儀である。
