これは何
いろいろ設定をいじって動かしながら VBA を書いてるんだけど、VBA じゃ連想配列のリテラルを書くのもつらい。ってことで、JSON チックにコンフィグを書けるといいな、と思ったり、ヒアドキュメント風に書けたら VBE だけで開発できていいな、と思ったり。ということで、今現在、開発に使っている、コンフィグの使いかたをメモしておこう的なものがこの記事。
要求と解決策と実際の記述例
- JSON っぽく、配列や連想配列も書きたい
- [VBA-JSON](https://github.com/VBA-tools/VBA-JSON) で。長年の VBA における JSON 難民には嬉しいですね。VBA-JSON。
- VBE で完結させたい (コンフィグを別ファイルにしない)
- VSCode の拡張機能で XVBA というのがあって、VBE 外で開発できるかも、期待したけど、今書いてるの、Excel VBA じゃなくて Publisher VBA なんですよね。なんで、コンフィグ書くのも VBE で完結できると嬉しい。本当は VSCode で書きたいのよ。
- 設定以外の文字列があまりないようにしたい
- ヒアドキュメントがサポートされていない、複数行にわたる文字列が書けない、`&=` って表記もない VBA の制限の中で、設定を記述しているところに他の文字列があまり出現しないようにしたい。 結局、中で VBA-JSON を使う `Config` クラスを作ってみました (後述)。
- JSON の組立てを、
c.a "[1, 2, 3]"
とか書けるようにしている。文字列変数s
を用いてs = s & "[1, 2, 3]"
とか書かなくてよい。 - VBA の文字列としてダブルクォーテーションはダブルクォーテーションでエスケープしなくてはならくて辛いので、ダブルクォーテーションの代わりにアンダースコアを使ってもいいようにした。つまり、JSON として
{ "name": "Candy" }
と表現しなければならない場合、VBA の文字列リテラルとしては{ ""name"": ""Candy"" }
と書かなければならないわけだけど、タルいので{ _name_: _Candy_ }
と書いてもいいようにした。(Replace()
関数を使うだけ)- 連想配列のキーはダブルクォーテーションで括らなくてもいいようにした。
{ name: _Candy_ }
と書ける。(RegExp.Replace()
を使用)
- 連想配列のキーはダブルクォーテーションで括らなくてもいいようにした。
次に、コンフィグの実例を示します。
Module1.bas
Public Function getConf() As Object
Dim c As New Config
c.a "{"
c.a " deck: {"
c.a " top: 7, left: 7 "
c.a " },"
c.a " card: {"
c.a " size: 90, gap: 5 "
c.a " },"
c.a " chars: [[_莨_, _たばこ_ ], [_藜_, _あかざ_ ], [_菱_, _ひし_ ], [_莠_, _えのころぐさ_ ] ,"
c.a " [_蕨_, _わらび_ ], [_艾_, _もぐさ_ ], [_蓼_, _たで_ ], [_苓_, _みみなぐさ_ ],"
c.a " [_葎_, _むぐら_ ], [_菘_, _すずな_ ], [_蒜_, _ひる_ ], [_茆_, _じゅんさい_ ],"
c.a " [_菫_, _すみれ_ ], [_苧_, _からむし_ ], [_蕪_, _かぶ_ ], [_蕣_, _あさがお_ ],"
c.a " [_薊_, _あざみ_ ], [_萍_, _うきくさ_ ], [_芹_, _せり_ ], [_茅_, _かや_ ]],"
c.a " dish: {"
c.a " holeSize: 0.19, traySize: 0.22, mealSize: 0.20 "
c.a " pairs: ["
c.a " { x: 0.2, y:-0.01, z:0 }, { x: 0.38, y:-0.12, z:1 }, { x:-0.35, y: 0.36, z:1 },"
c.a " { x: 0.36, y: 0.34, z:0 }, { x:-0.2, y: 0.23, z:0 }, { x:-0.06, y: 0.38, z:1 },"
c.a " { x: 0.03, y: 0.19, z:1 }, { x: 0.37, y: 0.13, z:0 }, { x: 0.16, y: 0.38, z:1 }"
c.a " ]"
c.a " }"
c.a "}"
Set getConf = c.Value
End Function
Config
クラス
Config.cls
Private mBuffer As String
Private Sub Class_Initialize()
mBuffer = ""
End Sub
Public Function a(str As String) As Config
mBuffer = mBuffer & str
Set a = Me
End Function
Public Property Get Value() As Object
Dim reg As Object: Set reg = CreateObject("VBScript.RegExp")
With reg
.Pattern = "([a-zA-Z0-9]+)([ ]*)(?=:)"
.IgnoreCase = False
.Global = True
End With
Dim str As String: str = reg.Replace(Replace(mBuffer, "_", """"), """$1""")
' Debug.Print str
Set Value = JsonConverter.ParseJson(str)
End Property
工夫している点は、次のとおり。
追記 (2021-08-14 21:36)
VBA-JSON 自体に AllowUnquotedKeys
オプションがある模様。