Search code examples
vbaie-automation

VBA IE automation - variable for element loses reference when button clicked on webpage


I use VBA and IE automation to open a webpage, login, navigate by filling some input fields and clicking specific buttons to the webpage and finally get some data from it.

While navigating I set several variables to elements from the webpage. Next I click a button to the webpage and then some of the variables (ele0, ele and eleCol0) "lose reference". By "lose reference" I mean that they neither point to the elements nor are equal to nothing.


This is how the variables (ele0, ele and eleCol0) appear in the Locals Window: enter image description here


And here is some of the code:

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

Can somebody please explain me:

  • What is this the meaning of this strange state of the variables?
  • Why or when is this happening?

I need to understand this to be able avoid it.


Solution

  • You often get stale elements on refresh e.g with certain click events. Provided the element exists on the newly loaded content then it is usually fine to simply avoid storing in variables and always work off ie.document.. I am assuming that you are working with a live document which can update with actions you perform. I would then pass the internet explorer instance locally rather than a stored HTMLDocument variable globally.