Xml 筛选每个实例的特定元素

Xml 筛选每个实例的特定元素,xml,vba,excel,Xml,Vba,Excel,我设法从EDGAR DB中提取数据。然而,我的代码从all实例文档中提取all数据。无论我多么努力地寻找一种方法,仅从选定的实例元素中拾取选定的元素文档,我都找不到一种方法。代码如下: Sub READSITE() Dim IE As InternetExplorer Dim els, el, colDocLinks As New Collection Dim lnk, res Dim Ticker As String Dim colXMLPaths A

我设法从EDGAR DB中提取数据。然而,我的代码从all实例文档中提取all数据。无论我多么努力地寻找一种方法,仅从选定的实例元素中拾取选定的元素文档,我都找不到一种方法。代码如下:

Sub READSITE()

    Dim IE As InternetExplorer
    Dim els, el, colDocLinks As New Collection
    Dim lnk, res
    Dim Ticker As String
    Dim colXMLPaths As New Collection
    Dim XMLElement As String
    Dim fillingType As String

    Set IE = New InternetExplorer

    IE.Visible = False

    Ticker = Worksheets("Sheet1").Range("A1").Value

    fillingType = Worksheets("Sheet3").Range("L1").Value

    LoadPage IE, "https://www.sec.gov/cgi-bin/browse-edgar?" & _
                  "action=getcompany&CIK=" & Ticker & "&type=" & fillingType & _
                  "&dateb=&owner=exclude&count=20"

    Set els = IE.Document.getelementsbytagname("a")
    For Each el In els
        If Trim(el.innertext) = "Documents" Then
            colDocLinks.Add el.href
        End If
    Next el

    For Each lnk In colDocLinks
        LoadPage IE, CStr(lnk)
        For Each el In IE.Document.getelementsbytagname("a")
            If el.href Like "*[0-9].xml" Then
                Debug.Print el.innertext, el.href
                colXMLPaths.Add el.href
            End If
        Next el
    Next lnk

    XMLElement = Range("C1").Value

    'For each link, open the URL and display the Debt Instrument Insterest Rate
    For Each lnk In colXMLPaths
        res = GetData(CStr(lnk), XMLElement)
        With Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
            .NumberFormat = "@"
            .Value = Ticker
            .Offset(0, 1).Value = lnk
            .Offset(0, 2).Value = res
        End With
    Next lnk

End Sub

Function GetData(sURL As String, sXMLElement As String)
    Dim strXMLSite As String
    Dim objXMLHTTP As New MSXML2.XMLHTTP
    Dim objXMLDoc As New MSXML2.DOMDocument
    Dim objXMLNodexbrl As MSXML2.IXMLDOMNode
    Dim objXMLNodeElement As MSXML2.IXMLDOMNode
    Dim objXMLNodeStkhldEq As MSXML2.IXMLDOMNode

    '''''''''''''''''''''
    Dim userBeanList As MSXML2.IXMLDOMNodeList
    Dim userbean As MSXML2.IXMLDOMNode
    Dim beanChild As MSXML2.IXMLDOMNode
    Dim i As Long
    '''''''''''''''''''''

    ' In Sheet 3 determine if Row 2 is free of data and set start row to 2. Else get the last free row in column b
    Sheets("Sheet3").Select
    Sheets("Sheet3").Range("B2").Select
    If ActiveCell.Value = "" Then
        i = 2
    Else
        Sheets("Sheet3").Range("B1").Select
        Selection.End(xlDown).Select
        ActiveCell.Offset(1, -1).Range("A1").Select
        i = ActiveCell.Row
    End If


    'Get tge XML from SEc

    GetData = "?" 'No data from XML
    objXMLHTTP.Open "GET", sURL, False  '<<EDIT: GET the site
    objXMLHTTP.send
    objXMLDoc.LoadXML objXMLHTTP.responseText
    objXMLDoc.setProperty "SelectionNamespaces", "xmlns:r='http://www.xbrl.org/2003/instance'"

    Set objXMLNodexbrl = objXMLDoc.SelectSingleNode("r:xbrl")

    'Get a single element value from the returned XML
    Set objXMLNodeElement = objXMLNodexbrl.SelectSingleNode(sXMLElement)

    If Not objXMLNodeElement Is Nothing Then
        GetData = objXMLNodeElement.Text
    End If

    'Print all nodes name and value for each Element in the XML
    Set userBeanList = objXMLDoc.SelectNodes("r:xbrl")
    For Each userbean In userBeanList
    Worksheets("Sheet3").Cells(i, 1).Value = sURL
        For Each beanChild In userbean.ChildNodes
                With Worksheets("Sheet3")
                    .Cells(i, 2).Value = beanChild.nodeName
                    .Cells(i, 3).Value = beanChild.Text
                End With
                i = i + 1
        Next beanChild
    Next userbean

End Function

Sub LoadPage(IE As Object, url As String)
    IE.Navigate url
    Do While IE.Busy Or IE.ReadyState <> READYSTATE_COMPLETE
        DoEvents
    Loop
End Sub
Sub-READSITE()
Dim IE作为InternetExplorer
Dim els、el、colDocLinks作为新系列
暗lnk,res
作为字符串的Dim-Ticker
将ColXmlPath设置为新集合
将XML元素设置为字符串
Dim fillingType为字符串
Set IE=新的InternetExplorer
可见=假
Ticker=工作表(“表1”).范围(“A1”).值
fillingType=工作表(“Sheet3”).范围(“L1”).值
加载页面,”https://www.sec.gov/cgi-bin/browse-edgar?" & _
“action=getcompany&CIK=“&Ticker&”&type=“&fillingType&”_
“&dateb=&owner=exclude&count=20”
设置els=IE.Document.getelementsbytagname(“a”)
对于每个el(单位:els)
如果Trim(el.innertext)=“Documents”,则
colDocLinks.Add el.href
如果结束
下一个el
对于ColdocLink中的每个lnk
装载页面IE,CStr(lnk)
对于IE.Document.getelementsbytagname(“a”)中的每个el
如果el.href像“*[0-9].xml”,那么
Debug.Print el.innertext,el.href
colXMLPaths.Add el.href
如果结束
下一个el
下一个lnk
XMLElement=范围(“C1”).值
'对于每个链接,打开URL并显示债务工具的利率
对于ColxmlPath中的每个lnk
res=GetData(CStr(lnk),XMLElement)
带有工作表(“Sheet1”)。单元格(Rows.Count,1)。结束(xlUp)。偏移(1,0)
.NumberFormat=“@”
.Value=Ticker
.偏移量(0,1)。值=lnk
.偏移量(0,2).值=分辨率
以
下一个lnk
端接头
函数GetData(sURL作为字符串,sxmlement作为字符串)
将strXMLSite设置为字符串
Dim objXMLHTTP作为新的MSXML2.XMLHTTP
Dim objXMLDoc作为新的MSXML2.DOMDocument
Dim objXMLNodexbrl作为MSXML2.IXMLDOMNode
Dim objXMLNodeElement作为MSXML2.IXMLDOMNode
Dim objXMLNodeStkhldEq作为MSXML2.IXMLDOMNode
'''''''''''''''''''''
Dim userBeanList作为MSXML2.IXMLDOMNodeList
将userbean作为MSXML2.IXMLDOMNode进行Dim
Dim beanChild作为MSXML2.IXMLDOMNode
我想我会坚持多久
'''''''''''''''''''''
'在第3页中,确定第2行是否没有数据,并将起始行设置为2。否则获取b列中的最后一个可用行
图纸(“图纸3”)。选择
图纸(“图纸3”)。范围(“B2”)。选择
如果ActiveCell.Value=”“,则
i=2
其他的
图纸(“图纸3”)。范围(“B1”)。选择
选择。结束(xlDown)。选择
ActiveCell.Offset(1,-1).范围(“A1”).选择
i=ActiveCell.Row
如果结束
'从SEc获取tge XML
GetData=“?”'没有来自XML的数据

objXMLHTTP.Open“GET”,sURL,False'如果希望每个实例最多只获取15个元素,请向循环添加一个条件/添加一个If语句,该语句将在15次迭代后退出循环。就像使用i=i+1控制打印行一样,使用一个新变量(x,y不重要)来计算通过beanChild循环的次数。如果您需要实际的代码,请让我知道,但如果您自己完成了所有这些编码,您似乎已经足够熟练,能够找到答案:)

编辑:

好的,这是一个我想说的例子。如果希望每个源最多15个元素,可以执行以下操作:

For Each userbean In userBeanList
Worksheets("Sheet3").Cells(i, 1).Value = sURL

x = 0  

For Each beanChild In userbean.ChildNodes
     If x < 15 then
           With Worksheets("Sheet3")
                .Cells(i, 2).Value = beanChild.nodeName
                .Cells(i, 3).Value = beanChild.Text
            End With
            i = i + 1
            x = x + 1
    Next beanChild
    Else
        Exit For
    End If
Next userbean
userBeanList中每个userbean的

工作表(“表3”)。单元格(i,1)。值=sURL
x=0
对于userbean.ChildNodes中的每个beanChild
如果x<15,则
带工作表(“表3”)
.Cells(i,2).Value=beanChild.nodeName
.Cells(i,3).Value=beanChild.Text
以
i=i+1
x=x+1
下一个beanChild
其他的
退出
如果结束
下一个用户bean

很抱歉我的回复太晚。工作逼着我来这里。由于我们是VBA新手,我们还没有自己完成所有的编码。我得到了user2140261和TimWilliams的帮助,你们可以在这里找到他们的贡献:在这里:我期待50-100个元素被提取。然而,如果你能详细阐述你的想法,以便我能研究它,请这样做,因为它可能会帮助我很大。不过,由于工作原因,我将在大约一个小时内回答你。我在一个洞日内尝试实现此功能:PDo您认为逻辑运算符If-then-else和多达50条else语句在使用模型时是有效的吗?我编辑了我的回答,向您展示了如何使用简单的If语句退出For-Each循环并在15个beanChild输出处停止,您可以通过在内部for each循环完成后不设置x=0来修改此设置,以获得连续计数的记录输出(或者更简单,不要使用新变量x,如果您想在50个总输出单元格处停止,请将If语句更改为If i<52)。非常感谢您的帮助,我的朋友。干杯我正试图用多维数组来实现它。你认为这是正确的策略吗?我已经编辑了你的标题。请参阅“”,其中的共识是“不,他们不应该”。