我有一個 JSON 檔案,其中包含: 物件陣列(“組件”)
有些物件可能有子陣列(“組件”),有些則沒有。我需要提取其中的labels,keys以及帶有所有,array的陣列(“值”)。labelsvalues
但是,以下VBA代碼僅適用于第一級“組件”,請勿深入研究第二級或第三級。讓我知道我是否做得對?
我一直在使用 JsonConverter 來決議 JSON 檔案,然后使用以下代碼:
Dim jSon As Variant
Set jSon = JsonConverter.ParseJson(jSonText)
Dim components As Collection
Set components = jSon("components")
Set Dict = New Scripting.Dictionary
Dim component As Variant
For Each component In components
Dim Label, Key As String 'not used
Dict.Add component("label"), component("key")
On Error Resume Next
Dim Values As Collection
Set Values = component("components")
Dim Data As Scripting.Dictionary
Set Data = component("data")
On Error GoTo 0
Dim value As Variant
If Not Values Is Nothing Then
For Each value In Values
Dict.Add value("label"), value("value")
Next value
ElseIf Not Data Is Nothing Then
Set Values = Data("values")
For Each value In Values
Dict.Add value("label"), value("value")
Next value
Else
'Debug.Print " No values"
End If
Set Values = Nothing
Set Data = Nothing
Next component
舊的 JSON 檔案 - 上面的代碼在這方面作業正常
{
"display": "form",
"settings": {
"pdf": {
"id": "1ec0f8ee-6685-5d98-a847-26f67b67d6f0",
"src": "https://files8-a847-26f67b67d6f08-a847-26f67b67d6f0"
}
},
"components": [
{
"label": "Family Name",
"tableView": true,
"key": "familyName",
"type": "textfield",
"input": true
},
{
"label": "Amount of Money",
"mask": false,
"tableView": false,
"delimiter": false,
"requireDecimal": false,
"inputFormat": "plain",
"truncateMultipleSpaces": false,
"key": "amountOfMoney",
"type": "number",
"input": true
},
{
"label": "I hereby confirm",
"tableView": false,
"key": "iHerebyConfirm",
"type": "checkbox",
"input": true,
"defaultValue": false
},
{
"label": "Which Cities do you like",
"optionsLabelPosition": "right",
"tableView": false,
"values": [
{
"label": "New York",
"value": "newNew YorkYork",
"shortcut": ""
},
{
"label": "Munich",
"value": "Munich",
"shortcut": ""
},
{
"label": "Paris",
"value": "Paris",
"shortcut": ""
},
{
"label": "Hongkong",
"value": "Hongkong",
"shortcut": ""
},
{
"label": "Mumbai",
"value": "Mumbai",
"shortcut": ""
}
],
"key": "whichCitiesDoYouLike",
"type": "selectboxes",
"input": true,
"inputType": "checkbox"
},
{
"label": "Favorite color",
"widget": "choicesjs",
"tableView": true,
"data": {
"values": [
{
"label": "black",
"value": "black"
},
{
"label": "white",
"value": "white"
},
{
"label": "blue",
"value": "blue"
},
{
"label": "green",
"value": "green"
}
]
},
"key": "favoriteColor",
"type": "select",
"input": true
},
{
"type": "button",
"label": "Submit",
"key": "submit",
"disableOnInvalid": true,
"input": true,
"tableView": false
}
]
}
新的 JSON 檔案:
uj5u.com熱心網友回復:
請注意,我已經使用 key 作為字典鍵和 label 作為值交換了字典條目,因為 label 不是唯一的(就示例 JSON 而言)并且會導致錯誤(或覆寫先前的條目,具體取決于實作)。
您的使用On Error Resume Next應避免(這適用于任何情況下,除非你使用的是它在其上很少用到的目的),你基本上隱藏所有可能的錯誤,這可能會導致你的代碼產生意外結果。您可以使用陳述句中的Exists方法If..Else..End If首先檢查字典鍵是否存在,只有在存在時才執行任務。
編輯- 更新代碼以處理新舊 JSON 格式
Private Sub Test()
'==== Change this part according to your implementation..."
Dim jsontxt As String
jsontxt = OpenTxtFile("D:/TestJSON2.txt")
'====
Dim jSon As Scripting.Dictionary
Set jSon = JsonConverter.ParseJson(jsontxt)
'Check if first level of components exist and get the collection of components if true
If jSon.Exists("components") Then
Dim components As Collection
Set components = jSon("components")
Dim Dict As Scripting.Dictionary
Set Dict = New Scripting.Dictionary
Dim comFirst As Variant
Dim comSecond As Variant
Dim comThird As Variant
Dim columnsDict As Variant
Dim valDict As Variant
For Each comFirst In components
'extract key-label from first level component
If Not Dict.Exists(comFirst("label")) Then Dict.Add comFirst("label"), comFirst("key")
' New JSON Format
'==== Check if second level of "components" key exist and extract label-key if true
If comFirst.Exists("components") Then
For Each comSecond In comFirst("components")
If Not Dict.Exists(comSecond("label")) Then Dict.Add comSecond("label"), comSecond("key")
'=== Check if "columns" key exist and extract the key-label if true
If comSecond.Exists("columns") Then
For Each columnsDict In comSecond("columns")
'==== Check if third level of "components" key exist and extract key-label if true
If columnsDict.Exists("components") Then
For Each comThird In columnsDict("components")
If Not Dict.Exists(comThird("label")) Then Dict.Add comThird("label"), comThird("key")
'==== Check if "values" key exist and extract label-value if true
If comThird.Exists("values") Then
For Each valDict In comThird("values")
If Not Dict.Exists(valDict("label")) Then Dict.Add valDict("label"), valDict("value")
Next valDict
End If
'====
Next comThird
End If
'====
Next columnsDict
End If
'====
'==== Check if "values" key exist and extract the label-value if true
If comSecond.Exists("values") Then
For Each valDict In comSecond("values")
If Not Dict.Exists(valDict("label")) Then Dict.Add valDict("label"), valDict("value")
Next valDict
End If
'====
Next comSecond
End If
'
' Old JSON format
'==== Check if "data" key exist and extract the label-value if true
If comFirst.Exists("data") Then
If comFirst("data").Exists("values") Then
For Each valDict In comFirst("data")("values")
If Not Dict.Exists(valDict("label")) Then Dict.Add valDict("label"), valDict("value")
Next valDict
End If
End If
'====
'==== Check if "values" key exist and extract the label-value if true
If comFirst.Exists("values") Then
For Each valDict In comFirst("values")
If Not Dict.Exists(valDict("label")) Then Dict.Add valDict("label"), valDict("value")
Next valDict
End If
'====
'
Next comFirst
End If
End Sub
uj5u.com熱心網友回復:
嘗試這個:
https://github.com/VBA-tools/VBA-JSON
您需要在您的專案中匯入檔案“JsonConverter.bas”,然后按照 README.md 檔案中的示例進行操作
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/361228.html
標籤:arrays json vba object parsing
上一篇:Lua中的物件表
