VBA - API调用在Excel中显示天气

问题描述 投票:0回答:3

我正在尝试在 Excel 工作表中显示天气。我正在从 open-meteo 的 API 中提取 JSON 数据 - https://api.open-meteo.com/v1/forecast?latitude=13.90&longitude=100.53&hourly=relativehumidity_2m,windspeed_180m,Temperature_180m

这是我的脚本,但由于某种原因它不起作用。

Public Sub openWeather()
    Dim xmlhttp As Object
    Dim responseData As String
    Dim json As Object
    Dim url As String

    url = "https://api.open-meteo.com/v1/forecast?latitude=13.90&" & _ 
     "longitude=100.53&hourly=relativehumidity_2m,windspeed_180m," & _ 
     "temperature_180m"
    
    On Error Resume Next
    Set xmlhttp = CreateObject("MSXML2.ServerXMLHTTP.6.0")
    If Err.Number <> 0 Then
        Exit Sub
    End If
    On Error GoTo 0
    
    With xmlhttp
        .Open "GET", url, False
        .send
        responseData = .responseText
    End With
    
    Set json = JsonConverter.ParseJson(responseData)
    
    With ThisWorkbook.Sheets("Sheet1")
        Dim hourlyData As Object
        Set hourlyData = json("hourly")
        
        Dim i As Integer
        For i = 1 To hourlyData.Count
            If Not IsObject(hourlyData(i)("windspeed_180m")) And & _
             TypeName(hourlyData(i)("windspeed_180m")) = "Double" Then
                .Cells(i, 3).Value = CDbl(hourlyData(i ("windspeed_180m"))
            Else
                .Cells(i, 3).Value = ""
            End If
    
            If Not IsObject(hourlyData(i)("temperature_180m")) And  & _
             TypeName(hourlyData(i)("temperature_180m")) = "Double" Then
                .Cells(i, 4).Value = CDbl(hourlyData(i)("temperature_180m"))
            Else
                .Cells(i, 4).Value = ""
            End If
        Next i
    
    End With
End Sub

错误:

类型不匹配

If Not IsObject(hourlyData(i)("windspeed_180m")) And TypeName(hourlyData(i)("windspeed_180m")) = "Double" Then

API调用成功。希望任何人都能够提供帮助。预先感谢。

excel vba weather-api
3个回答
1
投票

好的,它也适用于仅对象。但使用更具体的字典作为类型更容易阅读代码。您可以这样读取所有值:

Public Sub openWeather()

  Const url As String = "https://api.open-meteo.com/v1/forecast?latitude=13.90&longitude=100.53&hourly=relativehumidity_2m,windspeed_180m,temperature_180m"
  Dim json As Dictionary
  Dim ws As Worksheet
  Dim dataSet As Long
  Dim currRow As Long
  
  Set ws = ThisWorkbook.Sheets("Sheet1")
  currRow = 2
  
  With CreateObject("MSXML2.XMLHTTP.6.0")
    .Open "GET", url, False
    .send
    
    If .Status = 200 Then
      Set json = JsonConverter.ParseJson(.responseText)
      For dataSet = 1 To json("hourly")("time").Count
        ws.Cells(currRow, 1) = Replace(json("hourly")("time")(dataSet), "T", " ") 'timestamp
        ws.Cells(currRow, 2) = json("hourly")("relativehumidity_2m")(dataSet)     'relativehumidity
        ws.Cells(currRow, 3) = json("hourly")("windspeed_180m")(dataSet)          'windspeed
        ws.Cells(currRow, 4) = json("hourly")("temperature_180m")(dataSet)        'temperature
        currRow = currRow + 1
      Next dataSet
    Else
      MsgBox "Page not loaded. HTTP status: " & .Status
    End If
  End With
End Sub

1
投票

这也可以使用 Windows Excel 2010+ 和 Excel 365(Windows 或 Mac)中提供的 Power Query 来完成

使用 Power Query

  • Data => Get&Transform => Get Data => From Other Sources => Blank Query
  • PQ 编辑器打开时:
    Home => Advanced Editor
  • 将下面的 M 代码粘贴到您所看到的位置
  • 阅读评论并探索
    Applied Steps
    以了解算法
let

//define URL
    URL = "https://api.open-meteo.com/v1/forecast?latitude=13.90&longitude=100.53&hourly=relativehumidity_2m,windspeed_180m,temperature_180m",

//Read from web
// note header to allow for the compressed json used on this site
    Source = Json.Document(Web.Contents(URL, [Headers=[#"Accept-Encoding"="gzip"]]))[hourly],

//Convert to table
    #"Converted to Table" = Record.ToTable(Source),

//Expand the lists of values
    #"Expand Lists" = Table.FromColumns(
        #"Converted to Table"[Value], #"Converted to Table"[Name]),

//set the data types
    #"Changed Type" = Table.TransformColumnTypes(#"Expand Lists",{{"time", type datetime}, {"relativehumidity_2m", Int64.Type}, {"windspeed_180m", type number}, {"temperature_180m", type number}})
in
    #"Changed Type"

部分结果
enter image description here


0
投票

尝试:

Dim windspeed_180m As Double
If Not IsObject(hourlyData(i)("windspeed_180m")) And TypeName(hourlyData(i)("windspeed_180m")) = "Double" Then
    .Cells(i, 3).Value = CDbl(hourlyData(i)("windspeed_180m"))
Else
    .Cells(i, 3).Value = ""
End If
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.