Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Html Excel在尝试检查DispStaticNodeList时崩溃_Html_Excel_Vba_Dom_Web Scraping - Fatal编程技术网

Html Excel在尝试检查DispStaticNodeList时崩溃

Html Excel在尝试检查DispStaticNodeList时崩溃,html,excel,vba,dom,web-scraping,Html,Excel,Vba,Dom,Web Scraping,情况: 我试图检查变量a,该变量在“局部变量”窗口中显示为dispstationNodeList对象;每次我尝试这样做时,Excel都会崩溃 以下是局部变量窗口中的变量a,其类型显然为dispstationNodeList: 复制Excel崩溃: Option Explicit Public Sub TestPass() Dim html As HTMLDocument Set html = GetTestHTML Dim a As Object, b As Obje

情况:

我试图检查变量
a
,该变量在“局部变量”窗口中显示为
dispstationNodeList
对象;每次我尝试这样做时,Excel都会崩溃

以下是局部变量窗口中的变量
a
,其类型显然为
dispstationNodeList

复制Excel崩溃:

Option Explicit

Public Sub TestPass()
    Dim html As HTMLDocument
    Set html = GetTestHTML
    Dim a As Object, b As Object

    Set a = html.querySelectorAll("div.intro p")

    Dim i As Long

    For i = 0 To Len(a) -1
        On Error Resume Next
        Debug.Print a(i).innerText    '<== HTMLParaElement
        On Error GoTo 0
    Next i
End Sub

Public Function GetTestHTML(Optional ByVal url As String = "https://www.w3schools.com/cssref/trysel.asp") As HTMLDocument
    Dim http As New XMLHTTP60
    Dim html As New HTMLDocument
    With http                                    'Set http = CreateObject("MSXML2.XMLHttp60")
        .Open "GET", url, False
        .send
        html.body.innerHTML = .responseText
        Set GetTestHTML = html
    End With
End Function
Public Sub TestFail()
    Dim html As HTMLDocument
    Set html = GetTestHTML
    Dim a As Object, b As Object

    Set a = html.querySelectorAll("div.intro p")

    For Each b In a

    Next b
End Sub
  • 尝试在“局部变量”窗口中展开该项会导致Excel崩溃
  • 尝试为每个循环一个
    ,也会导致崩溃。*TestFail
  • 研究重点:

    Option Explicit
    
    Public Sub TestPass()
        Dim html As HTMLDocument
        Set html = GetTestHTML
        Dim a As Object, b As Object
    
        Set a = html.querySelectorAll("div.intro p")
    
        Dim i As Long
    
        For i = 0 To Len(a) -1
            On Error Resume Next
            Debug.Print a(i).innerText    '<== HTMLParaElement
            On Error GoTo 0
        Next i
    End Sub
    
    Public Function GetTestHTML(Optional ByVal url As String = "https://www.w3schools.com/cssref/trysel.asp") As HTMLDocument
        Dim http As New XMLHTTP60
        Dim html As New HTMLDocument
        With http                                    'Set http = CreateObject("MSXML2.XMLHttp60")
            .Open "GET", url, False
            .send
            html.body.innerHTML = .responseText
            Set GetTestHTML = html
        End With
    End Function
    
    Public Sub TestFail()
        Dim html As HTMLDocument
        Set html = GetTestHTML
        Dim a As Object, b As Object
    
        Set a = html.querySelectorAll("div.intro p")
    
        For Each b In a
    
        Next b
    End Sub
    
  • 我做了一些挖掘,搜索诸如
    Excel
    +
    Crash
    +
    dispstationNodeList
    之类的组合,结果为零;至少我用过谷歌搜索词。我很确定我的谷歌搜索引擎很弱
  • 如果我相信这一点,那么我正在处理一个受
    MSHTML
    支持的COM对象

  • 根据:

  • 如果名称是DispStaticNodeList,我们可以非常确定它是一个 数组..(或至少具有数组语义)

    基于第3点,我编写了下面的代码,
    TestPass
    ,它确实成功地在上面循环,但我不完全理解为什么。我设置了一个对象,然后循环了它的len

  • 我刚刚找到了以下状态:
  • 节点列表对象是节点的集合,例如 属性,例如Node.childNodes和document.querySelectorAll() 方法

    因此,似乎该对象可能是一个
    节点列表
    ,在即时窗口中给出的描述似乎是正确的,作为一个列表,我可以循环它的长度,但不确定为什么每个
    都不起作用,以及为什么Excel崩溃。他的同事建议,由于数据的层次性,它可能会崩溃。我进一步注意到有名为
    IDOMNodeIterator
    NodeIterator
    的类,但我不确定是否可以按照
    NodeList
    方法的描述使用这些类

    问题:

    Option Explicit
    
    Public Sub TestPass()
        Dim html As HTMLDocument
        Set html = GetTestHTML
        Dim a As Object, b As Object
    
        Set a = html.querySelectorAll("div.intro p")
    
        Dim i As Long
    
        For i = 0 To Len(a) -1
            On Error Resume Next
            Debug.Print a(i).innerText    '<== HTMLParaElement
            On Error GoTo 0
        Next i
    End Sub
    
    Public Function GetTestHTML(Optional ByVal url As String = "https://www.w3schools.com/cssref/trysel.asp") As HTMLDocument
        Dim http As New XMLHTTP60
        Dim html As New HTMLDocument
        With http                                    'Set http = CreateObject("MSXML2.XMLHttp60")
            .Open "GET", url, False
            .send
            html.body.innerHTML = .responseText
            Set GetTestHTML = html
        End With
    End Function
    
    Public Sub TestFail()
        Dim html As HTMLDocument
        Set html = GetTestHTML
        Dim a As Object, b As Object
    
        Set a = html.querySelectorAll("div.intro p")
    
        For Each b In a
    
        Next b
    End Sub
    
    什么是
    a
    ,当试图检查或循环每个
    时,为什么会导致Excel崩溃

    成功循环的代码:

    Option Explicit
    
    Public Sub TestPass()
        Dim html As HTMLDocument
        Set html = GetTestHTML
        Dim a As Object, b As Object
    
        Set a = html.querySelectorAll("div.intro p")
    
        Dim i As Long
    
        For i = 0 To Len(a) -1
            On Error Resume Next
            Debug.Print a(i).innerText    '<== HTMLParaElement
            On Error GoTo 0
        Next i
    End Sub
    
    Public Function GetTestHTML(Optional ByVal url As String = "https://www.w3schools.com/cssref/trysel.asp") As HTMLDocument
        Dim http As New XMLHTTP60
        Dim html As New HTMLDocument
        With http                                    'Set http = CreateObject("MSXML2.XMLHttp60")
            .Open "GET", url, False
            .send
            html.body.innerHTML = .responseText
            Set GetTestHTML = html
        End With
    End Function
    
    Public Sub TestFail()
        Dim html As HTMLDocument
        Set html = GetTestHTML
        Dim a As Object, b As Object
    
        Set a = html.querySelectorAll("div.intro p")
    
        For Each b In a
    
        Next b
    End Sub
    
    注意事项:

    我给一位同事发了一份测试手册,他也能用给出的例子重现这种行为

    项目参考资料:

    Option Explicit
    
    Public Sub TestPass()
        Dim html As HTMLDocument
        Set html = GetTestHTML
        Dim a As Object, b As Object
    
        Set a = html.querySelectorAll("div.intro p")
    
        Dim i As Long
    
        For i = 0 To Len(a) -1
            On Error Resume Next
            Debug.Print a(i).innerText    '<== HTMLParaElement
            On Error GoTo 0
        Next i
    End Sub
    
    Public Function GetTestHTML(Optional ByVal url As String = "https://www.w3schools.com/cssref/trysel.asp") As HTMLDocument
        Dim http As New XMLHTTP60
        Dim html As New HTMLDocument
        With http                                    'Set http = CreateObject("MSXML2.XMLHttp60")
            .Open "GET", url, False
            .send
            html.body.innerHTML = .responseText
            Set GetTestHTML = html
        End With
    End Function
    
    Public Sub TestFail()
        Dim html As HTMLDocument
        Set html = GetTestHTML
        Dim a As Object, b As Object
    
        Set a = html.querySelectorAll("div.intro p")
    
        For Each b In a
    
        Next b
    End Sub
    

    HTML示例(还提供了链接)

    
    h1欢迎来到我的主页/h1
    div class=“简介”
    pMy的名字是Donald span id=“Lastname”Duck。/span/p

    p id=“我的地址”style=“边框颜色:rgb(255,102,102);背景颜色:rgb(255,255,153)”>p id=“我的地址”我住在达克伯格/p

    pI有很多朋友:/p

    /div
    ul id=“Listfriends
    • 利古菲/李
    • 利米奇/李
    • Lidaysy/li
    • 利普卢托/李
    /保险商实验室
      我的朋友们都很棒!但是我真的很喜欢黛西!!/p

      p lang=“it”title=“Hello Beauty”再见贝拉/p

      如果名称是dispstationNodeList,我们可以非常确定它是一个数组..(或者至少具有数组语义)

      数组通常可以使用
      For Each
      循环进行迭代,但是使用
      For
      循环进行迭代。看起来您得到的并不完全是一个数组,虽然它似乎支持索引,但显然不支持枚举,这可以解释当您尝试使用
      For枚举数组时出现的问题r每个
      循环

      看起来“局部变量”工具窗口可能正在使用
      For Each
      语义列出集合中的项

      我不熟悉那个特定的库,所以这是一个有点(受过教育的)猜测,但是很容易创建一个自定义COM集合类型,它不能在VBA中用
      对每个
      循环进行迭代-通常错误是在VBA端捕获的…看起来库的枚举器实现中可能有错误(假设它有一个枚举器)导致它抛出一个异常,该异常最终未经处理,并以某种方式将所有内容都记录下来……问题是,您无法修复并重新编译该库……因此,您唯一能做的就是避免对每个
      循环使用
      迭代该类型,并避免在“局部变量”工具窗口中扩展它(因此,…经常保存您的工作!)

      从C#/.NET的角度给出了COM枚举如何工作的好主意。当然,该库不是托管代码(.NET),但使用的COM概念是相同的


      TL;DR:并不是因为您可以为…Next
      编写
      ,所以您可以为每个
      编写
      ;所涉及的COM类型必须明确支持枚举。如果VBA代码为每个
      循环编写
      ,那么它确实支持,因此它一定是类型枚举器中的一个bug。

      让我想知道…考虑到早期绑定,RuberDuck是否能够加载that类型库?我记得有一些令人惊讶的问题(如果不是彻底崩溃,就会导致解析器失败)只是在其中一个XML或HTTP标准库中迭代类型和成员,但我不记得是否是该库。@MathieuGuindon感谢您的响应。请问您指的是哪个库?同事想知道这是否与分层数据有关。我猜应该是HTML库。无论定义哪个此
      dispstationNodeList
      type;-)这与问题无关,但有一条(未经请求的)建议——始终对类型使用两部分命名。
      Dim html作为MSHTML.HTMLDocument