VBA解析JSON代码在Excel 365运行报错,旧版Excel可正常执行
问题说明
基于VBA-JSON库解析JIRA API返回的测试步骤数据,原有代码在Excel 2010环境可正常运行,在Excel 365环境执行到Set Var2 = issue("fields")("customfield_10104")("steps")语句时触发报错,无法继续执行。
原有实现代码如下:
Dim j As Object Set j = JsonConverter.ParseJson(JSON) Set Var = j("issues") ' second level array For Each issue In Var Set Var2 = issue("fields")("customfield_10104")("steps") For Each Step In Var2 ' third level objects Cells(Col, 1).Value = issue("key") Cells(Col, 2).Value = issue("fields")("description") Cells(Col, 3).Value = Step("index") Cells(Col, 4).Value = Step("fields")("Action") Cells(Col, 5).Value = Step("fields")("Data") Cells(Col, 6).Value = Step("fields")("Expected Result") Col = Col + 1 Next Step Next issue
排查思路
- 跨版本VBA引擎容错差异:Excel 2010 VBA对多级对象链式调用的中间空值校验更宽松,中间层返回空值时部分场景不会直接抛错;Excel 365(尤其是64位版本)收紧了校验规则,只要链式调用任意一级返回空值、非对象类型,就会直接抛出运行时错误。
- VBA-JSON库兼容性问题:早期版本VBA-JSON未适配64位Office和新版VBA的枚举逻辑,部分深嵌套JSON结构会被错误解析为Collection而非Dictionary,用字符串key取值时会直接报错。
- JIRA接口返回结构波动:如果Excel 365环境下的API请求头、鉴权参数和原2010环境不一致,JIRA可能返回不同结构的响应——比如无测试步骤的工单会将
customfield_10104直接返回为null或空字符串,而非包含steps键的对象。
优化方案
核心调整点:放弃不安全的连续链式key取值写法,对每一层嵌套做存在性校验、类型校验,显式声明所有变量避免隐式类型转换问题,兼容不同版本的运行逻辑。
优化后代码:
Dim j As Object Dim Var As Object, Var2 As Object Dim issue As Object, Step As Object Dim Col As Long ' 初始化写入起始行,避免未赋值默认值导致写入位置错误 Col = 2 ' 按实际业务需求调整起始行号 Set j = JsonConverter.ParseJson(JSON) ' 顶层字段校验 If Not j.Exists("issues") Then MsgBox "接口返回异常,无issues字段" Exit Sub End If Set Var = j("issues") For Each issue In Var ' 逐层校验嵌套字段存在性与类型 If issue.Exists("fields") Then With issue("fields") ' 校验自定义测试步骤字段 If .Exists("customfield_10104") Then Dim custField As Object On Error Resume Next Set custField = .Item("customfield_10104") On Error GoTo 0 ' 仅当字段是字典对象且存在steps键时才继续取值 If Not custField Is Nothing Then If custField.Exists("steps") Then Set Var2 = custField("steps") For Each Step In Var2 Cells(Col, 1).Value = issue("key") ' 写入描述字段 If .Exists("description") Then Cells(Col, 2).Value = .Item("description") Cells(Col, 3).Value = Step("index") ' 校验步骤下的字段集合 If Step.Exists("fields") Then With Step("fields") If .Exists("Action") Then Cells(Col, 4).Value = .Item("Action") If .Exists("Data") Then Cells(Col, 5).Value = .Item("Data") If .Exists("Expected Result") Then Cells(Col, 6).Value = .Item("Expected Result") End With End If Col = Col + 1 Next Step End If End If End If End With End If Next issue
额外注意事项
- 如果使用64位Excel 365,请将VBA-JSON库更新至最新适配版本,确认模块开头的条件编译声明已正确配置64位兼容参数。
- 调试时可在原报错行前加
Stop语句,运行中断后打开本地窗口逐层展开对象节点,可直接看到各层级的实际数据类型、值和结构,快速定位不符合预期的节点。
内容的提问来源于stack exchange,提问作者Am Salman
相关产品推荐
相关产品推荐

