LoginSignup
0
0

More than 1 year has passed since last update.

VBA のヒアドキュメント風 JSON チックコンフィグ

Last updated at Posted at 2021-08-14

これは何

いろいろ設定をいじって動かしながら VBA を書いてるんだけど、VBA じゃ連想配列のリテラルを書くのもつらい。ってことで、JSON チックにコンフィグを書けるといいな、と思ったり、ヒアドキュメント風に書けたら VBE だけで開発できていいな、と思ったり。ということで、今現在、開発に使っている、コンフィグの使いかたをメモしておこう的なものがこの記事。

要求と解決策と実際の記述例


JSON っぽく、配列や連想配列も書きたい

VBA-JSON で。長年の VBA における JSON 難民には嬉しいですね。VBA-JSON。

VBE で完結させたい (コンフィグを別ファイルにしない)

VSCode の拡張機能で XVBA というのがあって、VBE 外で開発できるかも、期待したけど、今書いてるの、Excel VBA じゃなくて Publisher VBA なんですよね。なんで、コンフィグ書くのも VBE で完結できると嬉しい。本当は VSCode で書きたいのよ。

設定以外の文字列があまりないようにしたい

ヒアドキュメントがサポートされていない、複数行にわたる文字列が書けない、&= って表記もない VBA の制限の中で、設定を記述しているところに他の文字列があまり出現しないようにしたい。
結局、中で VBA-JSON を使う Config クラスを作ってみました (後述)。

次に、コンフィグの実例を示します。

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

工夫している点は、次のとおり。
* 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() を使用)

追記 (2021-08-14 21:36)

VBA-JSON 自体に AllowUnquotedKeys オプションがある模様。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0