VBA JSON-解析多个值
使用带有多值键的JSON-VBA转换器时遇到问题 我编写了常规的递归例程来导航JSON树,但这里有一个简单的JSON解析示例,我似乎无法使用它 看看这个,这是非常棒和快速的 环境:Windows 7/Access 2016/专用局域网(无互联网) 代码如下: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
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已经具有返回数组的键
和项
属性,因此这里不需要循环。