How do I click a button on a webpage through VBA? - html

I am trying to use click a button through vba but it tells me that the "Object doesn't support this property or method".
My VBA code right now is:
IE.document.getElementByType("button").getelementByClass("qm_historyTab_GoButton").Click
The HTML for the button is:
<button class="qm_historyTab_GoButton" type="submit" style="font:normal 11px tahoma,arial,helvetica,sans serif;">
<span class="qm_historyTab_GoButtonText">GO</span>
</button>

Try this:
IE.document.getElementsByTagName("button") _
.getelementsByClassName("qm_historyTab_GoButton")(0).Click
Both of the getXXX methods return a collection of items (even if there's only one match in the document) so to address a single item from the last one in order to click it you need to add the (0)
EDIT: if the aim is to submit the form then this will also work
IE.document.getElementById("qm_historyForm_7871").submit
or as there's only one button with that classname:
IE.document.getElementsByClassName("qm_historyTab_GoButton")(0).Click

Ok so I found the solution in this specific instance. The button is a submit type and sends a message using HTMLInputElement.
What I needed to do was add "Microsoft HTML Object Library" to my references and utilize those features.
I had to create the variable that would send the response:
Dim htmlInput As MSHTML.HTMLInputElement
I couldn't figure out how to refer to this specific element individually so I grabbed everything with it's class name.
For Each htmlInput In IE.document.getElementsByClassName("qm_historyTab_GoButton")
If Trim(htmlInput.Type) = "submit" Then
htmlInput.Click
Exit For
End If
Next htmlInput
Then I had the program cycle through each item in the series and send a submit response. Since this was the only one with the class name, I got lucky.
So anyways, that's how I solved the problem.

Related

vb.net selenium select element from dropdown

I don't know much about selenium. I'm trying to select an element from a dropdown to click on it, but vb.net doesn't find this element. or it finds another element that has the same class name.
It is the following dropdown menu on aliexpress.
And this is the code I have written so far....
Dim chromeDService = ChromeDriverService.CreateDefaultService() 'hides command prompt
chromeDService.HideCommandPromptWindow = True
Dim opt As New ChromeOptions()
opt.AddArguments("headless") 'prevents driver from opening a new window
Dim driver As IWebDriver = New ChromeDriver(chromeDService, opt)
driver.Navigate.GoToUrl(URL_AS_STRING) 'the URL as String
driver.Manage.Timeouts().ImplicitWait = TimeSpan.FromSeconds(2)
If driver.FindElement(By.ClassName("switcher-info")).FindElement(By.ClassName("currency")).Text = "USD" Then
Console.WriteLine("changing currency...")
'driver.FindElement(By.LinkText("EUR")).Click()
driver.FindElement(By.ClassName("switcher-info")).Click()
driver.Manage.Timeouts().ImplicitWait = TimeSpan.FromSeconds(1)
Dim element As IWebElement = driver.FindElement(By.ClassName("switcher-common")).FindElement(By.ClassName("switcher-currency-c")).FindElement(By.ClassName("select-item"))
Console.WriteLine(element.GetAttribute("innerText"))
End If
My question now is, how can I select and click on the element with the currency?
I intend to click on it so that it selects another currency.
Of course I could also make everything less complicated and include an exchange API. But the real rates do not match with the prices
You can do it simply by clicking the corresponding elements one by one exactly what the real user does via the GUI.
I see Selenium in VBA doesn't have explicit waits, so only the implicitly wait can be used as you already defined it driver.Manage.Timeouts().ImplicitWait = TimeSpan.FromSeconds(2) and since it was defined we do not need to define it anymore until we want to define it for some other value.
This is what I wrote.
I hope this should work:
If driver.findElementByXPath("//a[#id='switcher-info']//span[#class='currency']").Text = "USD" Then
Console.WriteLine("changing currency...")
driver.findElementByXPath("//span[#class='currency']").Click()
driver.findElementByCssSelector(".switcher-currency .select-item").Click()
driver.findElementByXPath("//a[#data-currency='EUR']").Click()
driver.findElementByXPath("//button[#data-role="save"]").Click()
In case there are pop-ups appearing on the aliexpress home screen disturbing the above code run try do the following:
If driver.FindElementsByXPath("//div[contains(text(),'Don')]").Count Then
driver.FindElementsByXPath("//div[contains(text(),'Don')]").Click()
If driver.FindElementsByXPath("//img[#class='btn-close']").Count Then
driver.FindElementsByXPath("//img[#class='btn-close']").Click()
If driver.FindElementsByXPath("//img[#class='close-btn']").Count Then
driver.FindElementsByXPath("//img[#class='close-btn']").Click()
And only after that run the code above so that the whole code will be something like this:
If driver.FindElementsByXPath("//div[contains(text(),'Don')]").Count Then
driver.FindElementsByXPath("//div[contains(text(),'Don')]").Click()
If driver.FindElementsByXPath("//img[#class='btn-close']").Count Then
driver.FindElementsByXPath("//img[#class='btn-close']").Click()
If driver.FindElementsByXPath("//img[#class='close-btn']").Count Then
driver.FindElementsByXPath("//img[#class='close-btn']").Click()
If driver.findElementByXPath("//a[#id='switcher-info']//span[#class='currency']").Text = "USD" Then
Console.WriteLine("changing currency...")
driver.findElementByXPath("//span[#class='currency']").Click()
driver.findElementByCssSelector(".switcher-currency .select-item").Click()
driver.findElementByXPath("//a[#data-currency='EUR']").Click()
driver.findElementByXPath("//button[#data-role="save"]").Click()
You need to close all the popups before interacting with any element on the page. Try this:-
driver.findElementByXPath(".//div[contains(text(),'notifications')]//following::img").Click()
driver.findElementByXPath(".//img[#class='btn-close']").Click()
driver.findElementByXPath(".//a[#id='switcher-info']").Click()
driver.findElementByXPath(".//div[#data-role='switch-currency']").Click()
driver.findElementByXPath(".//li/a[#data-currency='EUR']").Click()
I think, that the ClassName-Selector ist not the right one.
It is not a real dropdown like <select> but a dropdown-menue of links.
the Link for US-Dollar looks like this:
<span class="select-item chang-border" data-spm-anchor-id="a2g0o.home.1000001.i0.650c2145pgspp2">
<a rel="nofollow" href="javascript:;" data-spm-anchor-id="a2g0o.home.1000001.40">USD ( US Dollar )</a>
</span>
You can use the FindElementByCssSelector to access this link:
driver.FindElementByCssSelector("[data-spm-anchor-id=a2g0o.home.1000001.40]").Click()
For EURO it is:
driver.FindElementByCssSelector("[data-spm-anchor-id=a2g0o.home.1000001.43]").Click()

How to Execute js of a webelement in Selenium

On a target Webpage, I have a HTML Button elements with following sub-tags (Excess HTML statements removed for brevity)
<a class="ebookreader" onclick="getBook2Read('12','Journey of India','Author-JN')">Read</a>
<a class="ebookreader" onclick="getBook2Read('32','Journey of Punjab','Author-JN')">Read</a>
<a class="ebookreader" onclick="getBook2Read('33','Journey of Haryana','Author-JN')">Read</a>
<a class="ebookreader" onclick="getBook2Read('38','Journey of Uttar Pradesh','Author-JN')">Read</a>
In my VB 2019 Code using Selenium Driver, I want to execute the js code related with onclick.
I have tried following statements, but in vain
For Each book In driver.FindElementsByClassName("ebookreader")
book.GetAttribute("onclick")
book.GetCssValue("onclick")
Next
But am not able to move ahead. I even tried creating filling a ListBox but the values added in the ListBox are shown as OpenQA.Selenium.Remote.RemoteWebElement or OpenQA.Selenium.Chrome.ChromeWebElement
Is there a way to invoke onclick js from Selenium?
Got it
For Each book In driver.FindElementsByClassName("ebookreader")
Dim onClickValue As String = book.GetAttribute("onclick")
If onClickValue <> "" Then
listBooks.Items.Add(onClickValue)
End If
Next
listBooks is the VB.Net forms ListBox Control

"Clicking" anchor element to navigate to next page VBA

I'm creating an automation that will go through almost 110 pages with VBA. These pages have identical layout. I would need to go from one page to another automatically by "clicking" next button. At the very end of every page, there is a "button" (list anchor) that says "Next page". Problem is that the source code does not contain ID which would make it easy to refer with:
getElementById("id").Click
I open browser. That works fine. and I've tried something like this but it doesn't work:
Dim ieDoc As Object
Dim links As Object
Dim link As Object
Set ieDoc = ieApp.Document
Set links = ieDoc.Anchors
For Each link In links
If link.innerHTML = "innerHTML" Then
link.Click
Exit For
End If
Next link
I have tried almost everything I could find from stackoverflow but nothing worked for my needs.
THis is the source code of the "Next button" that I'm trying to click:
<li class="pager-next"><a title="Next page" href="/fi/tyosuhde- edut/kayttokohdehakupage=1&service_type=lunch&keywords=&city=&service=&service_areas=&payment_method=&municipality=&service_coupon_code=&items_per_page=50">seuraava ›</a></li>
I quess the problem is that the ClassName is in "li" and not in "a"?
Could some help me??
EDIT
Found a workaround!!:
Set pages = doc.getElementsByTagName("a")
For Each page In pages
If (page.getAttribute("title") = "Siirry seuraavalle sivulle") Then
page.Click
End If
Next page
You will need to keep reseting the html document with each refresh.
After a refresh try
ieApp.document.querySelector("a[title=""Next page""]").Click
CSS Selector
More info about CSS Selectors: CSS selectors
EDIT:
In your case the actual HTML selector is
appIE.doc.querySelector("a[title = ""Siirry seuraavalle sivulle""]").Click
Note there is no space after the "a" and you will need to leave enough time between clicks to allow the new page to load.

VB WebBrowser click button

On this web page: https://www.youtube.com/upload_defaults
I would like to call a function and then click the "Save" button in the upper right corner.
There is no ID or Name. How can I do this?
You can use the distinct CSS class of the button: account-save-button
In VB.NET, use HtmlDocument.GetElementsByTagName like this:
Private Sub ClickSaveButton()
If (WebBrowser1.Document IsNot Nothing) Then
Dim Elems As HtmlElementCollection
Dim WebOC as WebBrowser = WebBrowser1
Elems = WebOC.Document.GetElementsByTagName("BUTTON")
For Each elem As HtmlElement In Elems
Dim CssClass As String = elem.GetAttribute("classname")
If ((CssClass IsNot Nothing) And (CssClass.Length <> 0)) Then
If CssClass.ToLower().Contains("account-save-button") Then
elem.InvokeMember("click");
Exit For
End If
End If
Next
End If
End Sub
To verify it with just a web browser, try this from your browser's developer console; it works because youtube uses jQuery:
$(".account-save-button").click();
Or pure javascript: document.getElementsByClassName('account-save-button')[0].click();
For reference, here is the button's markup:
<button class="yt-uix-button yt-uix-button-size-default yt-uix-button-primary account-save-button account-action-button" type="submit" onclick=";return true;"><span class="yt-uix-button-content">Save</span></button>
Other thoughts:
This is basically screen scraping, which can lead to brittle applications when the page changes, etc.
Google may already have a web service API for what you are trying to accomplish.. but that's a good question:
What exactly are you trying to accomplish? What is the context? We may be able to suggest a better alternate solution.
Update:
I checked the Youtube API Reference, but I don't see anything for setting preferences for upload defaults.

Clicking a button within an IE table

I am trying to click a button within a table on a webpage within IE, the source of the button shows:
<input type="image" src="img/testimg.png" onclick="picture_return(this,'92b84574a336a090618f151b6fc821cf:5','http://testwebpage.com/in/834');" value="Test Web Button">
This is a part of a large table with multiple <td> within the source, this is within another table which is then within the following class:
<div class="section_client_dnBox">
I tried to go through a few of the items within the class by using the following VBA code:
IE.Document.getElementsByClassName("section_client_dnBox")(0).Click
However, had no luck as (0) didn't press anything and anything larger ie, (1) gave me an error. So my question now is basically, is there any way of clicking the button using something simple such as reffering to it's value within the table (value="Test Web Button")?
From my experience, you need to look at the tag name rather than the class name. This is an example of the code I generally use when finding buttons.
For Each MyHTML_Element In document.getElementsByTagName("input")
If MyHTML_Element.Type = "submit" Then
MyHTML_Element.Click: Exit For
End If
Next
You might be able to change the . type to = "image". I too am just learning how to use IE automation in VBA so I am not a champ at it either. I hope that helps.
CSS selector:
It is far simpler to use a CSS selector of input[value='Test Web Button']. No loop required.
It says get element with input tag having attribute value having value = 'Test Web Button'. "[]" means attribute.
.querySelector method of document is how you apply the selector.
CSS query:
VBA:
ie.document.querySelector("input[value='Test Web Button']").Click