Excel VBA调用股票API解析JSON时出现Object Required错误的原因排查
我来帮你排查这个「Object Required」错误的问题,结合你的代码和返回的JSON示例,主要有几个可能的原因和对应的修复方案:
一、核心错误原因分析
触发这个错误的核心点是JsonConverter.ParseJSON(response)无法返回一个有效的对象给json变量,常见的诱因有以下几个:
1. 缺少必要的引用或JsonConverter模块
JsonConverter依赖Microsoft Scripting Runtime库中的Dictionary对象,同时你必须确保已经将JsonConverter的代码模块正确导入到你的VBA工程中:
- 修复步骤:
- 打开VBA编辑器,点击「工具」→「引用」,找到并勾选
Microsoft Scripting Runtime; - 如果你还没导入JsonConverter模块,直接将官方提供的模块代码复制粘贴到你的VBA工程里即可。
- 打开VBA编辑器,点击「工具」→「引用」,找到并勾选
2. API返回了错误格式的JSON
虽然你说已经把响应写入到Sheet1的D1单元格,但有时候API会因为参数问题(比如无效的apikey、错误的股票代码)返回错误信息而非正常行情JSON,比如:
{"Error Message": "Invalid API key"}
这种情况下ParseJSON无法解析出有效的对象,自然会触发「Object Required」错误。
- 修复方法:
- 查看Sheet1的D1单元格内容,确认返回的是正常的行情JSON;
- 如果是API错误,先修正apikey或股票代码参数。
3. 变量类型声明的问题
你代码里把json声明为Dictionary,但如果没有引用Microsoft Scripting Runtime,VBA会将Dictionary视为未定义的类型,导致解析后的对象无法正确赋值。
- 修复方法:
- 要么确保引用了
Microsoft Scripting Runtime,要么将json的声明改为Dim json As Object(这种方式更灵活,适配不同的JSON结构)。
- 要么确保引用了
4. 循环中的未声明变量(潜在问题)
你的循环代码For Each Value In json("Time Series (Daily)")里的Value没有声明,虽然这不是触发当前错误的直接原因,但可能引发后续的运行时错误,建议补充声明Dim dailyEntry As Object(因为每个日期节点都是一个字典对象)。
二、修正后的完整代码
Sub GetCompanyInfo() Dim hReq As Object, json As Object ' 用Object适配不同解析结果 Dim i As Long Dim ws As Worksheet Dim strUrl As String Dim response As String Dim timeSeries As Object Dim dailyEntry As Object ' 存储单条每日行情数据 Set ws = Sheet1 ' 拼接API请求地址 strUrl = "https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=" & ws.Cells(1, 2).Value & "&apikey=x" ' 发送API请求 Set hReq = CreateObject("MSXML2.XMLHTTP") With hReq .Open "GET", strUrl, False .Send End With response = hReq.ResponseText ws.Cells(1, 4).Value = response ' 先检查响应是否为错误内容 If response = "" Or InStr(1, response, "Error Message", vbTextCompare) > 0 Then MsgBox "API返回错误,请检查股票代码或API密钥!" Exit Sub End If ' 解析JSON响应 Set json = JsonConverter.ParseJSON(response) ' 获取每日行情数据集合 Set timeSeries = json("Time Series (Daily)") i = 2 ' 从第2行开始写入,避免覆盖第一行的内容 ' 遍历每日行情数据 For Each dailyEntry In timeSeries ws.Cells(i, 1).Value = dailyEntry("1. open") ' 可选:写入其他行情字段 ws.Cells(i, 2).Value = dailyEntry("2. high") ws.Cells(i, 3).Value = dailyEntry("3. low") ws.Cells(i, 4).Value = dailyEntry("4. close") i = i + 1 Next dailyEntry End Sub
内容的提问来源于stack exchange,提问作者DecentExperience

