json - Excel VBA : Parsed JSON Object Loop

标签 json excel vba scriptcontrol

按照下面的示例...从已解析的 JSON 字符串循环访问对象会返回错误“对象不支持此属性或方法”。谁能建议如何使这项工作有效?非常感谢(在提问之前我花了 6 个小时寻找答案)。

将 JSON 字符串解析为对象的函数(这可以正常工作)。

Function jsonDecode(jsonString As Variant)
    Set sc = CreateObject("ScriptControl"): sc.Language = "JScript" 
    Set jsonDecode = sc.Eval("(" + jsonString + ")")
End Function

循环解析的对象会返回错误“对象不支持此属性或方法”。

Sub TestJsonParsing()
    Dim arr As Object 'Parse the json array into here
    Dim jsonString As String

    'This works fine
    jsonString = "{'key1':'value1','key2':'value2'}"
    Set arr = jsonDecode(jsonString)
    MsgBox arr.key1 'Works (as long as I know the key name)

    'But this loop doesn't work - what am I doing wrong?
    For Each keyName In arr.keys 'Excel errors out here "Object doesn't support this property or method"
        MsgBox "keyName=" & keyName
        MsgBox "keyValue=" & arr(keyName)
    Next
End Sub 
PS。我已经研究过这些库:

-vba-json无法使示例正常运行。
-VBJSON不包含 vba 脚本(这可能有效,但不知道如何将其加载到 Excel 中,并且文档最少)。

此外,是否可以访问多维解析的 JSON 数组?只要让一个基本的键/值数组循环工作就很好了(抱歉,如果要求太多)。谢谢。

<小时/>

编辑:这里有两个使用 vba-json 库的工作示例。但上面的问题仍然是个谜......

Sub TestJsonDecode() 'This works, uses vba-json library
    Dim lib As New JSONLib 'Instantiate JSON class object
    Dim jsonParsedObj As Object 'Not needed

    jsonString = "{'key1':'val1','key2':'val2'}"
    Set jsonParsedObj = lib.parse(CStr(jsonString))

    For Each keyName In jsonParsedObj.keys
        MsgBox "Keyname=" & keyName & "//Value=" & jsonParsedObj(keyName)
    Next

    Set jsonParsedObj = Nothing
    Set lib = Nothing
End Sub

Sub TestJsonEncode() 'This works, uses vba-json library
    Dim lib As New JSONLib 'Instantiate JSON class object
    Set arr = CreateObject("Scripting.Dictionary")

    arr("key1") = "val1"
    arr("key2") = "val2"

    MsgBox lib.toString(arr)
End Sub

最佳答案

JScriptTypeInfo 对象有点不幸:它包含所有相关信息(正如您在Watch 窗口中看到的那样),但似乎无法使用VBA。

如果 JScriptTypeInfo 实例引用 Javascript 对象,则 For Each ... Next 将不起作用。但是,如果它引用 Javascript 数组,它确实可以工作(请参阅下面的 GetKeys 函数)。

因此,解决方法是再次使用 Javascript 引擎来获取我们无法使用 VBA 获取的信息。首先,有一个函数可以获取 Javascript 对象的键。

一旦您知道了 key ,下一个问题就是访问属性。如果键的名称仅在运行时已知,VBA 也无济于事。因此有两种方法可以访问对象的属性,一种用于值,另一种用于对象和数组。

Option Explicit

Private ScriptEngine As ScriptControl

Public Sub InitScriptEngine()
    Set ScriptEngine = New ScriptControl
    ScriptEngine.Language = "JScript"
    ScriptEngine.AddCode "function getProperty(jsonObj, propertyName) { return jsonObj[propertyName]; } "
    ScriptEngine.AddCode "function getKeys(jsonObj) { var keys = new Array(); for (var i in jsonObj) { keys.push(i); } return keys; } "
End Sub

Public Function DecodeJsonString(ByVal JsonString As String)
    Set DecodeJsonString = ScriptEngine.Eval("(" + JsonString + ")")
End Function

Public Function GetProperty(ByVal JsonObject As Object, ByVal propertyName As String) As Variant
    GetProperty = ScriptEngine.Run("getProperty", JsonObject, propertyName)
End Function

Public Function GetObjectProperty(ByVal JsonObject As Object, ByVal propertyName As String) As Object
    Set GetObjectProperty = ScriptEngine.Run("getProperty", JsonObject, propertyName)
End Function

Public Function GetKeys(ByVal JsonObject As Object) As String()
    Dim Length As Integer
    Dim KeysArray() As String
    Dim KeysObject As Object
    Dim Index As Integer
    Dim Key As Variant

    Set KeysObject = ScriptEngine.Run("getKeys", JsonObject)
    Length = GetProperty(KeysObject, "length")
    ReDim KeysArray(Length - 1)
    Index = 0
    For Each Key In KeysObject
        KeysArray(Index) = Key
        Index = Index + 1
    Next
    GetKeys = KeysArray
End Function


Public Sub TestJsonAccess()
    Dim JsonString As String
    Dim JsonObject As Object
    Dim Keys() As String
    Dim Value As Variant
    Dim j As Variant

    InitScriptEngine

    JsonString = "{""key1"": ""val1"", ""key2"": { ""key3"": ""val3"" } }"
    Set JsonObject = DecodeJsonString(CStr(JsonString))
    Keys = GetKeys(JsonObject)

    Value = GetProperty(JsonObject, "key1")
    Set Value = GetObjectProperty(JsonObject, "key2")
End Sub

注意:

  • 代码使用早期绑定(bind)。因此您必须添加对“Microsoft Script Control 1.0”的引用。
  • 在使用其他函数进行一些基本初始化之前,您必须调用一次InitScriptEngine

关于json - Excel VBA : Parsed JSON Object Loop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5773683/

相关文章:

excel - Range.Formula 由于变量而给出运行时错误

php - JSON - 斜杠不转义

javascript - 为什么 [object Object] 提到 "object"两次?

javascript - 为 JavaScript 客户端编码/解码大量数据的最佳方式?

ios - Json - 准备继续查看详细信息

java - Apache poi + Java : Write to a worksheet without deleting existing data

vba - Excel VBA 循环通过工作表失败

vba - 如何使用VBA中的CopyMemory在内存映射文件中存储数据和从内存映射文件中取出数据?

arrays - 将所有工作表数据打印到用户表单文本框中

vba - 将用户窗体声明为对象与 MSForms.Userform 之间的区别?