使用VBA提取XML属性
我不是一名开发人员,拥有非常有限的XML知识,但是我学到了过去3 - 4天在Web上进行的研究。所以提前对这个问题的基本层面表示歉意。我正试图结束这一次的任务。使用VBA提取XML属性
我有一些VBA Excel知识,目前我正尝试使用VBA从SEC文件网站上的给定公司页面提取SIC代码属性。作为一个例子,这是网站沃尔玛
在你可以看到顶部的蓝色条“SIC:5331”这是在5331我试图返回到VBA变量,这样我可以填充电子表格。当我在IE和陈词滥调查看源文件右键单击页面的一部分是相关的XML全文:
<div id="contentDiv">
<!-- START FILER DIV -->
<div style="margin: 15px 0 10px 0; padding: 3px; overflow: hidden; background-color: #BCD6F8;">
<div class="mailer">Mailing Address
<span class="mailerAddress">702 SOUTHWEST 8TH STREET</span>
<span class="mailerAddress"> BENTONVILLE AR 72716 </span>
</div>
<div class="mailer">Business Address
<span class="mailerAddress">702 SOUTHWEST 8TH ST</span>
<span class="mailerAddress">BENTONVILLE AR 72716 </span>
<span class="mailerAddress">5012734000</span>
</div>
<div class="companyInfo">
<span class="companyName">WAL MART STORES INC <acronym title="Central Index Key">CIK</acronym>#: <a href="/cgi-bin/browse-edgar?action=getcompany&CIK=0000104169&owner=exclude&count=40">0000104169 (see all company filings)</a></span>
<p class="identInfo"><acronym title="Standard Industrial Code">SIC</acronym>: <a href="/cgi-bin/browse-edgar?action=getcompany&SIC=5331&owner=exclude&count=40">5331</a> - RETAIL-VARIETY STORES<br />State location: <a href="/cgi-bin/browse-edgar?action=getcompany&State=AR&owner=exclude&count=40">AR</a> | State of Inc.: <strong>DE</strong> | Fiscal Year End: 0131<br />(Assistant Director Office: 2)<br />Get <a href="/cgi-bin/own-disp?action=getissuer&CIK=0000104169"><b>insider transactions</b></a> for this <b> issuer</b>.
<br />Get <a href="/cgi-bin/own-disp?action=getowner&CIK=0000104169"><b>insider transactions</b></a> for this <b>reporting owner</b>.
</p>
</div>
</div>
</div>
在试图理解VBA如何可能被用来提取SIC,我发现下面的职位上您的网站:
Query and parse xml attribute value into XLS using VBA
我试图复制应用barrowc的答案/粘贴到Excel工作模块插入路径沃尔玛申请但是当我步我得到Debug.Print“*** **“但我没有得到任何n.Text的东西。
Sub test4()
Dim d As MSXML2.DOMDocument60
Dim i As IXMLDOMNodeList
Dim n As IXMLDOMNode
Set d = New MSXML2.DOMDocument60
d.async = False
d.Load ("http://www.sec.gov/cgi-bin/browse-edgar?company=&match=&CIK=886475&filenum=&State=&Country=&SIC=&owner=exclude&Find=Find+Companies&action=getcompany")
Debug.Print "*****"
Set i = d.SelectNodes("//div[@id='contentDiv']")
For Each n In i
Debug.Print n.Text
Next n
Debug.Print "*****"
Set d = Nothing
End Sub
我已经试过各种字符串d.SelectNodes()
,但我不知道有足够的了解这个话题明白我要去哪里错了。因此,对我的语法或对资源的指针的评论将非常有用。
如果您只对SIC感兴趣,那么尝试解析整个DOM结构并不值得花时间。相反,识别一组独特的字符,搜索该字符,然后从那里提取SIC。
以下功能就是这样做的。你只需要通过它的页面的完整HTML源,它将返回SIC:
Function ExtractSIC(SourceHtml As String) As String
Const PrefixChars As String = "&SIC="
Const SuffixChars As String = "&"
Dim StartPos As Long, EndPos As Long
StartPos = InStr(SourceHtml, PrefixChars)
If StartPos = 0 Then Exit Function
StartPos = StartPos + Len(PrefixChars)
EndPos = InStr(StartPos, SourceHtml, SuffixChars) - 1
ExtractSIC = Mid(SourceHtml, StartPos, EndPos - StartPos + 1)
End Function
有趣的是你说的。我一直在努力并行地尝试解析DOM结构以及在网页上进行字符串搜索。直到大约一个小时前,两个都没有成功。我收到了另一个论坛的评论,这个论坛给了我一个可行的想法,尽管效率可能很低。我会在一会儿发帖。感谢您的上面的代码。我也会尝试。 – mchac 2013-05-08 16:59:25
我无法将我的代码作为5个小时以上的答案发布。当我被允许时,我会回复。在此期间我正在尝试你的。 – mchac 2013-05-08 17:03:56
再次感谢mwolfe。我已经在下面发布了我的代码,但是您提供的代码更优雅。我知道SIC只有4位数,所以我很懒惰,并且在代码中做了一个假设,并且可能会在将来抛出错误。你可以在注释部分看到我是如何做到的。 – mchac 2013-05-09 13:14:29
再次感谢mwolfe。我已经在下面发布了我的代码,但是您提供的代码更优雅。我知道SIC只有4位数,所以我很懒惰,并且在代码中做了一个假设,并且可能会在将来抛出错误。你可以在注释部分看到我是如何做到的。
Sub GetSICs()
Application.ScreenUpdating = False
Dim AWBN As String
Dim ASN As String
Dim CIK As String
Dim NUM_FILES_TO_GET As Long
Dim COUNTER As Long
Dim SICTagPos As Integer
Dim SIC As String
Set IEbrowser = CreateObject("InternetExplorer.application")
IEbrowser.Visible = False
AWBN = ActiveWorkbook.Name
ASN = ActiveSheet.Name
Workbooks(AWBN).Sheets(ASN).Range("A1").Select
ActiveCell.Offset(0, 11) = "SIC"
NUM_FILES_TO_GET = Application.WorksheetFunction.CountA(Range("A:A"))
For COUNTER = 1 To 3 'NUM_FILES_TO_GET
Application.StatusBar = "Counter = " & COUNTER
'SICTagPos = 0
CIK = ActiveCell.Offset(COUNTER, 2)
IEbrowser.Navigate URL:="http://www.sec.gov/edgar/searchedgar/companysearch.html"
Do
DoEvents
Loop Until IEbrowser.readyState = 4
Set frm = IEbrowser.Document.forms(0)
frm("CIK").Value = CIK
frm.submit
While IEbrowser.Busy Or IEbrowser.readyState <> 4: DoEvents: Wend
SIC = ExtractSIC(IEbrowser.Document.body.innerhtml)
'SICTagPos = InStr(1, IEbrowser.Document.body.innerhtml, "SIC=")
'SIC = Right(Left(IEbrowser.Document.body.innerhtml, SICTagPos + 7), 4)
ActiveCell.Offset(COUNTER, 11).NumberFormat = "@"
ActiveCell.Offset(COUNTER, 11) = SIC
Next
Application.StatusBar = False
Application.ScreenUpdating = True
End Sub
Function ExtractSIC(SourceHtml As String) As String
Const PrefixChars As String = "&SIC="
Const SuffixChars As String = "&"
Dim StartPos As Long, EndPos As Long
StartPos = InStr(SourceHtml, PrefixChars)
If StartPos = 0 Then Exit Function
StartPos = StartPos + Len(PrefixChars)
EndPos = InStr(StartPos, SourceHtml, SuffixChars) - 1
ExtractSIC = Mid(SourceHtml, StartPos, EndPos - StartPos + 1)
End Function
我想对[xpath选择器](https://developer.mozilla.org/en-US/docs/XPath)进行一些研究,以了解如何正确选择节点。那么至少你会更好地理解你可能需要选择的东西。我会亲自选择'acronym'节点,然后选择它的第二个进程兄弟。虽然您可能会遇到麻烦,因为这是HTML并且看起来不是有效的xml。你可能有更好的运气解析它作为一个字符串,而不是XML。特别是如果结构不会改变。 – 2013-05-08 14:56:00
您是否只需要该页面中的SIC,或者您是否使用该SIC作为您通常需要提取的数据类型的示例? – mwolfe02 2013-05-08 15:13:58
我只需要该页面的SIC代码,然后再重复其他军团。我在公司的Excel中创建了一个清单,并从SEC索引文件中提取了他们的CIK号码。我的意图是创建一个循环,在子接受该网址并迭代替换CIK号码,调用网页,从生成的网页拉SIC,然后插入下一个CIK等。 – mchac 2013-05-08 16:54:36