Ситуация:
Я пытаюсь проверить переменную a
, отображаемую как объект DispStaticNodeList
в окне локальных компьютеров;Excel вылетает каждый раз, когда я пытаюсь это сделать.
Вот переменная a
, по-видимому, типа DispStaticNodeList
, в окне localals:
Воспроизведение сбоя Excel:
- Попытка развернуть элемент в окне Locals приводит к сбою Excel.
- Попытка зацикливания
For Each
TestFail
Основные результаты исследований:
- Я сделал несколькокопаться в поисках таких комбинаций, как
Excel
+ Crash
+ DispStaticNodeList
, - ноль результатов;По крайней мере, с условиями поиска Google, которые я использовал.Я уверен, что мой Google-Fu был слабым. Если я верю в эту статью Я имею дело с COM-объектом, который поддерживается MSHTML
.
И в соответствии с это :
Если имя DispStaticNodeList, мы можем быть уверены, что этомассив .. (или, по крайней мере, имеет семантику массива).
Основываясь на пункте 3, я написал код, TestPass
ниже, который успешно зацикливается на нем, но я не полностьюпонимаю почему.Я установил объект, а затем зациклил его длина!
Я только что нашел
this , в котором говорится:
Объекты NodeList представляют собой наборы узлов, такие как возвращаемые свойствами, такими как Node.childNodes и документ.Метод querySelectorAll ().
Таким образом, кажется, что объект может быть NodeList
, что, учитывая описание в ближайшем окне, кажется правильным, и как список я могу зациклить его длину, ноне знаю, почему For Each
не работает и почему происходит сбой Excel.Коллега предполагает, что это может произойти сбой из-за иерархической природы данных.Я также отмечаю, что существуют классы с именами IDOMNodeIterator
и NodeIterator
, но я не уверен, смогу ли я использовать их в соответствии с описаниями для NodeList
методов здесь .
Вопрос:
Что такое a
и почему происходит сбой Excel при попытке выполнить проверку или цикл с For Each
?
кодом, которыйуспешно зацикливается:
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
* TestFail Код, вызывающий сбой:
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 (ссылка также указана)
<div class="noSel">
<h1 style=""><span class="markup"><h1></span>Welcome to My Homepage<span class="markup"></h1></span></h1>
<div id="helpIntro" style="">
<span class="markup"><div class="intro"></span>
<div class="intro">
<p style="margin-top: 4px; border-color: rgb(255, 102, 102); background-color: rgb(255, 255, 153);"><span class="markup"><p></span>My name is Donald <span id="Lastname" style=""><span class="markup"><span id="Lastname"></span>Duck.<span class="markup"></span></span></span><span class="markup"></p></span></p>
<p id="my-Address" style="border-color: rgb(255, 102, 102); background-color: rgb(255, 255, 153);"><span class="markup"><p id="my-Address"></span>I live in Duckburg<span class="markup"></p></span></p>
<p style="margin-bottom: 4px; border-color: rgb(255, 102, 102); background-color: rgb(255, 255, 153);"><span class="markup"><p></span>I have many friends:<span class="markup"></p></span></p>
</div>
<span class="markup"></div></span>
</div>
<br>
<div class="helpUl">
<span class="markup"><ul id="Listfriends></span>
<ul id="Listfriends" style="margin-top:0px;margin-bottom:0px;">
<li><span class="markup"><li></span>Goofy<span class="markup"></li></span></li>
<li><span class="markup"><li></span>Mickey<span class="markup"></li></span></li>
<li><span class="markup"><li></span>Daisy<span class="markup"></li></span></li>
<li><span class="markup"><li></span>Pluto<span class="markup"></li></span></li>
</ul>
<span class="markup"></ul></span>
</div>
<ul style="display:none;"></ul>
<p style=""><span class="markup"><p></span>All my friends are great!<span class="markup"><br></span><br>But I really like Daisy!!<span class="markup"></p></span></p>
<p lang="it" title="Hello beautiful" style=""><span class="markup"><p lang="it" title="Hello beautiful"></span>Ciao bella<span class="markup"></p></span></p>
Редактировать: я также смог сделать цикл следующим образом:
Public Sub Test()
Dim html As MSHTML.HTMLDocument, i As Long
Set html = GetTestHTML
For i = 0 To html.querySelectorAll("div.intro p").Length - 1
Debug.Print html.querySelectorAll("div.intro p")(i).innerText
Next i
End Sub