VBA从多个Web位置提取XML数据

时间:2014-02-14 17:46:41

标签: xml excel vba excel-vba xbrl

在我的previous question中(所有需要的东西都在这个问题上;链接在这里是为了完整性和测量)我想要一种方法从Web位置将XML数据提取到Excel。我收到的代码(由user2140261提供)作为答案就在这里:

Sub GetNode()
Dim strXMLSite As String
Dim objXMLHTTP As MSXML2.XMLHTTP
Dim objXMLDoc As MSXML2.DOMDocument
Dim objXMLNodexbrl As MSXML2.IXMLDOMNode
Dim objXMLNodeDIIRSP As MSXML2.IXMLDOMNode

Set objXMLHTTP = New MSXML2.XMLHTTP
Set objXMLDoc = New MSXML2.DOMDocument

strXMLSite = "http://www.sec.gov/Archives/edgar/data/10795/000119312513456802/bdx-20130930.xml"

objXMLHTTP.Open "POST", strXMLSite, False
objXMLHTTP.send
objXMLDoc.LoadXML (objXMLHTTP.responseText)

Set objXMLNodexbrl = objXMLDoc.SelectSingleNode("xbrl")

Set objXMLNodeDIIRSP = objXMLNodexbrl.SelectSingleNode("us-gaap:DebtInstrumentInterestRateStatedPercentage")

Worksheets("Sheet1").Range("A1").Value = objXMLNodeDIIRSP.Text
End Sub  

但每家公司都有不同的XML实例文档,每个时期公司都会发布不同的XML实例文档(例如每季度,每年一次)。 因此,可以在不同的网站位置访问这些文档。

现在在前面的过程中我们可以看到我们只需要使用语句

strXMLSite = "http://www.sec.gov/Archives/edgar/data/10795/000119312513456802/bdx-20130930.xml"

...但这是我们事先知道我们想要来自网络中某个指定位置的数据

如果我们想在下面的图片中为星号(*)描绘的这4个不同位置提取一些数据,该怎么办

Dynamically changing the data pull target

我们怎样才能在Excel中输入我们的“坐标”,例如在我们的某个用户表单/单元格中输入,然后使用这些坐标使VBA“导航/抓取”就像我们在浏览器中导航一样?

我们输入的坐标可以是:

  • 股票代号(例如特斯拉汽车的TSLA)
  • 一种文件,例如10-Q's

您可以分别为BDX和ANN选择这些链接中的文件类型:

BDX LINK

ANN LINK

下面我们有两个网站位置,用于BDX公司的实例文档位置,2个用于ANN公司

我们如何通过简单地为VBA提供

来从所有四个实例文档中存在的XML元素(例如us-gaap:CommonStockValue)中提取
  1. 股票代码
  2. 文档类型(10-K,10-Q)
  3. 是否可以使用Microsoft XML Core Services (MSXML)或我们还需要其他图书馆?

    您可以看到触发此代码数千次并且每次将URL从Web浏览器复制到strXMLSite作为String值是多么不切实际....

1 个答案:

答案 0 :(得分:1)

[EDIT1]

回应评论:

  

对我们来说唯一剩下的就是了解URL的实际变化,以便通过stan concantenation来预测和操纵它们?用什么代码语言编写URL?

简短的回答是打开浏览器,右键单击您感兴趣的网页中的空白处,然后从弹出菜单中选择View Source

要重复其他帖子VBA href Crawl on Browser's Source Code中提供的示例,请执行以下操作:

在浏览器中打开Edgar在线公司搜索:https://www.sec.gov/edgar/searchedgar/companysearch.html

使用快速搜索功能搜索股票代码CRR,它会给我这个网址:https://www.sec.gov/cgi-bin/browse-edgar?CIK=CRR&Find=Search&owner=exclude&action=getcompany,其中包含Carbo Ceramics,Inc的公开文件清单。

现在,右键单击页面获取源代码并向下滚动到第91行。您将看到此代码块:

      <table class="tableFile2" summary="Results">

这是结果表的开头,显示公开文件清单。

         <tr>
            <th width="7%" scope="col">Filings</th>
            <th width="10%" scope="col">Format</th>
            <th scope="col">Description</th>
            <th width="10%" scope="col">Filing Date</th>
            <th width="15%" scope="col">File/Film Number</th>
         </tr>

这是包含列描述的表格的标题行。

<tr>
<td nowrap="nowrap">SC 13G</td>
<td nowrap="nowrap"><a href="/Archives/edgar/data/1009672/000108975514000003/0001089755-14-000003-index.htm" id="documentsbutton">&nbsp;Documents</a></td>
<td class="small" >Statement of acquisition of beneficial ownership by individuals<br />Acc-no: 0001089755-14-000003&nbsp;(34 Act)&nbsp; Size: 8 KB            </td>
            <td>2014-02-14</td>
            <td nowrap="nowrap"><a href="/cgi-bin/browse-edgar?action=getcompany&amp;filenum=005-48851&amp;owner=exclude&amp;count=40">005-48851</a><br>14615563         </td>
         </tr>

这是在SC 13G上提交的提交Statement of acquisition of beneficial ownership by individuals Acc-no: 0001089755-14-000003 (34 Act) Size: 8 KB2014-02-14的表格中的第一行实际数据。

那么,现在您想循环浏览此页面上的所有文档URL,这就是您询问URL所用语言的原因? (换句话说,抓取页面?)

[开始原始答案]

  

我们怎样才能在Excel中输入我们的“坐标”,例如在我们的某个用户表单/单元格中输入,然后使用这些坐标使VBA“导航/抓取”就像我们在浏览器中导航一样?

我在研究另一个问题时用google搜索“将谷歌搜索结果作为xml”。回来的一个有趣的打击是这个链接:http://nielsbosma.se/projects/seotools/functions/

我对此工具的优点没有任何陈述,但它似乎具有您要求的功能。

  

现在在前面的过程中我们可以看到我们只需要使用该语句   strXMLSite =“http://www.sec.gov/Archives/edgar/data/10795/000119312513456802/bdx-20130930.xml”   ...但是,这是我们事先知道我们想要来自Web中一个指定位置的数据

是的,所以一旦你获得某种网络抓取功能来返回xml文档链接列表,你首先需要把它们放在用户可以看到的地方。我的偏好是工作表上的范围,但您也可以在表单中加载列表或组合框。无论如何,您可以修改Sub GetNode()以接受基于用户选择的输入参数:

Sub GetNode(strUrl as String)
...
strXMLSite = strUrl
...
Worksheets("Sheet1").Range("A1").Value = objXMLNodeDIIRSP.Text
End Sub  

或者最好使它成为一个函数,它将xml作为文本返回给你,但是你想要消费:

Function GetNode(strUrl as String) as String
...
strXMLSite = strUrl
...
'return result
GetNode = objXMLNodeDIIRSP.Text
End Function  

总体上有趣的问题,我很高兴为您提供有关您发布的代码的反馈。您可以通过谷歌搜索来回答您的其他问题。