【実務・中級編】【JSONエンコーダー自作】Dictionary と Array から正しいエスケープ処理済みのJSON文字列を生成するライブラリ – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

現代のエンタープライズ開発において、VBScriptは「枯れた技術」と揶揄されることもある。しかし、WSH(Windows Script Host)やRPAの現場において、この軽量でOS標準の実行環境がいかに強力な武器であるかを、真のアーキテクトは知っている。

VBScriptには標準のJSONライブラリが存在しない。多くのエンジニアはここで「外部COMコンポーネント」や「JScriptの eval への依存」といった安易な道を選ぶ。だが、それでは「環境依存の脆弱性」と「パフォーマンスの不透明性」を抱え込むことになる。

今回は、`Scripting.Dictionary` と `Array` を極限まで使いこなし、再帰処理と厳密なエスケープ処理を実装した、プロフェッショナル仕様のJSONエンコーダーを構築する。

1. なぜ「自作」が必要なのか:エスケープの罠

JSON文字列を生成する際、単に値をダブルクォーテーションで囲むだけでは不十分だ。
以下の3点は、素人コードとプロダクションコードを分ける決定的な境界線となる。

1. 制御文字の処理: 改行(CRLF)やタブ文字を `\n` `\r` `\t` に変換しなければ、出力されたJSONは即座にパースエラーを起こす。
2. バックスラッシュの二重化: Windowsのパス文字列(`C:\Temp`)を扱う際、`\` を `\\` とエスケープしなければならない。
3. 型推論の厳密性: VBScriptの `Empty`、`Null`、`Nothing` を、JSONの `null` にどうマッピングするか。

これらを完全に掌握してこそ、堅牢な自動化ツールと言える。

2. アーキテクチャ設計:再帰によるツリー構造の走査

JSONは入れ子構造(ツリー構造)だ。これを処理するには「再帰(Recursion)」が最も美しい解となる。

  • Object: `Scripting.Dictionary` を JSONの `{}` に対応させる。
  • Array: VBScriptの `Array` を JSONの `[]` に対応させる。
  • Value: 文字列、数値、ブール値、そして `Null`。

これらを動的に判別し、型に応じたフォーマットを適用するエンジンを実装する。

3. 極限のプロダクションコード:JsonEncoder ライブラリ

以下のコードは、保守性を高めるためにクラス化を検討してもよいが、VBScriptのポータビリティを最大限に活かすため、単一モジュールで動作する関数群として設計している。


‘ JSON Encoder for VBScript (WSH)

‘ 役割: Dictionary/Array を標準JSONフォーマットへシリアライズする
‘ 特徴: 再帰処理、制御文字エスケープ、型判定の厳密化

Option Explicit

”’

”’ オブジェクト(Dictionary/Array)をJSON文字列に変換する
”’

Function JsonEncode(ByVal val)
Dim result
Select Case VarType(val)
Case vbEmpty, vbNull
result = “null”
Case vbString
result = “””” & JsonEscape(val) & “”””
Case vbBoolean
result = IIf(val, “true”, “false”)
Case vbInteger, vbLong, vbSingle, vbDouble, vbCurrency, vbDecimal, vbByte
result = CStr(val)
Case vbDate
‘ ISO 8601形式の簡易版。必要に応じて調整
result = “””” & CStr(Year(val)) & “-” & Right(“0” & Month(val), 2) & “-” & Right(“0” & Day(val), 2) & “”””
Case vbObject
‘ Dictionary (JSON Object) の処理
If TypeName(val) = “Dictionary” Then
result = EncodeDictionary(val)
ElseIf val Is Nothing Then
result = “null”
Else
Err.Raise 5000, “JsonEncode”, “Unsupported Object Type: ” & TypeName(val)
End If
Case Else
‘ Array (JSON Array) の処理
If IsArray(val) Then
result = EncodeArray(val)
Else
result = “””” & JsonEscape(CStr(val)) & “”””
End If
End Select
JsonEncode = result
End Function

”’

”’ DictionaryをJSONオブジェクト形式に変換
”’

Private Function EncodeDictionary(ByRef dict)
Dim keys, key, i, items()
keys = dict.Keys
ReDim items(dict.Count – 1)

For i = 0 To dict.Count – 1
key = keys(i)
items(i) = “””” & JsonEscape(CStr(key)) & “””:” & JsonEncode(dict.Item(key))
Next

EncodeDictionary = “{” & Join(items, “,”) & “}”
End Function

”’

”’ 配列をJSON配列形式に変換
”’

Private Function EncodeArray(ByRef arr)
Dim i, items()
ReDim items(UBound(arr))

For i = 0 To UBound(arr)
items(i) = JsonEncode(arr(i))
Next

EncodeArray = “[” & Join(items, “,”) & “]”
End Function

”’

”’ JSON特殊文字および制御文字のエスケープ処理
”’

Private Function JsonEscape(ByVal str)
If IsNull(str) Then Exit Function
Dim s: s = str
s = Replace(s, “\”, “\\”)
s = Replace(s, “”””, “\”””)
s = Replace(s, “/”, “\/”)
s = Replace(s, vbCr, “\r”)
s = Replace(s, vbLf, “\n”)
s = Replace(s, vbTab, “\t”)
‘ その他必要に応じて制御文字を追加
JsonEscape = s
End Function

”’

”’ IIf 代替関数
”’

Private Function IIf(ByVal condition, ByVal truePart, ByVal falsePart)
If condition Then IIf = truePart Else IIf = falsePart
End Function

4. 現場での実践:データベース連携とファイル出力の急所

このエンコーダーを実務で使う際、特に重要なのが「データベース(ADODB.Recordset)」との連携だ。

データベースからの変換例

データベースのレコードをそのままこの関数に投げ込むことはできない。一度 `Dictionary` の配列に変換するのがアーキテクトの流儀だ。

‘ DBレコードセットをJSON化するロジックの断片
Dim recordList: Set recordList = CreateObject(“Scripting.Dictionary”)
Dim i: i = 0

Do Until rs.EOF
Dim row: Set row = CreateObject(“Scripting.Dictionary”)
Dim field
For Each field In rs.Fields
row.Add field.Name, field.Value
Next

‘ 配列として格納するためにインデックスをキーにするか、別途動的配列に入れる
‘ ここではシンプルに配列管理とする
‘ … (配列リサイズ処理) …
rs.MoveNext
Loop

パフォーマンスへの配慮

VBScriptの文字列連結(`&` 演算子)は、数万行におよぶ巨大なJSONを生成する場合、メモリコピーのオーバーヘッドにより急激に低速化する。
本コードでは `Join(items, “,”)` を採用している。これは、一度配列に要素を溜めてから一気に結合する手法で、VBScriptにおける最高速の文字列連結テクニックである。

ファイル出力のエンコーディング

`FileSystemObject` の `CreateTextFile` はデフォルトで ANSI 出力となる。JSONは UTF-8 が標準であるため、BOMなしUTF-8で出力するには `ADODB.Stream` を使用すべきだ。

5. 結論:コードに魂は宿っているか

今回紹介した `JsonEncode` は、シンプルながらも「型リフレクション」「再帰構造」「文字列アルゴリズム」という、計算機科学の基礎をVBScriptという制約の中で具現化したものだ。

優れたエンジニアは、新しい言語を知っていることではなく、手元にある道具の限界性能を120%引き出し、かつバグを寄せ付けない堅牢な設計ができることでその価値を証明する。

このコードをあなたのライブラリに加え、ブラックボックスになりがちなVBScript資産を、モダンなシステムと対等に渡り合える「一級のコンポーネント」へと昇華させてほしい。

タイトルとURLをコピーしました