首页 > 解决方案 > 使用 VBA 遍历嵌套 JSON

问题描述

我有一个我试图在 VBA 中解析的 JSON。JSON 类似于以下内容:

{
    "participantEligibilityResults": [
        {
            "eligibilityResult": {
                "participantId": "HSA92a",
                "clientId": "NIRCCCONFIG",
                "environment": "CONFIG",
                "errorReason": null,
                "previousEvent": {
                    "eventDate": "2019-01-01",
                    "eventReason": "7",
                    "eligibilityDetails": [
                        {
                            "standardBenefitAreaId": "SPLIFE",
                            "benefitOptionId": "1XPay",
                            "coverageLevelId": "PPSP",
                            "employeeMonthlyCost": 216.67,
                            "employerMonthlyCost": 0.0,
                            "benefitProgramId": "ProgH"
                        },
                        {
                            "standardBenefitAreaId": "SPLIFE",
                            "benefitOptionId": "NoCoveragePay",
                            "coverageLevelId": null,
                            "employeeMonthlyCost": 0.0,
                            "employerMonthlyCost": 0.0,
                            "benefitProgramId": "ProgH"
                        }
                    ],
                    "dependents": []
                },
                "currentEvent": {
                    "eventDate": "2020-03-14",
                    "eventReason": "5",
                    "eligibilityDetails": [
                        {
                            "standardBenefitAreaId": "BASICCHLIFE",
                            "benefitOptionId": "BCHWaive",
                            "coverageLevelId": null,
                            "employeeMonthlyCost": 0.0,
                            "employerMonthlyCost": 0.0,
                            "benefitProgramId": "ProgH",
                            "beneficiaryCollection": "Not Applicable",
                            "maxCoverageAmount": 0.0,
                            "minCoverageAmount": 0.0,
                            "coverageAmount": 0.0,
                            "preTax": true,
                            "postTax": false,
                            "userDefinedTaxability": false,
                            "numberOfPayPeriods": 52,
                            "payperiodsRemaining": 42.0
                        },
                        {
                            "standardBenefitAreaId": "DENTAL",
                            "benefitOptionId": "DentalPPO",
                            "coverageLevelId": "PPFAM2",
                            "employeeMonthlyCost": 29.17,
                            "employerMonthlyCost": 125.0,
                            "benefitProgramId": "ProgH",
                            "beneficiaryCollection": "Not Applicable",
                            "maxCoverageAmount": 0.0,
                            "minCoverageAmount": 0.0,
                            "preTax": true,
                            "postTax": false,
                            "userDefinedTaxability": false,
                            "numberOfPayPeriods": 52,
                            "payperiodsRemaining": 42.0
                        }
                    ],
                    "dependents": [
                        {
                            "fullName": "Allison Drew ",
                            "dependentId": "5d82c4bf-609d-4c2f-8c1b-7d8fdd8b9fde",
                            "relationshipType": "Spouse",
                            "birthDate": "1980-01-01",
                            "activeIndicator": true,
                            "approvedIndicator": true,
                            "studentIndicator": false,
                            "coverages": [
                                {
                                    "standardBenefitAreaId": "DENTAL",
                                    "benefitOptionId": "NoCoverageDental",
                                    "dependentCoverageRequired": false,
                                    "activeCourtOrdered": false
                                },
                                {
                                    "standardBenefitAreaId": "MEDICAL",
                                    "benefitOptionId": "NoCoverageMedical",
                                    "dependentCoverageRequired": false,
                                    "activeCourtOrdered": false
                                }
                            ]
                        },
                        {
                            "fullName": "Adam Drew ",
                            "dependentId": "d3f97b64-4a50-4dea-bec8-51d3db39352a",
                            "relationshipType": "Child",
                            "birthDate": "2012-01-01",
                            "activeIndicator": true,
                            "approvedIndicator": true,
                            "studentIndicator": false,
                            "coverages": [
                                {
                                    "standardBenefitAreaId": "DENTAL",
                                    "benefitOptionId": "NoCoverageDental",
                                    "dependentCoverageRequired": false,
                                    "activeCourtOrdered": false
                                },
                                {
                                    "standardBenefitAreaId": "MEDICAL",
                                    "benefitOptionId": "NoCoverageMedical",
                                    "dependentCoverageRequired": false,
                                    "activeCourtOrdered": false
                                }
                            ]
                        }
                    ]
                }
            },
            "changes": []
        }
    ]
}

我目前正在使用来自https://github.com/VBA-tools/VBA-JSON的 VBA-JSON来解析 JSON。

JsonOptions.AllowUnquotedKeys = True
Set JSON = JsonConverter.ParseJson(jsonResponse)

最终,我希望访问参与者结果 | 资格结果 | 当前事件 | 资格详情参与者结果 | 资格结果 | 当前事件 | 家属。我尝试使用以下方式开始遍历 JSON:

For Each Eligibility In JSON("participantEligibilityResults")
    For Each Detail In Eligibility("eligibilityResult")
            'DO SOMETHING HERE
        Next
Next

不幸的是,一旦我在参与者资格结果级别进行解析,我就无法访问以下级别。我收到错误消息“对象不支持此属性或方法。” 有人可以指出我正确的方向吗?

标签: jsonexcelvba

解决方案


包含的所有{}内容都将作为字典输出,包含的所有内容都[]将是一个集合。您只需要按照嵌套即可到达您想要的位置。

Sub Test()

    Dim result As String
    Dim Item, a
    Dim parsedResult As Object, obj, node, k

    'loading from a cell for testing...
    Set parsedResult = JsonConverter.ParseJson(Sheet2.Range("A1").Value)

    Set obj = parsedResult("participantEligibilityResults")(1)("eligibilityResult")

    Set node = obj("currentEvent")("eligibilityDetails")(1)
    DumpJSon node 'see below


    Set node = obj("currentEvent")("dependents")(1)
    DumpJSon node 'see below


End Sub

如果有您想要的特定项目,那么尝试创建嵌套循环来获取它们可能不是很有用 - 确定您想要的路径并直接访问这些值。如果您需要(例如)循环一个集合,那么这需要成为您方法的一部分。

仔细检查解析结果中的内容有时很有用,因此您可以使用它来将其转储到即时窗口(全部或仅部分)

Sub DumpJSon(obj, Optional level As Long = 0)
    Const LEVEL_STEP As Long = 5
    Dim k, v, n, s, tmp
    If TypeName(obj) = "Dictionary" Then
        For Each k In obj.keys
            s = String(level, "-") & k & " = "
            If IsObject(obj(k)) Then
                Debug.Print s & IIf(obj(k).Count = 0, "Empty ", "") & _
                           TypeName(obj(k))
                DumpJSon obj(k), level + LEVEL_STEP
            Else
                Debug.Print s & obj(k)
            End If
        Next k
    ElseIf TypeName(obj) = "Collection" Then
        n = 1
        For Each v In obj
            s = String(level, "-") & "(Item #" & n & ") "
            If IsObject(v) Then
                Debug.Print s & IIf(v.Count = 0, "Empty ", "") & _
                            TypeName(v)
                DumpJSon v, level + LEVEL_STEP
            Else
                Debug.Print s & v
            End If
            n = n + 1
        Next v
    End If
End Sub

推荐阅读