How to use getElementsBy without a specific ID - vba

I am new to programming with Microsoft Visual Basic and am trying to create a program that will put co-ordinates into an image database website.
I am trying to put numbers into a specific space on a website.
The place that I would like to input a number for right ascension, doesn't have a specific ID when I inspect it on the website, so I tried getElementsByTagName, however, this isn't working.
I also looked to find an ID of a larger section of the HTML code as specified here: How to access HTML element without ID?, however that isn't working either.
Sub MovesData()
Dim IE As Object
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.navigate "http://wsa.roe.ac.uk:8080/wsa/getImage_form.jsp? programmeID=&database=UKIDSSDR11PLUS&ra=&dec=&sys=J&filterID=all&xsize=1&ysize=1&obsType=object&frameType=stack&mfid=&fsid=&name="
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
IE.document.getElementsByTagName("ra").Value = "23"
End Sub
The HTML code for the specific line is:
<input type="text" name="ra" value="" size="15">
The section of HTML code is:
<td nowrap="" align="right"><b>RA</b> or <b>Galactic Long.:</b></td>
<td>
<input type="text" name="ra" value="" size="15">
<td><input type="text" name="ra" value="" size="15"></td>
I expect the output to be 23 in the right ascension box but it is just blank and there is a run time error 438 "Object doesn't support this property or method". Any help would be greatly appreciated!

Related

VBA IE Automation - cannot find "export" element ID

I'm working in Microsoft Excel 2010 VBA and I'm trying to automate pdf report downloads. I can navigate to where I need to be but I'm stuck on the last step;
There's an "Export" element that behaves like a link. If I were to click on it, it would initiate a pdf download. I want to automate this and direct the download to a specified folder, but when I inspect the element it doesn't appear to have an element ID by which I can call it (ie. getElementById().Click).
I'm new to VBA IE automation. Does anyone have suggestions on how to initiate that "Export" function?
I can't share the full HTML detail, as it is for a site with sensitive data, but below are snippets of the HTML, my VBA code, and a screenshot of the HTML section that is in question:
<DIV style="FONT-SIZE: 8pt; HEIGHT: 30px; FONT-FAMILY: Verdana; DISPLAY: inline"><TABLE style="DISPLAY: inline" cellSpacing=0 cellPadding=0>
<TBODY>
<TR>
<TD height=28><SELECT id=PrintFormat><OPTION value="">Select a format</OPTION><OPTION selected value=Pdf>Acrobat (PDF) file</OPTION></SELECT></TD>
<TD width=4></TD>
<TD height=28><A onclick="if (document.getElementById('PrintFormat').value != '') {var url = document.getElementById('PrintFormat').value + 'Stream.aspx'; document.location.href = url;}" style="FONT-SIZE: 8pt; TEXT-DECORATION: none; FONT-FAMILY: Verdana" href="#" shape="">Export</A></TD></TR></TBODY></TABLE></DIV>
My vba code;
Sub pdfdownloadautomation()
Set objIE = New InternetExplorer
objIE.Visible = True
objIE.navigate Sheet3.Range("A1").Value 'A1 contains url
objIE.document.getElementById("PrintFormat").Value = "Pdf"
'works fine to this point - just not sure how to call the export
objIE.document.getElementById("?").Click
End Sub
screenshot of inspected element in IE
You may try a CSS selector as follows to target the element. I can't test and don't know if there are parent frame/iframe/form tags to navigate. There appears to be one form element at least visible. Please provide the html including this form tag if possible. I have given variations without parent form and including parent form (which looks to be the case) - the assumption with the parent form element is that it is the first form element on the page.
ie.document.querySelector("td a[onclick^='if']").Click
Which might become:
ie.document.getElementsByTagName("form")(0).querySelector("td a[onclick^='if']").Click
The CSS selector is likely more complex than required but I am trying to localize using the visible cues in your image i.e. that there is an element with an a tag, that has onclick attribute starting with 'if', and is inside a parent td tag.
You could also gather all the a tag elements and loop until the Export innerText is found:
Dim list As Object, item As Object
Set list = ie.document.getElementsByTagName("a")
For Each item In list
If item.innerText = "Export" Then
item.Click
Exit For
End If
Next
Again, this may become
Set list = ie.document.getElementsByTagName("form")(0).getElementsByTagName("a")

Simulate Click event on a DIV element

I cannot simulate a click event on a div element. The HTML code is this one:
<div id="export" data-export="true" data-timespan="">
<button class="btn btn-default ladda-button" type="button" data-style="expand-right" data-spinner-color="#8899a6">
<span class="Icon Icon--featherDownload"></span>
<span class="ladda-label">
Exportar datos
</span>
<span class="ladda-spinner"></span></button>
<div class="hidden error server Callout Callout--danger">
<p>Ocurrió un problema al exportar tus datos, inténtalo de nuevo más tarde.</p>
</div>
</div>
In the webpage, is just a button that downloads a file when clicked. There is no URL. But after checking the code, is the div element what triggers the click event. Look the image.
Click to see image
That "g.handle" triggers a js.file form the website.
My vba code works perfect for doing other stuff in the website, but I cannot accomplish this task.
I've tried all this options:
Set div = HTMLDoc.getElementById("export")
div.FireEvent ("onclick")
div.Click
HTMLDoc.all.Item
Call HTMLDoc.parentWindow.execScript("g.handle", "JavaScript")
Nothing works. I'm kind of blocked right now and I have no idea of how to proceed. Maybe this has no solution? I have almost no idea of HTML and I have 0 idea of Javascript. But it must have a solution, because if I do it manually, i click on that DIV, wait some seconds and download my file.
Thanks in advance. Any help is welcome.
You didn't specify if the highlighted portion was the html code for the button or not, but it appears from looking at it that it isn't.
You can grab the class name for your button. The name may or may not be unique, and it's difficult to know that without seeing the entire html code, but you can set the btn variable below to the first instance of that class name. If there are multiple class names in your html code, then you will need to use a For Each...Next statement to iterate through them (unless you know the instance number off hand).
So we will go with the first instance of your class, hence the reason for the (0) appended on the end.
Sub Test()
Dim ie As New InternetExplorer, HTMLDoc As HTMLDocument, btn As Object
ie.navigate Url 'whatever this may be
' Some code to wait for your page to fully load
Set HTMLDoc = ie.document
Set btn = HTMLDoc.getElementsByClassName("btn btn-default ladda-button")(0)
btn.Click
End Sub

Trying to fill web form with VBA, can´t address element

I am trying to fill out a web form in IE with data from a workbook but I am having trouble addressing the text box since it seems to lack a name.
The site is behind a login so no link, sorry. But the element presents itself as
<input type="text" placeholder=" Søg på brugernavn, referencenummer, eller e-mail" ng-model="filterSearch.search" ng-change="filterOnSearch()" ng-model-options="{ debounce: 500 }" class="ng-pristine ng-valid ng-empty ng-touched">
when inspecting it in chrome.
I have tried
ie.document.getelementsbyclassname("ng-pristine ng-valid ng-empty ng-touched").Value = "11"
but VBA throws me a run-time error '438': Object doesn't support this property or method.
Any suggestions?
It may sound confusing but anytime you are trying to pull an element by classname you need to use the
.item(0)
after that you would use something similar to
ie.document.getelementsbyclassname("ng-pristine ng-valid ng-empty ng-touched").item(0).Value = "11"
This is assuming that you are trying to fill out an input box that has the class above and that the element is the only 1 in its class or the first one.
In the event that it does not work it may not be the first element in that class and then you may need to do item(1) or item(2) etc.

instead of xpath what can i select from the below code

Please help me to find locator in this case as id is dynamic and it changes every time when I refresh the page.
type="text" also I will not be able to use because, for the next fields, eveything is same from the down code except, the label changes from the "first name" to the "last name" and so on.
So I should be selecting something in terms of the first name which is mentioned in the label tag below.
Please anyone can help me in this case.
<input class="md-input-element ng-valid ng-dirty ng-touched" id="md-
input-4-input" spellcheck="false" type="text">
<!--template bindings={}-->
<label class="md-input-placeholder md-float md-empty" for="md-input-
4-input">First name * <!--template bindings={}--></label>
You can use preceding-sibling or following-sibling feature from xpath. As per code mentioned above your xpath should be like this:
//input[#type='text'][following-sibling::label[contains(text(),'First name')]]
But I think in html label should be first then input, if that is case please try below one:
//input[#type='text'][preceding-sibling::label[contains(text(),'First name')]]
you can get the css selector from the class (can't do by className if it has spaces in the class name so use css, put a "." at the beginning and replace any spaces with a ".")
#FindBy(css = ".md-input-element.ng-valid.ng-dirty.ng-touched")
private WebElement elementMDInputTouched;
#FindBy(css = ".md-input-placeholder.md-float.md-empty")
private WebElement elementMDInputEmpty;

IE Automation - Excel VBA

I am trying to do IE Automation through Excel VBA code.
I have a web page which has Top, Middle and results forms. I need to input values in the Middle form but unable to get any controls from this and get it as 0. Ie.Document.forms.Length gives 0. Tried the below code as well but does not work.
Ie.Document.forms("SearchForm").elements("PolicyNumber").Value = "Josh"
Looks like this form is on a frame but don't see frame reference inthe HTML code. HTML code is as below:
<body bgcolor="white">
<form method=POST name="SearchForm" action="PolicySearch" target="resultframe" >
<input type=hidden name="NewSearch" value="True" ></input>
<table class=box2 cellpadding="1" cellspacing="0" border="0" width="760" align="top" halign="left">
<tr>
<td class="name" align="left">
Policy# :<input type=text name="PolicyNumber" maxlength="10" value="" size="10"></input>
</td>
try thing as
Ie.Document.getElementsByName("PolicyNumber").Item(0).Value="Josh"
or
Iie.Document.getElementsByName("PolicyNumber").Value="Josh"
Try this:
declare a new variable:
Dim Elements As IHTMLElementCollection
Set the elements with the form and tag name, eg. input
Set Elements = IE.Document.forms("SearchForm").Document.getElementsByTagName("input")
Pass the value to the text / input
Elements("PolicyNumber").Value = "Josh"
Note: the code above is originally for frames and need to add MS HTML Objects library in the references. Though you can use Elements by declaring as object, declaring as IHTMLElementCollection will have events when you press "."