0

I am fairly new to VBA and trying to log in to a website. I have gotten the code to get me to the website then look up the input names for the username and password elements. This was important because everytime the page opens the names are slightly different so I can't just inspect the element name and use that as a fixed value.

The username input name always starts with "txt_1_" then some numbers and the password goes "txt_2_" and some numbers. That is the reason I have the if statement that looks for the names similar to those.

The error I am currently receiving is "Run-time error '438': Object doesn't support this property or method"

Below is what I have so far:

Sub login()
    Const Url$ = "examplewebsite.com"
    Dim HTMLDoc As HTMLDocument
    Dim oHTML_Element As IHTMLElement
    Dim ie As Object
    Set ie = CreateObject("InternetExplorer.Application")
    With ie
        .Navigate Url
        ieBusy ie
        .Visible = True
        
        Set HTMLDoc = ie.Document
        
        Dim ID1 As String, ID2 As String
        For Each oHTML_Element In HTMLDoc.getElementsByTagName("input")
            If oHTML_Element.Name Like "txt_1*" Then ID1 = oHTML_Element.Name
            If oHTML_Element.Name Like "txt_2*" Then ID2 = oHTML_Element.Name
        Next

        Debug.Print ID1
        Debug.Print ID2

        Dim oLogin As Object, oPassword As Object
        Set oLogin = .Document.getElementsByTagName(ID1)
        Set oPassword = .Document.getElementsByTagName(ID2)

        oLogin.Value = "MyUsername"
        oPassword.Value = "MyPassword"
        .Document.forms(0).submit
    End With
End Sub

Sub ieBusy(ie As Object)
    Do While ie.Busy Or ie.ReadyState < 4
        DoEvents
    Loop
End Sub

1 Answer 1

2

Issue

getElementsByTagName returns a collection of elements with the given tag name. So for your For loop it works for you to loop all the elements with the tagname of input.

However, when you are trying to assign oLogin and oPassword using the same getElementsByTagName it won't work, as you are passing a name attribute to it and not a tagname.

Solution

Using your code you can simply assign oLogin and oPassword in your for loop.

For Each oHTML_Element In HTMLDoc.getElementsByTagName("input")
    If oHTML_Element.Name Like "txt_1*" Then set oLogin = oHTML_Element
    If oHTML_Element.Name Like "txt_2*" Then set oPassword = oHTML_Element
Next

Another solution could be by using the attribute selector, specifically the starts with symbol. That pattern looks like [attribute^="value"]. So in your case input[name^="txt_1"] and input[name^="txt_2"].

This would then be used with querySelector instead of getElementsByTagName. This means you wouldn't have to loop either.

set oLogin = HTMLDoc.querySelector("input[name^=""txt_1""]")
set oPassowrd = HTMLDoc.querySelector("input[name^=""txt_2""]")

A few extra notes

  • You are using Late Binding for the Microsoft Internet Controls library — really you should use it early binding by creating a reference to the library.
  • Try to avoid using Systems Hungarian notation with your variable names — adding o before password and login gets really confusing for others to read (Read This Article).
  • Avoid writing your declarations on a single line. This is easy to write errors, and also is harder to read.
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.