VBA to click a webpage button - vba

I would like to click a webpage button using VBA. I tried several options (please see the code below) but none of them seems work. If instead of click I use focus, it selects the button that I want to push, however the click command is not working. What other methods can I try?
Sub SubmitInfo()
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.navigate "http://www.ecotransit.org/calculation.en.html"
Do While IE.readyState <> 4: DoEvents: Loop
Application.Wait (Now + TimeValue("0:00:02"))
' 1st option
IE.document.getElementById("calculationBT").Click
' 2nd option
IE.document.getElementsByClassName("formGreenButton")(0).Click
' 3rd option
Set htmlColl = IE.document.getElementsByTagName("input")
Do While IE.document.readyState <> "complete": DoEvents: Loop
For Each htmlInput In htmlColl
If Trim(htmlInput.Type) = "submit" Then
htmlInput.Click
Exit For
End If
Next htmlInput
' 4th option
Set htmlColl = IE.document.getElementsByTagName("input")
Do While IE.document.readyState <> "complete": DoEvents: Loop
For Each htmlInput In htmlColl
If Trim(htmlInput.Value) = "CALCULATE" Then
htmlInput.Click
Exit For
End If
Next htmlInput
End Sub
Below is the button HTML code that I want to click
<input id="calculationBT" type="submit" class="formGreenButton" value="CALCULATE" />

IE.document.getElementById("calculationBT").Click
should do the job but you must be sure that there is only one occurence of the id, which should be in this case.

Related

VBA Web Scraping: macro stops when I run it but not in debugging mode

I have tried few thing like waiting for 1 to 10 seconds before the linecode with issue "Html.querySelector("a[href='#tab-import']").Click" where it stops or adding a "loop" until the page charges but I dont know why it only works in debugging mode.
HTML source:
Import
The error is 91: Object variable not set.
My code with cemented credentials
Sub Direnet()
Dim ieApp As InternetExplorer
'create a new instance of ie
Set ieApp = New InternetExplorer
'you don’t need this, but it’s good for debugging
ieApp.Visible = True
'go to the page we want
ieApp.Navigate "http://direnetdemos.com/casagarza-op/admin/index.php?route=tool/export_import&token=9reP7LOHg0SMChCYFBbcLPoQSjiQ72W1"
Do While ieApp.Busy: DoEvents: Loop
Do Until ieApp.ReadyState = READYSTATE_COMPLETE: DoEvents: Loop
With ieApp
.document.all.Item("input-username").Value = "xxxx"
.document.all.Item("input-password").Value = "xxxx"
.document.forms(0).submit
Do While ieApp.Busy: DoEvents: Loop
Do Until ieApp.ReadyState = READYSTATE_COMPLETE: DoEvents: Loop
'Click en pestaña Import
Dim Html As HTMLDocument
Set Html = ieApp.document
Application.Wait (Now + TimeValue("0:00:02"))
Html.querySelector("a[href='#tab-import']").Click
Html.querySelectorAll("input[name='incremental']")(1).Click
Html.querySelector("input[id='upload']").Click
Html.querySelector("a[onclick='uploadData();']").Click
End With
End Sub
Every time you click something you should wait for the browser to be "ready" again:
Html.querySelector("a[href='#tab-import']").Click
Do
DoEvents
Loop Until Not ieApp.Busy And ieApp.ReadyState = READYSTATE_COMPLETE
Html.querySelectorAll("input[name='incremental']")(1).Click
Do
DoEvents
Loop Until Not ieApp.Busy And ieApp.ReadyState = READYSTATE_COMPLETE
Html.querySelector("input[id='upload']").Click
Do
DoEvents
Loop Until Not ieApp.Busy And ieApp.ReadyState = READYSTATE_COMPLETE
Html.querySelector("a[onclick='uploadData();']").Click
Do
DoEvents
Loop Until Not ieApp.Busy And ieApp.ReadyState = READYSTATE_COMPLETE
Also, don't use Application.Wait for this kind of thing - it literally just freezes code execution for a given time. It doesn't allow events to process or have any kind of link to the broswer's ready state.
Well it finally worked moving this linecode "IE.Visible = True" a few lines after. Thank you very much for all.

Automate clicking buttons on one page and then another page using vba

I am trying to work on something that clicks a button\line on a page, then clicks on others when the new page loads. I can get my vba to click the first button/link, but then when trying to click the next I am getting the error
Run-time error 91: Object variable or With block variable not set
Now I have to be honest, the code I do have is from research, and by no means do I understand it fully, I have searched all over trying to rectify the 2nd click, but nothing seems to be working.
the code I have so far is
Public Sub SHAREREPORTING()
Dim IE As SHDocVw.InternetExplorer
Dim Button As Object
Dim Button2 As Object
Set IE = New InternetExplorerMedium
IE.Visible = True
IE.navigate "URL"
Do While IE.ReadyState <> READYSTATE_COMPLETE Or IE.Busy: DoEvents: Loop
Set Button = IE.Document.getElementById("b1_pki")
Button.Click
Application.Wait (Now + TimeValue("0:00:05"))
SendKeys "mypassword" , True
SendKeys "{ENTER}", True
Do While IE.ReadyState <> READYSTATE_COMPLETE Or IE.Busy: DoEvents: Loop
Set Button2 = IE.Document.getElementById("seite-itm-2")
Application.Wait (Now + TimeValue("0:00:05"))
Button2.Click
End Sub
the code for the 2 buttons ( I am calling them buttons/links, because I'm not too sure what they are, I don't understand javascript) I am trying to click at the moment is
Button1/Link1
<A onclick=loginViaPKI(); onkeypress=loginViaPKI(); id=b1_pki title="Log on with PKI - Button - To activate, press spacebar." class=urBtnEmph hideFocus style="WHITE-SPACE: nowrap" href="javascript:void(0);" ct="Button">Log on with PKI</A>
Button2/Link2
<TD onclick="return htmlbSL(this,7,'seite:sel_tab_2','','3','sel_tab_2')" id=seite-itm-2 class=urTbsLabelOff onkeydown="if (sapUrMapi_checkKey(event,'keydown',new Array('32'))){return htmlbSL(this,7,'seite:sel_tab_2','','3','sel_tab_2')};sapUrMapi_TabStrip_keySelect('seite',2,4,event);" noWrap><SPAN id=seite-itm-2-txt title="Bookmarks " class=urTbsTxtOff>Bookmarks </SPAN></TD>
The program requires references to the following:
1 Microsoft Internet Controls
2. Microsoft HTML Object Library
The Internet control is used to browse the webpage and the HTML Objects are used to identify the username and password textboxes and submit the text using the control button.
Dim HTMLDoc As HTMLDocument
Dim oBrowser As InternetExplorer
Sub Login_2_Website()
Dim oHTML_Element As IHTMLElement
Dim sURL As String
On Error GoTo Err_Clear
sURL = "https://www.google.com/accounts/Login"
Set oBrowser = New InternetExplorer
oBrowser.Silent = True
oBrowser.timeout = 60
oBrowser.navigate sURL
oBrowser.Visible = True
Do
' Wait till the Browser is loaded
Loop Until oBrowser.readyState = READYSTATE_COMPLETE
Set HTMLDoc = oBrowser.Document
HTMLDoc.all.Email.Value = "sample#vbadud.com"
HTMLDoc.all.passwd.Value = "*****"
For Each oHTML_Element In HTMLDoc.getElementsByTagName("input")
If oHTML_Element.Type = "submit" Then oHTML_Element.Click: Exit For
Next
' oBrowser.Refresh ' Refresh If Needed
Err_Clear:
If Err <> 0 Then
Debug.Assert Err = 0
Err.Clear
Resume Next
End If
End Sub

Query Web Table on Current Website

I am running into a bit of a problem. Normally when I pull a table I use the "data from web" tool in excel, however I now have quite a few places I need to pull data that first require me to enter a username and password. I figured out some code for that (though probably not the most elegant) but realized that once I get to my desired page I have no idea how to extract the table. Here is what I have so far.
Sub Login()
Sheets("IOL").Select
Set ie = CreateObject("InternetExplorer.application")
ie.Visible = True
ie.Navigate ("https://internalsite.company.com/secure/login" & ActiveCell)
Do
If ie.ReadyState = 4 Then
ie.Visible = True
Exit Do
Else
DoEvents
End If
Loop
ie.Document.forms(0).all("badgeBarcodeId").Value = "00000"
ie.Document.forms(0).submit
'used because it redirects to a new page after submitting and I couldn't figure out how to make it wait for the new page to load before proceeding.
Application.Wait (Now + TimeValue("0:00:02"))
ie.Document.forms(0).all("password").Value = "00000"
ie.Document.forms(0).submit
End Sub
After the login is accomplished I would like to go to http://internalsite.company.com/csv and import the csv directly into a sheet. Anytime I make a new connection it makes me log in again so I figure there has to be a way to extract the file without adding a new connection. I'm pretty new with more complex VBA so bear with me.
I was able to get this code to do the job, but it is more preferable to get the CSV directly instead of the table. Sometimes the table doesn't like to load.
Sub Login()
Dim clip As DataObject
Dim ieTable As Object
Set ie = CreateObject("InternetExplorer.application")
ie.Visible = True
ie.Navigate ("https://internalsite1.company.com/secure/login" & ActiveCell)
Do
If ie.ReadyState = 4 Then
ie.Visible = True
Exit Do
Else
DoEvents
End If
Loop
ie.Document.forms(0).all("badgeBarcodeId").Value = "00000"
ie.Document.forms(0).submit
Do While ie.Busy: DoEvents: Loop
Do Until ie.ReadyState = 4: DoEvents: Loop
ie.Document.forms(0).all("password").Value = "000000"
ie.Document.forms(0).submit
Do While ie.Busy: DoEvents: Loop
Do Until ie.ReadyState = 4: DoEvents: Loop
ie.Navigate "http://internalsite2.company.com/site/Inbound?filter=1To3Days"
Do While ie.Busy: DoEvents: Loop
Do Until ie.ReadyState = 4: DoEvents: Loop
Set ieTable = ie.Document.all.Item("DataTables_Table_0")
If Not ieTable Is Nothing Then
Set clip = New DataObject
clip.SetText "" & ieTable.outerHTML & ""
clip.PutInClipboard
Workbooks("Production Meeting Dashboard.xlsm").Activate
Sheets("IOL").Select
Range("A1").Select
ActiveSheet.PasteSpecial Format:="Unicode Text", link:=False, _
DisplayAsIcon:=False, NoHTMLFormatting:=True
End If
End Sub

Log-in to Website

I'm trying to create an Excel macro that will log me into this website. I've written macros to log me into to other websites, but this one is somehow different.
When I use the following code to programmatically insert the username and password and then programmatically click the "log-in" button, the webpage comes back with the message
Error: please provide a username and Error: Please provide a
password
Sub LogIn()
' Open IE and navigate to the log-in page
Set ie = CreateObject("InternetExplorer.Application")
With ie
.Visible = True
.navigate "https://www.prudential.com/login"
' Loop until the page is fully loaded
Do Until Not ie.Busy And ie.ReadyState = 4
DoEvents
Loop
Application.Wait (Now + TimeValue("0:00:10"))
' Enter the necessary information on the Login web page and click the submit button
ie.document.getElementById("username").Value = "abcdef"
ie.document.getElementById("password").Value = "12345678"
ie.document.getElementsByClassName("btn btn-primary btn-login btn-sm-block analytics-login")(0).Click
' Loop until the page is fully loaded
Do Until Not ie.Busy And ie.ReadyState = 4
DoEvents
Loop
End With
' Do stuff
' Quit IE
ie.Quit
End Sub
I can see that my code has inserted the username and password into the webpage boxes, but for some reason after successfully clicking the submit button, the username and password are not being detected.
What code will successfully insert the username and password so that it can be processed by the web page? You'll know that your code works when you get the following error message:
We are unable to verify your username and password. Please try again.
Thanks for your help!
It actually wants you to send a key, so you can bypass this request like this:
ie.document.getElementById("username").Focus
ie.document.getElementById("username").Value = "abcde"
Application.SendKeys "f", True
ie.document.getElementById("password").Focus
ie.document.getElementById("password").Value = "1234567"
Application.SendKeys "8", True
ie.document.getElementsByClassName("btn btn-primary btn-login btn-sm-block analytics-login")(0).Click
Edit:
Sub GetData()
Dim ie As InternetExplorer
Dim desc As IHTMLElement
Set ie = New InternetExplorer
With ie
.navigate "https://www.prudential.com/login"
.Visible = True
End With
Do While (ie.Busy Or ie.ReadyState <> READYSTATE_COMPLETE)
DoEvents
Loop
ie.document.getElementById("username").Focus
Application.SendKeys "abcdef"
Application.Wait (Now + TimeValue("0:00:01"))
ie.document.getElementById("password").Focus
Application.SendKeys "12345678"
Application.Wait (Now + TimeValue("0:00:01"))
ie.document.getElementsByClassName("btn btn-primary btn-login btn-sm-block analytics-login")(0).Click
Set ie = Nothing
End Sub
Try the code below:
Option Explicit
Const READYSTATE_COMPLETE As Long = 4
Const URL_String As String = "https://www.prudential.com/login"
Sub Login()
Dim IE As Object
Dim ObjElement As Object
' using Late Binding
Set IE = CreateObject("InternetExplorer.Application")
With IE
.navigate URL_String
.Visible = True
End With
Do While (IE.Busy Or IE.ReadyState <> READYSTATE_COMPLETE)
DoEvents
Loop
IE.document.getElementByid("username").Value = "abcdef"
IE.document.getElementByid("password").Value = "12345678"
' Optional: I didn't need the wait time
Application.Wait (Now + TimeValue("0:00:01"))
Set ObjElement = IE.document.getElementsByClassName("btn btn-primary btn-login btn-sm-block analytics-login")
ObjElement(0).Click
Set IE = Nothing
End Sub
Another approach might be something like the following.
Sub Get_Logged_In()
Dim IE As New InternetExplorer, HTML As HTMLDocument
Dim post As Object, elem As Object
With IE
.Visible = True
.navigate "https://www.prudential.com/login"
While .Busy = True Or .readyState < 4: DoEvents: Wend
Set HTML = .document
End With
With HTML
Set post = .querySelector("#username")
post.Focus
post.innerText = "abcdef"
Set elem = .querySelector("#password")
elem.Focus
elem.innerText = "12345678"
.querySelector("button[data-qa='Login Button']").Click
End With
IE.Quit
End Sub
Reference to add to the library:
1. Microsoft Internet Controls
2. Microsoft HTML Object Library
In case anyone else has a similar problem I was finally able to get Sendkeys to work. Still, if anyone can come up with a non-Sendkeys solution it would be much preferred.
Two important points in getting Sendkeys to work are 1) use of
Set WSS = CreateObject("WScript.Shell")
and 2) to be sure to run the macro from Excel (e.g. tools-macro-macros) and not from the VB Editor (running from the editor will simply insert the text somewhere within the code and not on the target webpage).
' Open IE and navigate to the log-in page
Application.StatusBar = "Opening IE and logging in to the website"
Set WSS = CreateObject("WScript.Shell")
my_username = "abcdef"
my_pw = "12345678"
Set ie = CreateObject("InternetExplorer.Application")
With ie
.Visible = True
.navigate "https://www.prudential.com/login"
.Top = 0
.Left = 0
.Height = 1025
.Width = 1925
' Loop until the page is fully loaded
Do Until Not ie.Busy And ie.ReadyState = 4
DoEvents
Loop
Application.Wait (Now + TimeValue("0:00:10"))
WSS.SendKeys "{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}"
Application.Wait (Now + TimeValue("0:00:01"))
WSS.SendKeys my_username
Application.Wait (Now + TimeValue("0:00:01"))
WSS.SendKeys "{TAB}"
Application.Wait (Now + TimeValue("0:00:01"))
WSS.SendKeys my_pw
Application.Wait (Now + TimeValue("0:00:01")
ie.document.getElementsByClassName("btn btn-primary btn-login btn-sm-block analytics-login")(0).Click
' Loop until the page is fully loaded
Do Until Not ie.Busy And ie.ReadyState = 4
DoEvents
Loop
End With
' You're now logged in, do your stuff..

VBA Click Link in IE Ajax PopUp

I'm trying to automate the process of downloading a CSV from a web site.
I've managed to write the code to:
Log in to the site
Navigate to the correct page
Click the link to make the download accessible.
From there, my problem begins. Upon clicking the link, the site does a series of Ajax calls and displays a div with a link to download the file that has a unique name each time. I can get the box to pop up, but I cannot get the VBA to click the link after it becomes available. Can anybody help with getting VBA to click the link in the box that is displayed after the ajax call?
Sub GetTableData()
Dim ieApp As InternetExplorer
Dim ieDoc As Object
Set ieApp = New InternetExplorer
ieApp.Visible = True
ieApp.Navigate "https://www.thesite.com/Login.aspx"
Do While ieApp.Busy: DoEvents: Loop
Do Until ieApp.ReadyState = READYSTATE_COMPLETE: DoEvents: Loop
Set ieDoc = ieApp.Document
On Error GoTo downloadPage
testPage = ieDoc.getElementById("file_box_link_id")
With ieDoc
.getElementById("EMail").Value = "me#web.com"
.getElementById("Password").Value = "pass"
.getElementById("Submit").Click
End With
Do While ieApp.Busy: DoEvents: Loop
Do Until ieApp.ReadyState = READYSTATE_COMPLETE: DoEvents: Loop
ieApp.Navigate "https://www.thesite.com/Menu.aspx"
Do While ieApp.Busy: DoEvents: Loop
Do Until ieApp.ReadyState = READYSTATE_COMPLETE: DoEvents: Loop
downloadPage:
ieDoc.getElementById("download_link").Click
Do While ieApp.Busy: DoEvents: Loop
Do Until ieApp.ReadyState = READYSTATE_COMPLETE: DoEvents: Loop
' THIS IS WHERE THE PROBLEM COMES...THIS HTML IS ADDED AFTER THE AJAX CALL
dlLink = ieDoc.getElementById("download_link")
Debug.Print dlLink.href
ieApp.Quit
Set ieApp = Nothing
End Sub
I'm not sure if you can get any data from the pop-up, but if you can, try to use getElementsByTagName method and the outerText property.
For Each Link In ieDoc.getElementsByTagName("a") Do
If Link.outerText = "The link text" Then
Link.Click
Exit For
End If
Next
You can find more information here
Hope it help!
Best regards,
Luiz Fernando