I want to click on a button in IE (which probably is not actually a button) using VBA. The problem is that there is no ID or name in the source of the "button" I want to click on.
Here is the part of the source of the webpage (see link):
Part of source (NEW)
I want to click on the part which has as text: "Informatie" in it. Im currently using the following code (just a part of it) in VBA. But when i excecute the code, nothing happens, not even an error message:
Dim e
Set e = HTMLDoc.getElementsByClassName("BackgroundApp")(0).getElementsByTagName("Div")(7).getElementsByTagName("td")(0)
e.Click
Hard to help without actual page, so I replicate it and here is the tested code:
Dim IE as Object
Dim objCollection As Object
Dim tdNode As Object
Set objCollection = IE.document.getElementsByTagName("td")
For Each tdNode In objCollection
If InStr(1, tdNode.innerHTML, "Informatie", vbTextCompare) > 0 Then
' "Informatie" button is found
tdNode.Click ' click it
Exit For
End If
Next tdNode
Give it a try and report back.
Related
I'm fairly new to HTML, so please bear with me on this. I am using Excel VBA to interact with an website, with the intent to automate this interaction.
Problem Statement
I have a web page with (what looks like) a button that I need to click on. In the HTML it is listed as a Menu Item. Im able to successfully click other buttons on the page, but those have < button > tags.
I have tried to use the click method by selecting it by ID but I get an 'Object Variable or With block variable not set' error.
Sub WD_auto()
Dim IE As New SHDocVw.InternetExplorer
Dim HTMLDoc As MSHTML.HTMLDocument
Dim HTMLSel As MSHTML.IHTMLElement
IE.Visible = True
IE.navigate "https://wd3.myworkday.com/redacted/d/home.htmld"
Do While IE.Busy = True Or IE.readyState <> 4: DoEvents: Loop
Set HTMLDoc = IE.document
Set HTMLSel = HTMLDoc.getElementById("88831e18a0894109a83c10bc9a9be6c7")
HTMLSel.Click
End Sub
The block of HTML that i think i need to interact with is shown below.
<div class="GNMRENADFGC GNMRENADBHC GNMRENADHHC" tabindex="-2"
id="88831e18a0894109a83c10bc9a9be6c7" role="menuitem"
aria-posinset="1" aria-setsize="3">
Any pointers or literature would be appreciated.
Ok after some more research i have a solution. I am just looping all the div tags and checking the Inner Text property of each until I find the one I want to click.
It works, but if anyone has a more elegant solution I'm all ears. The loop seems a bit wasteful, I would prefer to just refer directly to, and then click the element.
Set ElementsA = IE.document.getElementsByTagName("div")
For Each ElementA In ElementsA
On Error Resume Next
If ElementA.innerText = "User Name and Password login" Then
ElementA.Click
Exit For
End If
Next ElementA
I'm trying to set up an Excel form that auto-fills an HTML web form. I've figured out how to use VBA to get the elements and cycle through them to add values. My issue is with a text field that is revealed with the click of a check box. I can't have Excel check the box until after I've obtained the elements for the form.
I've looked at the html, and it looks like the field is hidden to some degree when the form is first loaded, as the id and everything can only be found in the tree once the box is checked. The problem is, this field won't show up in the VBA elements list no matter what I try. I've tried re-doing the Set command, and gotten an error when I do that. I'm not sure how to refresh the elements list in VBA to include the new input box.
I used the Set command to get all the elements
Set frm = ie.document.getElementByID("form1")
This is fine, but I can't use that same command to try to re-Set the element list. I get the run-time error 438 (Object doesn't support this property or method)
I tried making a Variant titled frm2, but I get the same error
Sub formFill()
Dim ie As Object
Dim frm As Variant
Dim element As Variant
Set ie = CreateObject("InternetExplorer.Application")
ie.navigate "THIS IS THE URL"
While ie.readyState <> 4: DoEvents: Wend
'Get form by ID
Set frm = ie.document.getElementByID("form1")
ie.Visible = True
For Each element In frm.elements
Select Case element.Name
Case "fv_RRFC$chkOtherModel"
element.Checked = True
element.FireEvent ("OnClick")
frm.getElementByID("fv_RRFC_txtOtherModel")(0).Value = "test model" 'I tried using the command here, but it didn't work
Case "fv_RRFC$txtRRFC_PROGRAM"
element.Value = "test"
Case "fv_RRFC$txtOtherModel"
element.Value = "test model"
'My attempt to add it to the Select Case. Not surprised this didn't work, as the for Each loop uses the list it had before
End Select
Next
End Sub
I expected to be able to re-load the elements list to interact and fill the newly revealed box, but I've had no luck finding a way to do that.
Here is a piece of code of the HTML page I am working on.
I am trying to programmatically click on the element highlighted in blue in the picture above.
Here is the code I wrote:
Set objIE = New SHDocVw.InternetExplorer
Do While objIE.Busy: DoEvents: Loop
Do Until objIE.readyState = READYSTATE_COMPLETE: DoEvents: Loop
Set IeDoc2 = objIE.Document
Set the_input_elements2 = IeDoc2.getElementsByClassName("parent-item")
For Each input_element2 In the_input_elements2
If input_element2.href = "javascript:directToSearch()" Then
input_element2.Click
Exit For
End If
Next input_element2
How do I click on an element of a ul in HTML using VBA?
When I run this code, nothing happens. No errors but no result.
Here's a couple of ways to refer to the element you're interested in:
'Targeted (if you know exactly at which order the elements appear in the list)
Dim li As HTMLListElement
Set li = IeDoc2.getElementById("accordion-leftmenu") 'get the list item you're interested in...
Debug.Print li.Children(1).innerText '...and access its sub-element in a targeted way
Debug.Print li.getElementsByTagName("a")(1).innerText '...or find all <a></a> elements contained in it and access the one you're interested in, in a targeted way
'Non targeted (you have to search for it)
Dim element As HTMLObjectElement
For Each element In IeDoc2.getElementsByTagName("a") 'loop through all <a></a> elements...
If element.innerText = "Advanced Search" Then '...and find the one you're interested in
Debug.Print element.innerText
End If
Next element
For demonstration purposes the above code just prints the inner text of the element. You can modify it accordingly.
References used: Microsoft HTML Object Library
Also on a side note, please post the actual HTML next time rather than a screenshot of it. It would make it easier for people to help you.
Loop all "a" tags inside the ID of the left menu
IeDoc2.getElementById("accordion-leftmenu").getElementsByTagName("a")
in the loop check if the .innerText is "Advanced Search". click if it is.
Dim IeDoc2 As MSHTML.HTMLDocument
Dim the_input_elements2 As MSHTML.IHTMLElementCollection
Dim input_element2 As MSHTML.IHTMLElement
...
Set the_input_elements2 = IeDoc2.getElementById("accordion-leftmenu").getElementsByTagName("a")
For Each input_element2 In the_input_elements2
If input_element2.innerText = "Advanced Search" Then
input_element2.Click
Exit For
End If
Next input_element2
Edit: Alright, I've tested the code and it works. I did however have to make sure that Two references were checked: "Microsoft HTML Object Library" and "Microsoft Internet Controls".
I'm having issues with accessing a button with a span tag because it is nested within multiple tags. Here is a screenshot of the code with the highlighted portion that I'm trying to click on. [1]: https://imgur.com/a/e7Ya412 "HTML code"
I've already tried getting all of the spans element by using elementcollection but it still cannot access the span element that I need.
Dim HTMLspans As MSHTML.IHTMLElementCollection
Set HTMLspans = HTMLDoc.getElementsByTagName("span")
For Each HTMLspan In HTMLspans
Debug.Print HTMLspan.getAttribute("id")
This code will show me some span elements but not all. I also tried using nested for loops to see if I can access it like this but it still doesn't work.
For Each HTMLtable In HTMLtables.getElementsByTagName("table")
For Each HTMLtbody In HTMLtable.getElementsByTagName("tbody")
For Each HTMLtr In HTMLtbody.getElementsByTagName("tr")
For Each HTMLtd In HTMLtr.getElementsByTagName("td")
For Each HTMLspan In HTMLtd.getElementsByTagName("span")
Debug.Print HTMLspan.getAttribute("id")
Next HTMLspan
Next HTMLtd
Next HTMLtr
Next HTMLtbody
Next HTMLtable
This returns some span element but it doesn't show the one that I need.
With the right code, I expect to access the span tag with the id="revit_form_ComboButton_0_label"
But I can't access it. Could this code be the one that's causing issues?
<!--Portlet-Outlined Start-->
I cannot access any tags under this code and it's unfortunate that the website I'm using is not public.
Just use the id (unless there is a parent iframe/frame)
ie.document.getElementById("revit_form_ComboButton_0_label")
or
ie.document.querySelector("#revit_form_ComboButton_0_label")
This is the code I used to access the button on the iframe.
Dim HTMLDoc As MSHTML.HTMLDocument
Dim iframeDoc As MSHTML.HTMLDocument
Dim HTMLbutton As MSHTML.IHTMLElement
Set iframeDoc = HTMLDoc.frames("eZlmIFrame_iframe").Document
Set HTMLbutton = iframeDoc.getElementById("revit_form_ComboButton_0_label")
HTMLbutton.Click
I'm trying to fill out a form using VBA (just to get more skilled in programming with VBA). I noticed that the web form is not updating a hidden field when a radio button is checked via VBA.
To be more specific, the hidden field doesn't become visible after checking the radio button.
In my research to why that is I read that: "Events won't (usually) fire when you change the data programmatically". When this assumption is true, what's the difference between filling out a form manually or programmatically? But when this assumption is wrong, what adjustments do I need to make in my code in order to make hidden fields visible after clicking that radio button?
The website I'm working with is from the Dutch Tax authorities:
https://www.belastingdienst.nl/wps/wcm/connect/nl/auto-en-vervoer/content/hulpmiddel-motorrijtuigenbelasting-berekenen
This is my code.
Sub Show_Hidden_Field()
'Declaration section
Dim htmlDoc As New MSHTML.HTMLDocument
Dim objShell, objShellWindows, objShellWindow As Object
Dim htmlOption As MSHTML.IHTMLElement
'Wait an extra 3 seconds so you can switch to the IE window
'and see what's going on
Application.Wait Now + TimeValue("0:00:03")
'Find the correct Internet Explorer window
Set objShell = CreateObject("Shell.Application")
Set objShellWindows = objShell.Windows
For Each objShellWindow In objShellWindows
If objShellWindow.Name = "Internet Explorer" Then
'Find this window
If objShellWindow.LocationURL = "https://www.belastingdienst.nl/wps/wcm/connect/nl/auto-en-vervoer/content/hulpmiddel-motorrijtuigenbelasting-berekenen" Then
'This the correct page. Get the content of page
Set htmlDoc = objShellWindow.document
Exit For
End If
End If
Next objShellWindow
'Find the radio button . . .
Set htmlOption = htmlDoc.getElementById("V1-1_True")
'. . . and check it.
htmlOption.Checked = True
'**********************************************************************
'I've also tried these options without succes.
'htmlOption.Click
'htmlOption.FireEvent ("onchange")
'Or set the focus to another field
'**********************************************************************
End Sub
You have a couple issues with your code. The first one is that you are using the wrong type for your radio button element.
While htmlOption is technically a MSHTML.IHTMLElement, it more specifically should be of type: MSHTML.HTMLInputElement. So change your declaration to:
Dim htmlOption As MSHTML.HTMLInputElement
For your actual issue, you should just use .Click. Taking a look at developer.mozilla.org:
The HTMLElement.click() method simulates a mouse click on an element.
When click() is used with supported elements (such as an <input>), it fires the element's click event. This event then bubbles up to elements higher in the document tree (or event chain) and fires their click events. (emphasis added)
So, you wouldn't need to use .Checked = True, because upon clicking the input element, you will not only solve your problem with the hidden area being revealed, you are also simultaneously changing the value to True.
So you would just use this:
'Find the radio button . . .
Set htmlOption = htmlDoc.getElementById("V1-1_True")
'. . . and check it.
htmlOption.Click