VBA can't access nested span element in HTML - html

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

Related

Select HTML Menu Item via VBA

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

How to add elements revealed by click action to elements list in Excel VBA for an html web form

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.

How to click on a <a> element of an <li> of a <ul> using vba?

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".

VBA Excel Run time error 438 / getElementbyClassName

I'm a newbie, attempting to web scrape aspect ratio details from the imdb.com website.
I've plundered some code on You Tube and adapted it using inspect element.
The code opens imdb and runs a search by title but returns a Run Time error 438.
Ideally I'd like it to return the html of the top result so I could perform a further click the top result to follow through to the page with tech details from where I could get the aspect ratio information and paste it into a cell.
Unfortunately I get a fail from my Click instruction - haven't even got to the point of extracting the aspect ratio info.
Can anyone see where I've gone wrong?
Many thanks,
Nick
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Row = Range("Title").Row And Target.Column = Range("Title").Column Then
Dim ie As New InternetExplorer
ie.Visible = True
ie.navigate "https://www.imdb.com/find?ref_=nv_sr_fn&q=" & Range("Title").Value
Do
DoEvents
Loop Until ie.readyState = READYSTATE_COMPLETE
Dim doc As HTMLDocument
Set doc = ie.document
Dim sDD As String
doc.getElementsByTagName("a").Click
End If
End Sub
So, addressing your code
You can use a shorter version of Target.Address = Range("Title").Address
You don't want the first a tag element. You want the first search result a tag element.
You can use a CSS selector combination to get the first search result a tag element as shown below.
I use a CSS selector combination of .result_text a to target elements within parent class result_text with tag a. The . is a class selector.
This combination is known as a descendant selector.
Using search term in sheet of Red October this is what the CSS query first result is:
It is a relative link with base string https://www.imdb.com.
Applying via querySelector method means only first matched result is returned i.e. the top result.
VBA:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If Target.Address = Range("Title").Address Then
Dim ie As New InternetExplorer
ie.Visible = True
ie.navigate "https://www.imdb.com/find?ref_=nv_sr_fn&q=" & Range("Title").value
Do
DoEvents
Loop Until ie.readyState = READYSTATE_COMPLETE
Dim doc As HTMLDocument
Set doc = ie.document
doc.querySelector(".result_text a").Click
'other code
End If
Application.EnableEvents = True
End Sub
This line of code:
doc.getElementsByTagName("a")
gives you the Collection of Hyperlinks in your HTML Document. That is, it gives you ALL the elements that match your given criteria, if any are available.
However, some issues may arrive:
There may not be any hyperlinks available - So there are no elements to click on.
You are not referencing any element to click. If you want the first one in the collection of found items, you could go with the index, as suggested. Else, you might look for another clicking criteria (such as what is its text or another given attribute).
Even still, a found element might not be clickable by your browser, if, for example, it is shadowed by another element.

Clicking in IE using VBA

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.