excel vba 中的网络查询

excel web query in vba

我有一项工作sheet,目前使用 Yahoo Finance API 和 MSXML 更新大约 200 只股票。我还想从其他没有 api 的网站获取一些其他信息,例如“http://www.earningswhisper.com/stocks.asp?symbol=googl”。

另外,例如,如果您查看下面该网页中的一些信息,您会看到发布日期为 1/29/2015。中间还有一些文本,目前是“[未确认]”,但在某些时候它会变成“[已确认]”,并且这两个文本项都很有趣。

由于缺乏更好的网络技能,我目前只有一个 sheet 和一个在代码中同步刷新的查询 Table。它起作用了……最终。我宁愿使用代码中的响应,但我不知道该怎么做。我不需要自动刷新此特定信息。

问题

  1. 是否有首选的 VBA 方式处理 html 响应?你能展示一个代码片段来说明吗?
  2. 是否可以相对容易地将 html 转换为 xml 或 json?代码片段?
  3. 如果 QueryTable 实际上是足够好的解决方案,那么使用事件为每只股票创建一个 sheet 并异步刷新会更快吗?

我知道网络上有大量信息,但其中大部分似乎都过时且令人困惑。我正在使用 Excel 2013.

我可以使用 html 和抓取 Table(6) 获取我想要的数据,如下面的代码所示。我想我可以解析 InnerText 但我怀疑有一种更简单的方法可以从中获取我需要的元素 table.

Sub TestHtml()
   Dim Resp, sText, FirstCode As String
   Dim oHttp, oFile, oTable As Object
   Dim lines As Variant

   Set oHttp = CreateObject("Microsoft.XMLHttp")
   oHttp.Open "GET", "http://www.earningswhisper.com/stocks.asp?   symbol=googl", False
   oHttp.send ("")
   Resp = oHttp.responseText
   Set oFile = CreateObject("htmlfile")
   oFile.Write Resp
   Set oTable = oFile.getElementsByTagName("Table")(6)
   sText = oTable.innertext
   MsgBox sText
End Sub

这是 table 中的一行,下面是完整的 table。

<tr onMouseover="this.className='newsart_s2'" onMouseOut="this.className='newsart'">
  <td width="67%" align=left valign=middle>&nbsp;Release Date: <font color='#505050'><small>[not confirmed]</small></font>
  </td>
  <td width="33%" align=right valign=middle><a href="calendar.asp?day=-5">1/29/2015</a> &nbsp;</td>
</tr>

使用 VBA 代码向下钻取并获取 table 中元素的最佳方法是什么?

<TABLE cellpadding=1 cellspacing=0 border=0 id=QEsts width="100%" bgcolor="#505050"><tr><td><TABLE cellpadding=2 cellspacing=0 border=0 width="100%" bgcolor="#FFFFFF" height='148'><tr><td valign=top>
<table cellpadding=0 cellspacing=0 border=0 width="100%" class='newsart'>
<tr><td colspan="2" bgcolor="#FFFFFF"><table width="100%" bgcolor="#FFFFFF" cellpadding=1 cellspacing=0 border=0><tr><td style="background-image: url('images/headbar2.gif'); background-color: #000000; BORDER-RIGHT: #000000 thin solid; BORDER-TOP: #000000 thin solid; FONT-WEIGHT: bold; FONT-SIZE: 12px; MARGIN: 2px; BORDER-LEFT: #000000 thin solid; COLOR: #e1b64b; BORDER-BOTTOM: #000000 thin solid; FONT-FAMILY: Arial;">&nbsp; 4th Quarter Ending December 2014</td></tr></table></td></tr>
<tr onMouseover="this.className='newsart_s2'" onMouseOut="this.className='newsart'"><td width="67%" align=left valign=middle> &nbsp;<b>Earnings Whisper</b> <small>&#174</small>: </td><td width="33%" align=right valign=middle><b>.24</b> &nbsp;</td></tr>
<tr onMouseover="this.className='newsart_s2'" onMouseOut="this.className='newsart'"><td width="67%" align=left valign=middle> &nbsp;Consensus Estimate:</td><td width="33%" align=right valign=middle>.16 &nbsp;</td></tr>
<tr onMouseover="this.className='newsart_s2'" onMouseOut="this.className='newsart'"><td width="67%" align=left valign=middle> &nbsp;Surprise Expectation <small><sup>1</sup></small>: </td><td width="33%" align=right valign=middle> &nbsp;</td></tr>
<tr onMouseover="this.className='newsart_s2'" onMouseOut="this.className='newsart'"><td width="67%" align=left valign=middle> &nbsp;Release Date: <font color='#505050'><small>[not confirmed]</small></font></td><td width="33%" align=right valign=middle><a href="calendar.asp?day=-5">1/29/2015</a> &nbsp;</td></tr>
<tr><td width="100%" align=right colspan="2" valign=middle>After Close &nbsp;</td></tr>
<tr onMouseover="this.className='newsart_s2'" onMouseOut="this.className='newsart'"><td width="67%" align=left valign=middle> &nbsp;Expected Time <small><sup>2</sup></small>: </td><td width="33%" align=right valign=middle>N/A &nbsp;</td></tr>
<tr onMouseover="this.className='newsart_s2'" onMouseOut="this.className='newsart'"><td width="67%" align=left valign=top> &nbsp;Conference Call: </td><td width="33%" align=right valign=top>4:30 PM ET &nbsp;<small><br> &nbsp;</small></td></tr>
</table>
</td></tr></TABLE></td></tr></TABLE>

</td>

您可以与 DOM 交互,因为您已成功创建该对象,但您知道在您的情况下,从上面的 table 获取必要值的最简单方法是将 InnerText 解析为字符串,试试下面的代码:

aTmp0 = Split(sText, "Release Date:")
If Ubound(aTmp0) = 1 Then
    aTmp1 = Split(aTmp0(1), "Expected Time")
    MsgBox aTmp1(0)
Else
    MsgBox "Release Date not found"
End If