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

huangapple go评论71阅读模式
英文:

VBA - API call displayed weather in Excel

问题

以下是您提供的内容的中文翻译:

我正在尝试在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调用成功。希望有人能够提供帮助。提前感谢。

英文:

I am trying to show weather in an Excel sheet. I am extracting the JSON data from the API of open-meteo - https://api.open-meteo.com/v1/forecast?latitude=13.90&amp;longitude=100.53&amp;hourly=relativehumidity_2m,windspeed_180m,temperature_180m

This is my script, but it is not working for some reason.

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

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

Error:

> Type mismatch
>
> vb
&gt; If Not IsObject(hourlyData(i)(&quot;windspeed_180m&quot;)) And TypeName(hourlyData(i)(&quot;windspeed_180m&quot;)) = &quot;Double&quot; Then
&gt;

The API call is successful. Hope anybody is able to help. Thanks in advance.

答案1

得分: 1

以下是您提供的代码的中文翻译部分:

Ok, it works also with object only. But it's more easy to read the code with the more specific dictionary as type. You can read all values like this:
' 打开天气数据
Public Sub openWeather()
' 天气数据的 API 地址
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
' 使用 MSXML2.XMLHTTP.6.0 创建 HTTP 请求
With CreateObject("MSXML2.XMLHTTP.6.0")
.Open "GET", url, False
.send
' 检查 HTTP 响应状态
If .Status = 200 Then
' 解析 JSON 数据
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 "页面未加载。HTTP 状态:" & .Status
End If
End With
End Sub

请注意,这只是代码的翻译部分,不包括代码中的注释。如果您需要代码中的注释的翻译,请提供注释的具体部分。

英文:

Ok, it works also with object only. But it's more easy to read the code with the more specific dictionary as type. You can read all values like this:

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

答案2

得分: 1

以下是您要翻译的内容:

这也可以通过使用 Power Query 来实现,适用于 Windows Excel 2010+ 和 Excel 365(Windows 或 Mac)。

要使用 Power Query:

  • 数据 => 获取和转换 => 获取数据 => 来自其他源 => 空白查询
  • 当 PQ 编辑器打开时:首页 => 高级编辑器
  • 将下面的 M 代码粘贴到您看到的位置
  • 阅读注释并探索“已应用步骤”以理解算法
let
//定义URL
URL = "https://api.open-meteo.com/v1/forecast?latitude=13.90&longitude=100.53&hourly=relativehumidity_2m,windspeed_180m,temperature_180m",
//从网页读取
// 注意标头以允许在此站点上使用的压缩json
Source = Json.Document(Web.Contents(URL, [Headers=[#"Accept-Encoding"="gzip"]]))[hourly],
//转换为表格
#"转换为表格" = Record.ToTable(Source),
//展开值列表
#"展开列表" = Table.FromColumns(
#"转换为表格"[Value], #"转换为表格"[Name]),
//设置数据类型
#"更改类型" = Table.TransformColumnTypes(#"展开列表",{{"time", type datetime}, {"relativehumidity_2m", Int64.Type}, {"windspeed_180m", type number}, {"temperature_180m", type number}})
in
#"更改类型"

部分结果
VBA – API调用在Excel中显示天气

英文:

This can also be accomplished using Power Query, available in Windows Excel 2010+ and Excel 365 (Windows or Mac)

To use Power Query

  • Data =&gt; Get&amp;Transform =&gt; Get Data =&gt; From Other Sources =&gt; Blank Query
  • When the PQ Editor opens: Home =&gt; Advanced Editor
  • Paste the M Code below in place of what you see
  • Read the comments and explore the Applied Steps to understand the algorithm
let
//define URL
URL = &quot;https://api.open-meteo.com/v1/forecast?latitude=13.90&amp;longitude=100.53&amp;hourly=relativehumidity_2m,windspeed_180m,temperature_180m&quot;,
//Read from web
// note header to allow for the compressed json used on this site
Source = Json.Document(Web.Contents(URL, [Headers=[#&quot;Accept-Encoding&quot;=&quot;gzip&quot;]]))[hourly],
//Convert to table
#&quot;Converted to Table&quot; = Record.ToTable(Source),
//Expand the lists of values
#&quot;Expand Lists&quot; = Table.FromColumns(
#&quot;Converted to Table&quot;[Value], #&quot;Converted to Table&quot;[Name]),
//set the data types
#&quot;Changed Type&quot; = Table.TransformColumnTypes(#&quot;Expand Lists&quot;,{{&quot;time&quot;, type datetime}, {&quot;relativehumidity_2m&quot;, Int64.Type}, {&quot;windspeed_180m&quot;, type number}, {&quot;temperature_180m&quot;, type number}})
in
#&quot;Changed Type&quot;

Partial Results<br>
VBA – API调用在Excel中显示天气

答案3

得分: 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
英文:

Try :

Dim windspeed_180m As Double
If Not IsObject(hourlyData(i)(&quot;windspeed_180m&quot;)) And TypeName(hourlyData(i)(&quot;windspeed_180m&quot;)) = &quot;Double&quot; Then
.Cells(i, 3).Value = CDbl(hourlyData(i)(&quot;windspeed_180m&quot;))
Else
.Cells(i, 3).Value = &quot;&quot;
End If

huangapple
  • 本文由 发表于 2023年5月21日 16:18:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76298919.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定