I have the same issue as in Excel VBA: Parsed JSON Object Loop but cannot find any solution. My JSON has nested objects so suggested solution like VBJSON and vba-json do not work for me. I also fixed one of them to work properly but the result was a call stack overflow because of to many recursion of the doProcess function.

The best solution appears to be the jsonDecode function seen in the original post. It is very fast and highly effective; my object structure is all there in a generic VBA Object of type JScriptTypeInfo.

The issue at this point is that I cannot determine what will be the structure of the objects, therefore, I do not know beforehand the keys that will reside in each generic objects. I need to loop through the generic VBA Object to acquire the keys/properties.

If my parsing javascript function could trigger a VBA function or sub, that would be excellent.

推荐答案

If you want to build on top of ScriptControl, you can add a few helper method to get at the required information. The JScriptTypeInfo object is a bit unfortunate: it contains all the relevant information (as you can see in the Watch window) but it seems impossible to get at it with VBA. However, the Javascript engine can help us:

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

以下是几点注意事项:

  • If the JScriptTypeInfo instance refers to a Javascript object, For Each ... Next won't work. However, it does work if it refers to a Javascript array (see GetKeys function).
  • 只有在运行时才知道其名称的访问属性使用函数GetPropertyGetObjectProperty.
  • Javascript数组提供属性length0Item 01Item 1等.使用VBA点表示法(jsonObject.property),只有长度属性是可访问的,并且只有在声明一个名为length的变量时,才使用所有小写字母.否则案子就不匹配,也找不到.其他属性在VBA中无效.所以最好使用GetProperty函数.
  • The code uses early binding. So you have to add a reference to "Microsoft Script Control 1.0".
  • You have to call InitScriptEngine once before using the other functions to do some basic initialization.

Json相关问答推荐

基于两个条件替换扁平化的SON中的值

Swift解码错误类型与`Bool`type不一致

如何在使用GO时检测JSON中不需要的字段?

kotlinx-serialization:如何将具有不同类型对象的JsonArray转换为同一个Class

如何在JQ过滤器文件中使用多行?

Vegalite中分组条形图中的偏移量问题

将pyspark.sql.Rowtype数据转换为Json字符串,消除Azure Databricks NB中的值

VSCode 为 python 文件添加标尺,但不为 C 文件添加标尺.为什么?

转换为Json时忽略内部对象中的数组

如何将 JSON 文本作为参数传递给 powershell?

在 PostgreSQL 中 Select 分层 JSON 作为表

PowerShell:如何将哈希表输出为 json 并使用 foreach 循环将其存储在变量中?

如何在 onClick 事件处理程序中识别在同一 map 上绘制的多个多边形中的哪个(使用 react-leaflet)被单击?

JSON Schema 与 XML Schema 的比较及其future

JSON 模式验证

Qt使用QJsonDocument、QJsonObject、QJsonArray解析JSON

如何在 json 编码字符串内的子数组数据周围添加方括号?

如何在已声明的 JSON 对象中添加键值对

如何将有向无环图 (DAG) 存储为 JSON?

如何将 mysqli 结果转换为 JSON?