Browser Links

Jendra found an interesting bug while automating Internet Explorer. The Document object has a dozen or so collections that allow you to access various components of the html document. For instance, you can use the Links collection to iterate through all the hyperlinks (anchor tags with an href attribute) or you can use the All collection to iterate HTMLElements of any type.

Jendra has an image tag with a name attribute of “links”. It seems when you have an element with a name attribute equal to the name of a collection. I’ve tested it with Links and All and I assume it screws up on any collection name.

I set up a couple of html docs; TestLinks.htm and TestLinks2.htm. In the TestLinks2, I changed the name attribute to “links1? and the code did not fail. Below is the code I used to test it.

I don’t see a decent workaround to this bug. Jendra decided to test the Typename of the objects in the loop and exit gracefully if it was different than expected. Of course that means the code won’t actually work, but at least it won’t throw an ugly run-time error.

Here’s the test code. When the Navigate line is changed to TestLinks2, no error. As it is, I get error 438 “Object doesn’t support this property or method”. In debug mode from the immediate window you can see why

?Typename(ieDoc.Links)
HTMLImg

Of course an HTMLImg object doesn’t have a Length property so the For i = 1 to… line fails.

Sub TestLinksColl()
   
    Dim ieApp As InternetExplorer
    Dim ieDoc As Object
    Dim i As Long
   
    Set ieApp = New InternetExplorer
   
    ieApp.Navigate “/excel/TestLinks.html”
   
    Do
        DoEvents
    Loop Until ieApp.ReadyState = READYSTATE_COMPLETE
   
    Set ieDoc = ieApp.Document
   
    Debug.Print “******Links collections”
    For i = 1 To ieDoc.links.Length
        Debug.Print i, Mid(ieDoc.links(i – 1).innertext, 1, 20), TypeName(ieDoc.links(i – 1))
    Next i
   
    Debug.Print
    Debug.Print “******All collection”
    For i = 1 To ieDoc.all.Length
        Debug.Print i, Mid(ieDoc.all(i – 1).innertext, 1, 20), TypeName(ieDoc.all(i – 1))
    Next i
   
End Sub
Posted in Uncategorized

4 thoughts on “Browser Links

  1. I’ve got two quite decent workaround for you. :)

    One is to use early binding for the ieDoc object, which somehow seems to clarify the compiler’s mind and remove the confusion between “links” as an element name and as an element type. Add a reference to “Microsoft HTML object library”, declare ieDoc As HTMLDocument, and the loop works fine.

    The other is to loop through all elements and check their typename. This works with both early and late binding.

    For Each ieElem In ieDoc.body.all
    If TypeName(ieElem) = “HTMLAnchorElement” Then
    Debug.Print ieElem.innertext
    End If
    Next ieElem

  2. When I copy and paste the above code into Excel’s VBA editor, it doesn’t register as a subroutine that I can actually run. My problem is that:

    Dim ieApp As InternetExplorer

    I don’t register “InternetExplorer” as a valid type, e.g. String, Long, Single, etc.

    Can you help?

    Thanks,

    – Peter


Posting code? Use <pre> tags for VBA and <code> tags for inline.

Leave a Reply

Your email address will not be published.