我想使用VBA通过特定的日期使用Norges银行的API检索汇率。
我试图修改以前使用的代码以从另一个API检索数据,但是很遗憾,我无法使其工作。我已经能够获取API本身以在浏览器中检索所需的信息,但是我想要一个VBA代码,可以在其中自动检索这些汇率。
在下面的代码中,我试图查找特定日期XXX / NOK的汇率。
Public Function FX(FXdate As String, FXcurrency As String)
Dim firstVal As String, secondVal As String, thirdVal As String
firstVal = "https://data.norges-bank.no/api/data/EXR/B."
secondVal = ".NOK.SP?format=sdmx-json&startPeriod="
thirdVal = "&endPeriod="
Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
URL = firstVal & secondVal & thirdVal
objHTTP.Open "GET", URL, False
objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
objHTTP.send ("")
Set regex = CreateObject("VBScript.RegExp"): regex.Pattern = """observations""*""([0-9])""": regex.Global = False
Set matches = regex.Execute(objHTTP.responseText)
tmpVal = Replace(matches(0).SubMatches(0), ".", Application.International(xlListSeparator))
GetCurrency = CDbl(tmpVal)
End Function
例如,如果我想要在2018年1月2日的SEK / NOK,则原始数据API返回以下数据。在此示例中,我希望VBA在“观察”之后返回值,在这种情况下为“ 99.46”。
{"header":{"id":"64ffd01684ad7f51ab197c573027a05f","prepared":"2018-09-28T09:33:13","test":false,"sender":{"id":"NB"},"receiver":{"id":"ANONYMOUS"}},"dataSets":[{"action":"Information","series":{"0:0:0:0":{"attributes":[0,0,0,0],"observations":{"0":["99.46"]}}}}],"structure":{"name":"Exchange rates","description":"Norges Bank exchange rate statistics","dimensions":{"dataset":[],"series":[{"id":"FREQ","name":"Frequency","description":"The time interval at which observations occur over a given time period.","keyPosition":0,"role":null,"values":[{"id":"B","name":"Business"}]},{"id":"BASE_CUR","name":"Base Currency","description":"The first currency in a currency pair quotation. Also known as the transaction currency.","keyPosition":1,"role":null,"values":[{"id":"SEK","name":"Swedish krona"}]},{"id":"QUOTE_CUR","name":"Quote Currency","description":"The second currency in a currency quote pair. Also known as counter currency.","keyPosition":2,"role":null,"values":[{"id":"NOK","name":"Norwegian krone"}]},{"id":"TENOR","name":"Tenor","description":"The amount of time left for the repayment of a loan or until a financial contract expires.","keyPosition":3,"role":null,"values":[{"id":"SP","name":"Spot"}]}],"observation":[{"id":"TIME_PERIOD","name":"Time Period","description":"The period of time or point in time to which the measured observation refers.","keyPosition":4,"role":"time","values":[{"start":"2018-01-02T00:00:00","end":"2018-01-02T00:00:00","id":"2018-01-02","name":"2018-01-02"}]}]},"attributes":{"dataset":[],"series":[{"id":"DECIMALS","name":"Decimals","description":"The number of digits to the right of a decimal point.","role":null,"values":[{"id":"2","name":"2"}]},{"id":"CALCULATED","name":"Calculated","description":"Indicates if the value is calculated or an actual observation.","role":null,"values":[{"id":"false","name":"false"}]},{"id":"UNIT_MULT","name":"Unit Multiplier","description":"Exponent in base 10 specified so that multiplying the observation numeric values by 10^UNIT_MULT gives a value expressed in the UNIT.","role":null,"values":[{"id":"2","name":"Hundreds"}]},{"id":"COLLECTION","name":"Collection Indicator","description":"Dates or periods during which the observations have been collected.","role":null,"values":[{"id":"C","name":"ECB concertation time 14:15 CET"}]}],"observation":[]}}}
有什么解决方法吗?
答案 0 :(得分:1)
进行API调用:
在这里,您可以使用函数进行API调用并使用JSON parser获得结果。我本来可以使用Split self从响应文本中提取项目,但是已经在给出的答案中得到了证明,因此我将向您展示JSON解析。我添加了一个附加标头,以希望减轻浏览器提供的缓存结果。
您可以将JSON解析部分移至函数中,但我希望单独进行演示。
您没有在API调用的URL字符串中显示值的串联。
Option Explicit
Public Sub TEST()
'https://data.norges-bank.no/api/data/EXR/B.SEK.NOK.SP?format=sdmx-json&startPeriod=2018-01-02&endPeriod=2018-01-02
Dim json As Object
Set json = JsonConverter.ParseJson(FX_json("2018-01-02", "SEK"))
Debug.Print json("dataSets")(1)("series")("0:0:0:0")("observations")("0")(1)
End Sub
Public Function FX_json(ByVal FXdate As String, ByVal FXcurrency As String) As String
Dim firstVal As String, secondVal As String, thirdVal As String, url As String
firstVal = "https://data.norges-bank.no/api/data/EXR/B."
secondVal = ".NOK.SP?format=sdmx-json&startPeriod="
thirdVal = "&endPeriod="
url = firstVal & FXcurrency & secondVal & FXdate & thirdVal & FXdate
With CreateObject("MSXML2.ServerXMLHTTP")
.Open "GET", url, False
.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
.setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
.send
FX_json = .responseText
End With
End Function
JSON树视图:
这是感兴趣的项目的JSON树路径的视觉效果
参考:
在将JSONConverter.bas下载并添加到项目中之后,转到VBE>工具>参考,然后添加对Microsoft脚本运行时的参考。
答案 1 :(得分:0)
整个问题可以翻译成如何分割字符串?。可能有20多种不同的方式来做到这一点。从序列化和循环显示正确的属性,到使用search(),find(),向左,向右和拆分。
所以,这只是其中一种方法-假设您在excel的给定范围内拥有整个输入字符串,如下所示:
然后,您需要获取observations":{"0":["
和下一个"
之间的数据。
如果通过第一定界符将字符串拆分为数组,然后获取第二部分,则会实现此目的。然后再次用"
分割,并采用第一部分:
使用一些硬编码不太容易,但是应该可以:
Sub TestMe()
Dim inputTxt As String
inputTxt = Worksheets(1).Range("A1")
inputTxt = Split(inputTxt, "observations"":{""0"":[""")(1)
inputTxt = Split(inputTxt, """")(0)
Debug.Print inputTxt
End Sub
类似的问题: