在Windows上的Excel VBA中,如何减轻由IDE的大小写行为破坏的解析JSON的点语法遍历问题?

时间:2016-06-08 19:13:11

标签: json excel vba

在Windows上的Excel VBA中,如何减轻由IDE的大小写行为破坏的解析JSON的点语法遍历问题?

嗨,在这里回答我自己的问题。我已经在Excel VBA中使用JSON做了一些工作,并发布了大量的发现,我将在Q&格式 https://stackoverflow.com/help/self-answer http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/

所以在stackoverflow的其他地方,人们可以看到有关在VBA中解析JSON的问题但他们似乎错过了一两招。

首先,我不再使用自定义JSON解析库,而是使用ScriptControl的Eval方法作为我所有JSON代码的基础。 此外,我们还表达了对本机Microsoft解决方案的偏好。

在第一个问题中,我将展示在Excel VBA中,实际上可以使用点语法来遍历JSON结构但不幸的是,这是 受到VBA IDE"有用性的打击"关于资本化。

下面是一些示例代码,其中标有1的行:我们可以看到文本" objJSON.key1"并且此代码有效,直到一个取消注释

'Tools->References->
'Microsoft Script Control 1.0;  {0E59F1D2-1FBE-11D0-8FF2-00A0D10038BC}; C:\Windows\SysWOW64\msscript.ocx

Option Explicit
Option Private Module

Private Sub TestJSONParsingWithVBACallByName()

    Dim oScriptEngine As ScriptControl
    Set oScriptEngine = New ScriptControl
    oScriptEngine.Language = "JScript"

    Dim sJsonString As String
    sJsonString = "{'key1': 'value1'  ,'key2': { 'key3': 'value3' } }"


    Dim objJSON As Object
    Set objJSON = oScriptEngine.Eval("(" + sJsonString + ")")
1:  Debug.Assert objJSON.key1 = "value1"
    Debug.Assert objJSON.key2.key3 = "value3"

    '**** BUT IF UNCOMMENT NEXT LINE THIS AFFECTS ALL CAPITALISATION INSTANCES OF KEY1 INCLUDING LINE 1 WHICH THENCE BREAKS
2:  'Dim Key1 as Long

End Sub

以下是截图 BeforeUncommentedAnnotated 在取消注释第2行之后,Line1将被重写为符号' key1'现在给了一个资本' K'。

AfterCommentedAnnoted

现在经过一些实验后,似乎重写效果仅限于项目范围,因此其他项目不受影响。 这意味着可以通过始终使用单独的项目来隔离问题,但是如何将对象编组到消费项目中 从那里访问它,肯定会再次遇到同样的问题。因此,项目隔离并不是真正的解决方案。

一种方法是确保符号不会发生冲突并为JSON键提供某种前缀,所以这里是一个例子

'Tools->References->
'Microsoft Script Control 1.0;  {0E59F1D2-1FBE-11D0-8FF2-00A0D10038BC}; C:\Windows\SysWOW64\msscript.ocx

Private Sub TestJSONParsingWithDotSyntaxAndKeyPrefixesToAvoidNameClash()

    Dim oScriptEngine As ScriptControl
    Set oScriptEngine = New ScriptControl
    oScriptEngine.Language = "JScript"

    Dim sJsonString As String
    sJsonString = "{'kKey1': 'value1'  ,'kKey2': { 'kKey3': 'value3' } }"


    Dim objJSON As Object
    Set objJSON = oScriptEngine.Eval("(" + sJsonString + ")")
1:  Debug.Assert objJSON.kKey1 = "value1"
    Debug.Assert objJSON.kKey2.kKey3 = "value3"

    '**** SAFE TO UNCOMMENT AS SYMBOLS DO NOT CLASH NOW
2:  'Dim Key1 As Long
End Sub

不知怎的,我不喜欢这个,似乎很奇怪,只需更改JSON,以便VBA可以访问它。此外,人们可能无法控制源JSON。

还有其他方法,例如向脚本引擎添加一些javscript以允许Javascript进行访问。对于用户Codo https://stackoverflow.com/users/413337/codo的帽子提示,这是基于这种方法的样本......

'Tools->References->
'Microsoft Script Control 1.0;  {0E59F1D2-1FBE-11D0-8FF2-00A0D10038BC}; C:\Windows\SysWOW64\msscript.ocx

Private Sub TestJSONParsingWithMiniScript()
    'hat tip to Codo https://stackoverflow.com/users/413337/codo
    'Based on https://stackoverflow.com/questions/5773683/excel-vba-parsed-json-object-loop#7300963  
    Dim oScriptEngine As ScriptControl
    Set oScriptEngine = New ScriptControl
    oScriptEngine.Language = "JScript"
    oScriptEngine.AddCode "function getProperty(jsonObj, propertyName) { return jsonObj[propertyName]; } "


    Dim sJsonString As String
    sJsonString = "{'key1': 'value1'  ,'key2': { 'key3': 'value3' } }"

    Dim objJSON As Object
    Set objJSON = oScriptEngine.Eval("(" + sJsonString + ")")
    Debug.Assert oScriptEngine.Run("getProperty", objJSON, "key1") = "value1"
    Debug.Assert oScriptEngine.Run("getProperty", oScriptEngine.Run("getProperty", objJSON, "key2"), "key3") = "value3"

End Sub

我喜欢将脚本添加到脚本引擎的技术但是,我发现了一种更原生的技术,那就是使用VBA.CallByName 这就是我的答案所示的技巧。

我没有选择自己的答案作为权威,因为我认为 (1)似乎社区可以继续提高我们在Excel VBA和JBA中进行JSON解析的知识 (2)如果有人发现如何停止资本化,那么这显然是赢家。

这是5系列的问题1.这是完整系列

Q1 In Excel VBA on Windows, how to mitigate issue of dot syntax traversal of parsed JSON broken by IDE's capitalisation behaviour?

Q2 In Excel VBA on Windows, how to loop through a JSON array parsed?

Q3 In Excel VBA on Windows, how to get stringified JSON respresentation instead of “[object Object]” for parsed JSON variables?

Q4 In Windows Excel VBA,how to get JSON keys to pre-empt “Run-time error '438': Object doesn't support this property or method”?

Q5 In Excel VBA on Windows, for parsed JSON variables what is this JScriptTypeInfo anyway?

1 个答案:

答案 0 :(得分:2)

最后,我使用了原生的VBA.CallByName

进行了以下操作
'Tools->References->
'Microsoft Script Control 1.0;  {0E59F1D2-1FBE-11D0-8FF2-00A0D10038BC}; C:\Windows\SysWOW64\msscript.ocx

Private Sub TestJSONParsingWithCallByName()

    Dim oScriptEngine As ScriptControl
    Set oScriptEngine = New ScriptControl
    oScriptEngine.Language = "JScript"

    Dim sJsonString As String
    sJsonString = "{'key1': 'value1'  ,'key2': { 'key3': 'value3' } }"


    Dim objJSON As Object
    Set objJSON = oScriptEngine.Eval("(" + sJsonString + ")")
    Debug.Assert VBA.CallByName(objJSON, "key1", VbGet) = "value1"
    Debug.Assert VBA.CallByName(VBA.CallByName(objJSON, "key2", VbGet), "key3", VbGet) = "value3"

End Sub