我正在尝试编写 Excel VBA 代码,该代码调用 API 来获取数据、处理数据,然后在电子表格中的一系列单元格上输出清理后的数据。
我在尝试使用 JsonConverter 解析 API 响应时遇到错误。
我按照 https://github.com/VBA-tools/VBA-JSON 上的说明安装 VBA-JSON,并将 JsonConverter.bas 导入到我的脚本中,并添加对“Microsoft Scripting Runtime”的引用。
我将 Tablacus 安装为 64 位 ScriptControl。
这是代码的开头,以及出错的地方:
Function IsValidJson(jsonString As String) As Boolean
Dim regex As Object
Set regex = CreateObject("VBScript.RegExp")
regex.Pattern = "^[\s\S]*\{[\s\S]*\}[\s\S]*$"
IsValidJson = regex.Test(jsonString)
End Function
Sub RefreshData()
Dim url As String
Dim http As Object
Dim json As Object
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim trading_pairs() As String
Dim trading_pairs_eth() As String
Dim trading_pairs_usd() As String
Dim final_pairs() As String
Dim final_prices() As Double
Dim final_volumes() As Double
Dim pair As String
Dim volume As Double
Dim price As Double
Dim row As Integer
Dim JsonConverter As Object
Dim dict As New Dictionary
Set http = CreateObject("MSXML2.XMLHTTP")
Set JsonConverter = CreateObject("ScriptControl")
JsonConverter.Language = "JScript"
JsonConverter.AddCode "function parseJson(jsonString) { return JSON.parse(jsonString); }"
' Fetch all trading pairs with BTC as the quote currency
url = "https://api.pro.coinbase.com/products/BTC-USD/book"
http.Open "GET", url, False
http.send
If IsValidJson(http.responseText) Then
Set json = JsonConverter.ParseJson(http.responseText) ' <- error happens here
ReDim trading_pairs(json("bids").Count - 1)
For i = 0 To json("bids").Count - 1
trading_pairs(i) = json("bids")(i)("price")
Next i
Else
MsgBox "Invalid JSON string"
Exit Sub
End If
这是整个脚本的一部分,相当长。
行
Set json = JsonConverter.ParseJson(http.responseText)
是抛出错误 438 的地方。
在尝试使用 JsonConverter 解析“http.responseText”之前,我有一个 IsValidJson 函数来验证它。
它通过了验证检查,但在尝试解析时仍然抛出错误 438。
代码最初由 ChatGPT 生成。
您链接的 JSON-Converter 不是需要实例化的类。您显示的代码看起来像是(至少)两种不同事物的混合物。
您需要使用的代码相当简单。
Sub RefreshData()
Const url = "https://api.pro.coinbase.com/products/BTC-USD/book"
Dim http As Object
Set http = CreateObject("MSXML2.XMLHTTP")
' Fetch all trading pairs with BTC as the quote currency
http.Open "GET", url, False
http.send
Set json = JsonConverter.ParseJson(http.responseText)
(now your work starts)
End Sub
调用
JsonConverter.ParseJson(http.responseText)
是对模块ParseJson
的函数JsonConverter
的调用,而不是对象。您可以省略模块名称,只需写 Set json = ParseJson(http.responseText)
- 这是完全相同的。
因此需要删除变量的定义
JsonConverter
否则编译器会假设您想要调用该对象的方法ParseJSon
,因此您将收到 438 错误。
我不知道为什么你或 ChatGPT 想要创建一个
ScriptControl
对象,请删除该行以及对 Language
和 AddCode
的分配。
我也不确定函数
IsValidJson
是否正在完成它的工作,我已经删除了对它的调用。如果 JSON 无效,ParseJSon 函数将引发错误 (10001)。
一旦成功,您需要遍历解析后的 JSon,您的代码很快就会引发下一个错误。只是一些提示:
我快速浏览了
http.responseText
,对我来说它看起来像这样:
{"bids":[["36575.59","0.51069628",3]],
"asks":[["36575.6","0.0266337",2]],
"sequence":68520027803,
"auction_mode":false,
"auction":null,
"time":"2023-11-18T22:04:21.019956Z"}
调用
ParseJSon
后,您将在变量json
中得到一个字典作为结果(使用调试器检查内容)。元素 bids
是一个包含 1 个元素的数组,该元素本身是一个包含 3 个元素(3 个数字)的数组。 JSonConverter 将数组转换为 Collection
。 VBA 中的集合是从 1 开始的,而不是从 0 开始的。获得一个想法:
Set json = JsonConverter.ParseJson(http.responseText)
Debug.Print http.responseText
Dim bids As Collection, bidvalues As Collection
Set bids = json("bids")
' You now have a collection with one element.
Dim i As Long, j As Long
For i = 1 To bids.Count
Set bidvalues = bids(i)
For j = 1 To bidvalues.Count
Debug.Print i, j, bidvalues(j)
Next j
Next i