How do I get around breaking InternetExplorer Object with Application.SendKeys - vba

I thought I was well on my way to success. What I'm attempting to do is Load a URL in IE, input some data, then run a report.
To accomplish this, I've created an InternetExplorer object, used that object to turn on visibility, and navigate to my URL.
Upon getting to the page, I have to supply some data to let the report generator do what it needs to do, then press enter. Once I'm to this point I need to do some navigation to different URLs until I arrive at the report page. To accomplish this, I'm attempting to return to using my InternetExplore object (IE) to navigate, but any time I use IE.anything the 462 error pops.
My question is two fold:
The object was good to begin with, I have to assume it was the use of Application.Send or Application.Wait that has somehow broke my object, why?
What did I do wrong?
Suggestions on how to resolve this?
Dim text As String
Dim IE
Set IE = CreateObject("InternetExplorer.Application")
'
IE.Visible = True
IE.Navigate "http://~~~~~~~~~.net/reports/views/result/reportResult.faces"
'
text = "somedata"
.
Application.Wait (Now + TimeValue("00:00:02"))
Application.SendKeys (text), True
'
Application.Wait (Now + TimeValue("00:00:02"))
Application.SendKeys vbCrLf, True
'
Application.Wait (Now + TimeValue("00:00:02"))
IE.Navigate "http://~~~~~~~~~.net/reports/views/myMrs/myFavorites.faces"

The end product was completely different than where I was headed. Thanks to those who provided input, especially Sorceri who turned me on to focusing on the elements.
Below is the finished code segment (I have more things I do after this but this gets me where I needed to go).
Private Sub OpenReport()
Dim text As String
Dim x As Integer
Dim IE
Set IE = New InternetExplorerMedium
text = "somecode"
'Load link
IE.Visible = True
IE.Navigate "http://~~~~~~~~~/reports/views/result/reportResult.faces"
'Wait for page to load
Do While IE.Busy Or IE.ReadyState <> 4
DoEvents
Loop
'fill in the pcode
IE.Document.getelementbyid("code").Value = text
'Click Submit
IE.Document.getElementsByClassName("btn btn-lg btn-primary btn-block")(0).Click
'Wait for page to load
Do While IE.Busy Or IE.ReadyState <> 4
DoEvents
Loop
'Click on Favorites
IE.Document.getElementsByClassName("myMRSFavoritesLink")(0).Click
'Wait for page to load
Do While IE.Busy Or IE.ReadyState <> 4
DoEvents
Loop
'Click on report
IE.Document.getElementsByName("myFavoritesForm:treeTable_tableId:1:infoButton101644806j_id__v_19")(0).Click
'Wait for page to load
Do While IE.Busy Or IE.ReadyState <> 4
DoEvents
Loop
Click on execute report
IE.Document.getElementsByName("setParametersForm:startReportButton")(0).Click
End Sub

Related

VBA - Logging into Website - Login Button

Good afternoon all,
Please forgive me, I am new to VBA and have been practicing within my workbooks but for my work would be highly useful to branch out to Webscraping.
The following is my code.
Sub pullsalesdatafromonline()
Dim IE As Object
Dim doc As HTMLDocument
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.navigate "https://www.peoplestuffuk.com/WFMMCDPRD/Login.jsp"
Do While IE.Busy Or IE.readyState <> 4
Application.Wait DateAdd("s", 1, Now)
Loop
Set doc = IE.document
doc.getElementById("txtUserID").Click
doc.getElementById("txtUserID").Value = Usernameinserted
doc.getElementById("txtPassword").Click
doc.getElementById("txtPassword").Value = PasswordInserted
doc.getElementById("Login").Click
IE.navigate "https://www.peoplestuffuk.com/WFMMCDPRD/LoginSubmit.jsp"
IE.navigate "https://www.peoplestuffuk.com/WFMMCDPRD/ModuleSelection.jsp"
IE.navigate "https://www.peoplestuffuk.com/WFMMCDPRD/dashboard/main/dashboardmain.jsp"
IE.navigate "https://www.peoplestuffuk.com/WFMMCDPRD/rrd/matrixReport.jsp?fromPM=N"
End Sub
Here is the element that I am trying to scrape from;
<INPUT onclick=javaScript:submitForm() class=button-t type=button value=Login>
<SPAN id=Login_span class=buttonbox></SPAN>
I've looked at several other links that have looked into firing the .onclick event but, can't quite seem to figure it out.
The error in VBA highlights the:
IE.navigate "https://www.peoplestuffuk.com/WFMMCDPRD/ModuleSelection.jsp"
line. When my username and password enter, the page refreshes/ tries to exectute and then empties the Login and password info and leaves me on the Login page.
Would greatly appreciate someone's input.
Thank you
If you had a demo username and password to share then there was an efficient way of logging in using xhr. However, as for your current attempt concern, they are not the ids you used them within .getElementById(). Given that the following approach should log you in. Make sure to uncomment the delay, if the script fails to do the doing.
Sub pullsalesdatafromonline()
Dim IE As Object, doc As HTMLDocument
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.navigate "https://www.peoplestuffuk.com/WFMMCDPRD/Login.jsp"
While IE.Busy Or IE.readyState < 4: DoEvents: Wend
Application.Wait Now + TimeValue("00:00:03")
Set doc = IE.document
doc.querySelector("[name='txtUserID']").innerText = "username"
doc.querySelector("[name='txtPassword']").innerText = "password"
' Application.Wait Now + TimeValue("00:00:03")
doc.querySelector("input[value='Login']").Click
End Sub

VBA Macro for Internet Explorer - code run well on debugging 1 by 1 command but didn't work if i run the whole program

I'm new with VBA Macro using for automate the internet explorer.
I've used it for creating bot to follow other online shopping follower (e-commerce).
Actually the code run well if I use debug 1 by 1 command, and it worked (can do the follow thing).
But if I run the whole program, the code just operate maybe several command & stopped (but it didn't error).
I used it for e-commerce (sho.ee).
The step is:
open IE for other shop's followers
grab all the link
open the new link in new IE
follow them, close the new IE
and looping.
If I run step by step it worked.
Hope you guys could help me which wrong with the code.
Here's the code => i changed the name of the shop by xxx
Sub Followers()
Dim objIE As InternetExplorer
Dim ieAnchors As Object
Dim Anchor As Object
Set objIE = New InternetExplorer
objIE.Visible = True
objIE.Navigate "https://shopee.co.id/shop/xxx/followers/"
Do While objIE.Busy = True Or objIE.ReadyState <> 4: DoEvents: Loop
Set ieAnchors = objIE.Document.getElementsByClassName("shop-href")
For Each Anchor In ieAnchors
result = Anchor
If result <> result_prev Then
Dim objIE_1 As InternetExplorer
Dim ieBtn As Object
Dim Btn As Object
Set objIE_1 = New InternetExplorer
objIE_1.Visible = True
objIE_1.Navigate Anchor
Do While objIE_1.Busy = True Or objIE_1.ReadyState <> 4: DoEvents: Loop
Set ieBtn = objIE_1.Document.getElementsByClassName("shopee-button-outline shopee-button-outline--complement shopee-button-outline--fill ")
For Each Btn In ieBtn
Btn.Click
Next Btn
objIE_1.Quit
result_prev = Anchor
End If
Next Anchor
End Sub
Sometimes pages load in parts, registering as complete before all elements have loaded. In these cases I use application.Wait to force the program to wait a set amount of time for page loads:
'wait five seconds
Application.Wait (Now + TimeValue("0:00:05"))
If it is a simple page, I will have a Do loop a check for ReadyState to avoid slowing the program down unnecessarily:
'wait for page to load
Do Until ie.ReadyState = READYSTATE_COMPLETE or ie.ReadyState = 4
DoEvents
Loop
yes it worked. by adding Application.Wait (Now + TimeValue("0:00:05"))
Sub Followers()
Dim objIE As InternetExplorer
Dim ieAnchors As Object
Dim Anchor As Object
Set objIE = New InternetExplorer
objIE.Visible = True
objIE.Navigate "https://shopee.co.id/shop/xxx/followers/"
Do While objIE.Busy = True Or objIE.ReadyState <> 4: DoEvents: Loop
Application.Wait (Now + TimeValue("0:00:02"))
Set ieAnchors = objIE.Document.getElementsByClassName("shop-href")
For Each Anchor In ieAnchors
result = Anchor
If result <> result_prev Then
Dim objIE_1 As InternetExplorer
Dim ieBtn As Object
Dim Btn As Object
Application.Wait (Now + TimeValue("0:00:02"))
Set objIE_1 = New InternetExplorer
objIE_1.Visible = True
objIE_1.Navigate Anchor
Do While objIE_1.Busy = True Or objIE_1.ReadyState <> 4: DoEvents: Loop
Set ieBtn = objIE_1.Document.getElementsByClassName("shopee-button-outline shopee-button-outline--complement shopee-button-outline--fill ")
For Each Btn In ieBtn
Btn.Click
Next Btn
objIE_1.Quit
result_prev = Anchor
End If
Next Anchor
End Sub

Capturing the IE windows using For Each window shell application

I need to capture the windows and need to navigate further, I am able to capture using the below code,
With objIE
Application.Wait (Now + TimeValue("00:00:05"))
Set TBL = .document.getElementById("payersitecredential-table")
Set PRV = TBL.getElementsByTagName("A"): PRV.Item(1).Click
'once the above code runs, it opens up an another window and i need to set that window as object.
Application.Wait (Now + TimeValue("00:00:20"))
End With
For Each WINDW In CreateObject("Shell.Application").Windows
If WINDW.Name = "Internet Explorer" Then
If InStr(WINDW.LocationURL, "newmmis") <> 0 Then
Set objIE1 = WINDW
Exit For
ElseIf InStr(WINDW.LocationURL, "https://www.example.com") <> 0 Then
Set ClsWindw = WINDW
ClsWindw.Quit
GoTo ThEnD
End If
End If
Next
With objIE1
Do While .Busy Or .readyState <> 4 'this is the place i get error as object required
DoEvents
Loop
Application.Wait (Now + TimeValue("00:00:05"))
.document.getElementById("InquireStatus").Click
End With
i have kept a wait time of 60 seconds for the URL to load, but sometimes the URL takes much time to load, at that time it is unable to set the object, could you guys let me figure out this and give me a solution.
Please see this in support of my comment
Sub ex()
Dim ie As SHDocVw.InternetExplorer
Dim wins As New SHDocVw.ShellWindows
For Each ie In wins
Debug.Print ie.Document.URL, ie.ReadyState, ie.Busy
Next ie
End Sub
EDIT
I would utilise the above, like so, this will find the IE based on URL and wait until it's ready and return, so use set IE=GetMeReadyIE("http://stackoverflow.com/questions/tagged/vba") for example.
Function GetMeReadyIE(strURL As String) As SHDocVw.InternetExplorer
Dim ie As SHDocVw.InternetExplorer
Dim wins As New SHDocVw.ShellWindows
For Each ie In wins
If ie.Document.URL = strURL Then
While ie.ReadyState <> READYSTATE_COMPLETE Or ie.Busy
DoEvents
Wend
Set GetMeReadyIE = ie
Exit For
End If
Next ie
End Function

How to pause Excel VBA and wait for user interaction before loop

I have a VERY basic script I am using with an excel spreadsheet to populate a form. It inserts data into the fields then waits for me to click the submit button on each page. Then it waits for the page to load and fills in the next set of fields. I click submit, next page loads, etc. Finally, on the last two pages I have to do some manual input that I can't do with the spreadsheet. Code thus far is shown below.
My question is, at the end of what I have there now, how can I make the system wait for me to fill out that last page, then once I submit it realize that it has been submitted and loop back to the beginning, incrementing the row on the spreadsheet so that we can start over and do the whole thing again for the next student?
As you will probably be able to tell I am not a programmer, just a music teacher who does not savor the idea of filling out these forms manually for all 200 of my students and got the majority of the code you see from a tutorial.
Function FillInternetForm()
Dim IE As Object
Set IE = CreateObject("InternetExplorer.Application")
'create new instance of IE. use reference to return current open IE if
'you want to use open IE window. Easiest way I know of is via title bar.
IE.Navigate "https://account.makemusic.com/Account/Create/?ReturnUrl=/OpenId/VerifyGradebookRequest"
'go to web page listed inside quotes
IE.Visible = True
While IE.busy
DoEvents 'wait until IE is done loading page.
Wend
IE.Document.All("BirthMonth").Value = "1"
IE.Document.All("BirthYear").Value = "2000"
IE.Document.All("Email").Value = ThisWorkbook.Sheets("queryRNstudents").Range("f2")
IE.Document.All("Password").Value = ThisWorkbook.Sheets("queryRNstudents").Range("e2")
IE.Document.All("PasswordConfirm").Value = ThisWorkbook.Sheets("queryRNstudents").Range("e2")
IE.Document.All("Country").Value = "USA"
IE.Document.All("responseButtonsDiv").Click
newHour = Hour(Now())
newMinute = Minute(Now())
newSecond = Second(Now()) + 3
waitTime = TimeSerial(newHour, newMinute, newSecond)
Application.Wait waitTime
IE.Document.All("FirstName").Value = ThisWorkbook.Sheets("queryRNstudents").Range("a2")
IE.Document.All("LastName").Value = ThisWorkbook.Sheets("queryRNstudents").Range("b2")
IE.Document.All("Address1").Value = "123 Nowhere St"
IE.Document.All("City").Value = "Des Moines"
IE.Document.All("StateProvince").Value = "IA"
IE.Document.All("ZipPostalCode").Value = "50318"
End Function
I would use the events of the IE, more specifically the form, something like this, using MSHTML Controls library.
Private WithEvents IEForm As MSHTML.HTMLFormElement
Public Sub InternetExplorerTest()
Dim ie As SHDocVw.InternetExplorer
Dim doc As MSHTML.HTMLDocument
Set ie = New SHDocVw.InternetExplorer
ie.Visible = 1
ie.navigate "http://stackoverflow.com/questions/tagged/vba"
While ie.readyState <> READYSTATE_COMPLETE Or ie.Busy
DoEvents
Wend
Set doc = ie.document
Set IEForm = doc.forms(0)
End Sub
Private Function IEForm_onsubmit() As Boolean
MsgBox "Form Submitted"
End Function

Need to use VBA to select an option from a drop down list in Internet Explorer

I have successfully got my code to open IE, navigate to the webpage I need, and login. I now need to select an option from a drop down list - please see the following html code:
html code for the list
How do I select the "TPS Managed Conservative - Dec 11" option from the dropdown.
My code so far:
Sub Strategic_Alpha_Monthly_Pivots_1_MASTER()
' open IE, navigate to the desired page and loop until fully loaded
Dim ie As Object
Set ie = CreateObject("InternetExplorer.Application")
my_url = "http://analytics.financialexpress.net/login.aspx"
With ie
.Visible = True
.navigate my_url
Do Until Not ie.Busy And ie.readyState = 4
DoEvents
Loop
End With
' Input the userid and password
ie.document.getElementById("txtPassword").Value = "xxxxx"
' Click the "Search" button
ie.document.getElementById("btnAction").Click
Do Until Not ie.Busy And ie.readyState = 4
DoEvents
Loop
ie.document.getElementById("ListPortfolio").Select
End Sub
selectedIndex or Value could be used. According to the screenshot the value 983678630 can be used. HTH
If Not VBA.IsNull(ie.document.getElementById("ListPortfolio")) Then
Dim htmlSelect
Set htmlSelect = ie.document.getElementById("ListPortfolio")
' htmlSelect.selectedIndex = 6
htmlSelect.Value = 983678630
Else
MsgBox "Element 'ListPortfolio' was not found", vbExclamation
End If