VBA IE自动化-单击网页上的按钮时元素的变量失去引用

VBA IE自动化-单击网页上的按钮时元素的变量失去引用,vba,ie-automation,Vba,Ie Automation,我使用VBA和IE automation打开一个网页,登录,通过填写一些输入字段和单击网页的特定按钮导航,最后从中获取一些数据 在导航时,我为网页中的元素设置了几个变量。接下来,我单击网页上的一个按钮,然后一些变量(ele0,ele和eleCol0)“失去参考”。所谓“失去参照”,我的意思是它们既不指向元素,也不等于零 这就是变量(ele0、ele和eleCol0)在局部变量窗口中的显示方式: 下面是一些代码: Option Explicit Public Sub Get_data()

我使用VBA和IE automation打开一个网页,登录,通过填写一些输入字段和单击网页的特定按钮导航,最后从中获取一些数据

在导航时,我为网页中的元素设置了几个变量。接下来,我单击网页上的一个按钮,然后一些变量(
ele0
ele
eleCol0
)“失去参考”。所谓“失去参照”,我的意思是它们既不指向元素,也不等于零


这就是变量
ele0
ele
eleCol0
)在局部变量窗口中的显示方式:


下面是一些代码:

Option Explicit


Public Sub Get_data()
Dim frmDocDap As HTMLDocument, frmDocPlir As HTMLDocument
Dim ele0 As HTMLHtmlElement, ele As HTMLHtmlElement, ele2 As HTMLHtmlElement, ele3 As HTMLHtmlElement
Dim frm As HTMLFrameElement
Dim eleCol As IHTMLElementCollection, eleCol2 As IHTMLElementCollection, eleCol0 As IHTMLElementCollection
Dim i As Integer, j As Integer
Dim sTemp As String
Dim sArr() As String
Dim bFlag As Boolean
Dim iRow As Long
Dim wsHid As Worksheet

'get doc from a frame:
    Set frm = html.getElementById("tabIframe2") 'html is a global variable of type HTMLDocument that holds the current IE document.
    Set frmDocDap = frm.contentWindow.Document
'udf that delays code by specific seconds:
    Delay_Code_By 1
'get table:
    Set ele0 = frmDocDap.getElementById("multi_record")
'no records check:
    If ele0 Is Nothing And frmDocDap.body.Children.Item(6).innerText = "No records." Then
        If MsgBox("Close Internet Explorer?", vbQuestion + vbYesNo, "No records!") = 6 Then _
            oIE.Quit
        GoTo END_HERE
    End If
    Set ele0 = ele0.FirstChild
'get first row:
    Set eleCol0 = ele0.getElementsByTagName("tr")
'get a specific link.
    Set ele2 = html.getElementById("describe")
    Set ele2 = ele2.getElementsByTagName("a")(5)

i = 2
NEXT_ITEM:
'click record to open details about it.
    Set ele = eleCol0(i)
    ele.Click
'at this point reference is lost for variables ele0, eleCol0, ele. All the others are OK.
    ele2.Click
    
    '...
    
END_HERE:
    Set ele0 = Nothing
    Set ele = Nothing
    Set ele2 = Nothing
    Set frm = Nothing
    Set eleCol0 = Nothing
    Set frmDocDap = Nothing
End Sub


Public Sub Delay_Code_By(seconds As Integer)
Dim endTime As Date
    endTime = DateAdd("s", seconds, Now)
    Do While Now < endTime
        DoEvents
    Loop
End Sub
选项显式
公共子对象获取_数据()
将frmDocDap设置为HTMLDocument,将frmDocPlir设置为HTMLDocument
将ele0调暗为HTMLHtmlElement,ele调暗为HTMLHtmlElement,ele2调暗为HTMLHtmlElement,ele3调暗为HTMLHtmlElement
Dim frm作为HTMLFrameElement
将eleCol调暗为IHTMlementCollection,将eleCol2调暗为IHTMlementCollection,将eleCol0调暗为IHTMlementCollection
尺寸i为整数,j为整数
作为字符串的Dim sTemp
Dim sArr()作为字符串
作为布尔值的Dim bFlag
暗淡无光
将wsHid设置为工作表
'从框架获取文档:
Set frm=html.getElementById(“tabIframe2”)“html是一个HTMLDocument类型的全局变量,它保存当前IE文档。
设置frmDocDap=frm.contentWindow.Document
'将代码延迟特定秒数的udf:
延迟\u代码\u 1
'获取表格:
Set ele0=frmDocDap.getElementById(“多记录”)
“无记录检查:
如果ele0为Nothing且frmDocDap.body.Children.Item(6).innerText=“无记录。”则
如果MsgBox(“关闭Internet Explorer?”,vbQuestion+vbYesNo,“无记录!”)=6,则_
好的,退出
转到这里结束
如果结束
设置ele0=ele0.FirstChild
'获取第一行:
Set eleCol0=ele0.getElementsByTagName(“tr”)
'获取特定链接。
Set ele2=html.getElementById(“描述”)
Set ele2=ele2.getElementsByTagName(“a”)(5)
i=2
下一项:
'单击记录以打开有关它的详细信息。
设置ele=eleCol0(i)
ele.点击
'此时变量ele0、eleCol0、ele的引用丢失。其他的都好。
ele2.点击
'...
在这里结束:
设置ele0=无
设置ele=Nothing
设置ele2=无
设置frm=无
设置eleCol0=无
设置frmDocDap=Nothing
端接头
公共子延迟码(秒为整数)
Dim endTime作为日期
endTime=DateAdd(“s”,秒,现在)
现在就做
谁能给我解释一下:

  • 这个奇怪的变量状态是什么意思
  • 为什么或何时会发生这种情况

我需要理解这一点才能避免它。

刷新时,您经常会遇到过时的元素,例如某些单击事件。如果元素存在于新加载的内容中,则通常可以简单地避免存储在变量中,并始终使用ie.document。。我假设您正在使用一个实时文档,该文档可以使用您执行的操作进行更新。然后,我将在本地传递internet explorer实例,而不是全局传递存储的HTMLDocument变量。

我明白了。请再问一个问题。新文档中不存在该元素,但我将多次切换到第一个文档。在这种情况下,是否有方法固定该元素?或者我应该在每次返回第一个文档时都获取它吗?每次我在本地传递internet explorer实例和html文档时,都要获取一个新的引用,而不是像您建议的那样使用公共变量。非常感谢。