Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
VBA JSON-解析多个值_Json_Vba_Parsing - Fatal编程技术网

VBA JSON-解析多个值

VBA JSON-解析多个值,json,vba,parsing,Json,Vba,Parsing,使用带有多值键的JSON-VBA转换器时遇到问题 我编写了常规的递归例程来导航JSON树,但这里有一个简单的JSON解析示例,我似乎无法使用它 看看这个,这是非常棒和快速的 环境:Windows 7/Access 2016/专用局域网(无互联网) 代码如下: Option Compare Database Option Explicit Sub testparse() Dim js As String, i As Long, jo As Object, item As Variant Dim

使用带有多值键的JSON-VBA转换器时遇到问题

我编写了常规的递归例程来导航JSON树,但这里有一个简单的JSON解析示例,我似乎无法使用它

看看这个,这是非常棒和快速的

环境:Windows 7/Access 2016/专用局域网(无互联网)

代码如下:

Option Compare Database
Option Explicit

Sub testparse()
Dim js As String, i As Long, jo As Object, item As Variant
Dim keys(), vals()

' fails on this string
js = "{ !Category!: !Famous Pets!," & _
  "!code!: [!a!,!b!,!c!] }"            ' string with multiple values

' with the following string, this works
js = "{ !Category!: !Famous Pets!," & _
  "    !code!: !singlecodevalue! }"

js = Replace(js, "!", Chr(34)) ' replace ! with quotes

Debug.Print " js = " & js
Set jo = JsonConverter.ParseJson(js) ' returns object with json elements
i = 0
ReDim keys(1 To jo.Count)
ReDim vals(1 To jo.Count)

Debug.Print " Number keys found at top level " & jo.Count
For Each item In jo
    i = i + 1
    keys(i) = item
    vals(i) = jo(item)
    Next item

For i = 1 To jo.Count
    Debug.Print "key " & keys(i) & " = " & vals(i)
    Next i

End Sub



对于在JSON对象中运行时遇到的每一项,都必须确定要处理的内容——特别是如果您事先不知道数组中有多少项!如果您有一个复合JSON结构,其中包含数组等内部的集合,那么它会变得更加复杂

底线是,在访问JSON对象之前,必须检查从JSON对象中提取的每个项目,并弄清楚它是什么。JSON对象的顶层(假设使用了
JsonConverter
)将始终是
字典
。因此,您可以通过顶级字典的键进行循环:

Dim json As Dictionary
Set json = JsonConverter.ParseJson(someJsonString)

Dim topLevelKey As String
For Each topLevelKey In json
    Dim item As Variant
    Debug.Print topLevelKey & " = " & item
Next topLevelKey 
问题是
并不总是一个简单的字符串。它可以是一个值(
String
)、一个数组(
Collection
)或一个组(
Dictionary
)。作为一个很好的参考

基本上,这意味着您必须在使用前检查每个
项目。所以你可以这样检查:

Select Case TypeName(item)
    Case "Collection"
        '--- loop through the item as a Collection
    Case "Dictionary"
        '--- loop through the item as a Dictionary
    Case Else
        '--- the item is a value of some type (String, Boolean, etc)
End Select
在这里的示例中,我创建了一个名为
ParseItem
的子项,它以这种方式检查每个项。将原始代码改写为以下示例:

Option Explicit

Sub testparse()
    Dim js As String, i As Long, jo As Object, item As Variant
    Dim keys(), vals()

    ' fails on this string
    js = "{ !Category!: !Famous Pets!," & _
         "!code!: [!a!,!b!,!c!] }"               ' string with multiple values

    ' with the following string, this works
    '    js = "{ !Category!: !Famous Pets!," & _
    '         "    !code!: !singlecodevalue! }"

    '--- compound example
    '    js = "{ !Category!: !Famous Pets!,!code!: [!a!,!b!,{!c! : { !c1! : !1!, !c2!:!2!}}] }"

    js = Replace(js, "!", Chr(34))               ' replace ! with quotes

    Debug.Print "----------------------"
    Debug.Print "js = " & js
    Set jo = JsonConverter.ParseJson(js)         ' returns object with json elements
    ParseDictionary 1, "root", jo
End Sub

Private Sub ParseCollection(ByVal level As Long, _
                            ByVal key As String, _
                            ByRef jsonCollection As Variant)
    Dim item As Variant
    For Each item In jsonCollection
        ParseItem level, key, item
    Next item
End Sub

Private Sub ParseDictionary(ByVal level As Long, _
                            ByVal key As String, _
                            ByRef jsonDictionary As Variant)
    Dim dictKey As Variant
    For Each dictKey In jsonDictionary
        ParseItem level, dictKey, jsonDictionary(dictKey)
    Next dictKey
End Sub

Private Sub ParseItem(ByVal level As Long, _
                      ByVal key As String, _
                      ByRef item As Variant)
    Select Case TypeName(item)
    Case "Collection"
        Debug.Print Format(level + 1, "00 ") & key & " (collection)"
        ParseCollection (level + 1), key, item
    Case "Dictionary"
        Debug.Print Format(level + 1, "00 ") & key & " (dictionary)"
        ParseDictionary (level + 1), key, item
    Case Else
        Debug.Print Format(level, "00 ") & key & " = " & item
    End Select
End Sub

对于在JSON对象中运行时遇到的每一项,都必须确定要处理的内容——特别是如果您事先不知道数组中有多少项!如果您有一个复合JSON结构,其中包含数组等内部的集合,那么它会变得更加复杂

底线是,在访问JSON对象之前,必须检查从JSON对象中提取的每个项目,并弄清楚它是什么。JSON对象的顶层(假设使用了
JsonConverter
)将始终是
字典
。因此,您可以通过顶级字典的键进行循环:

Dim json As Dictionary
Set json = JsonConverter.ParseJson(someJsonString)

Dim topLevelKey As String
For Each topLevelKey In json
    Dim item As Variant
    Debug.Print topLevelKey & " = " & item
Next topLevelKey 
问题是
并不总是一个简单的字符串。它可以是一个值(
String
)、一个数组(
Collection
)或一个组(
Dictionary
)。作为一个很好的参考

基本上,这意味着您必须在使用前检查每个
项目。所以你可以这样检查:

Select Case TypeName(item)
    Case "Collection"
        '--- loop through the item as a Collection
    Case "Dictionary"
        '--- loop through the item as a Dictionary
    Case Else
        '--- the item is a value of some type (String, Boolean, etc)
End Select
在这里的示例中,我创建了一个名为
ParseItem
的子项,它以这种方式检查每个项。将原始代码改写为以下示例:

Option Explicit

Sub testparse()
    Dim js As String, i As Long, jo As Object, item As Variant
    Dim keys(), vals()

    ' fails on this string
    js = "{ !Category!: !Famous Pets!," & _
         "!code!: [!a!,!b!,!c!] }"               ' string with multiple values

    ' with the following string, this works
    '    js = "{ !Category!: !Famous Pets!," & _
    '         "    !code!: !singlecodevalue! }"

    '--- compound example
    '    js = "{ !Category!: !Famous Pets!,!code!: [!a!,!b!,{!c! : { !c1! : !1!, !c2!:!2!}}] }"

    js = Replace(js, "!", Chr(34))               ' replace ! with quotes

    Debug.Print "----------------------"
    Debug.Print "js = " & js
    Set jo = JsonConverter.ParseJson(js)         ' returns object with json elements
    ParseDictionary 1, "root", jo
End Sub

Private Sub ParseCollection(ByVal level As Long, _
                            ByVal key As String, _
                            ByRef jsonCollection As Variant)
    Dim item As Variant
    For Each item In jsonCollection
        ParseItem level, key, item
    Next item
End Sub

Private Sub ParseDictionary(ByVal level As Long, _
                            ByVal key As String, _
                            ByRef jsonDictionary As Variant)
    Dim dictKey As Variant
    For Each dictKey In jsonDictionary
        ParseItem level, dictKey, jsonDictionary(dictKey)
    Next dictKey
End Sub

Private Sub ParseItem(ByVal level As Long, _
                      ByVal key As String, _
                      ByRef item As Variant)
    Select Case TypeName(item)
    Case "Collection"
        Debug.Print Format(level + 1, "00 ") & key & " (collection)"
        ParseCollection (level + 1), key, item
    Case "Dictionary"
        Debug.Print Format(level + 1, "00 ") & key & " (dictionary)"
        ParseDictionary (level + 1), key, item
    Case Else
        Debug.Print Format(level, "00 ") & key & " = " & item
    End Select
End Sub

如果
code
是数组,则值表示为集合对象:如果不使用
Set
,则无法将对象分配到数组位置。仅供参考,字典中已经有返回数组的
属性,因此这里不需要循环。当
code
是数组时,值表示为集合对象:如果不使用
Set
,则无法将对象分配到数组位置。仅供参考,Dictionary已经具有返回数组的
属性,因此这里不需要循环。