VBA open IE as invisible is not working - vba

I am trying to open IE in background as below, but after 2 or 3 pages navigation it is taking more time to navigate and it moving in the loop
For k= 2 to lr
check_w:
Set ie = CreateObject("InternetExplorer.Application")
ie.navigate Sheets("sheet1").Range("E" & k).Value
ie.Visible = False
Application.Wait (Now() + TimeValue("00:00:03"))
check_webpage:
Set BDoc = Nothing
Web_app_Title = Sheets("sheet1").Range("E" & k).Value
search_WEB_APP_URL
If BDoc Is Nothing Then
If ie Is Nothing Then
Application.Wait (Now() + TimeValue("00:00:03"))
GoTo check_w
Else
GoTo check_webpage
End If
End If
next k

A new IE-instance is created by in every iteration of your loop.
Set ie.visible = True for testing or open a Windows Task Manager, and you see what i mean.
So, quite simply, create the IE-object once before entering the loop. After finishing the loop, quit it before setting ie = Nothing.
Set ie = CreateObject("InternetExplorer.Application")
For k= 2 to lr
ie.navigate Sheets("sheet1").Range("E" & k).Value
....
Next k
ie.quit
Set ie = nothing
Should your experience problems with your IE-object getting dropped (for whatever reason), then, by any means, you can still wrap something like
If ie = Nothing Then Set ie = CreateObject("InternetExplorer.Application")
inside the loop.
Hint: instead of Application.Wait (Now() + TimeValue("00:00:03")) I used something like While ie.busy = True in Powershell - not sure if that applies in VBA too.
EDIT: Do While ie.ReadyState <> 4 : Loop

Related

VBA closing IE javascript popup

The below code opens an instance of InternetExplorer and downloads odds. It works fine but occasionally a pop-up window appears which causes the code to not work. Any help on how to navigate the below pop-up (i.e. click 'continue to oddschecker') when the pop-up does appear?
<a class="continue beta-callout js-close-class" onclick='s_objectID="javascript:void(0)_9";return this.s_oc?this.s_oc(e):true' href="javascript:void(0)">Continue to Oddschecker</a>
Full code:
Sub Oddschecker()
Dim ie, wp As Object
Dim i As Integer
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = False
ie.Navigate "https://www.oddschecker.com/horse-racing/racing-coupon"
Do While ie.Busy
DoEvents
Loop
Do While ie.ReadyState <> 4
DoEvents
Loop
Set wp = ie.Document
'Application.ActiveSheet.UsedRange.ClearContents
Application.Worksheets("sheet1").UsedRange.ClearContents
i = 2
For Each rw In wp.getElementsByTagName("table")(0).getElementsByTagName("tr")
If rw.className = "date" Then
Worksheets("sheet1").Range("A1") = rw.innerText
ElseIf rw.className = "fixture-name" Then
i = i + 1
Worksheets("sheet1").Range("A" & i) = rw.getElementsByTagName("td")(0).innerText
i = i + 1
ElseIf rw.className = "coupons-table-row match-on" Then
For Each od In rw.getElementsByTagName("p")
If InStr(od.innerText, "(") <> 0 Then
Worksheets("sheet1").Range("A" & i) = Trim(Left(od.innerText, InStr(od.innerText, "(") - 1))
np = Trim(Right(od.innerText, Len(od.innerText) - InStr(od.innerText, "(")))
Worksheets("sheet1").Range("B" & i) = Left(np, Len(np) - 1)
i = i + 1
Else
Worksheets("sheet1").Range("A" & i) = Trim(od.innerText)
i = i + 1
End If
Next od
End If
Next rw
ie.Quit
Range("A1:B" & i).WrapText = False
Columns("A:B").EntireColumn.AutoFit
Set wp = Nothing
Set ie = Nothing
End Sub
If you wish to continue with that page (navigating to that popup page), you can try like:
Dim HTML As HTMLDocument, addcheck As Object
While IE.Busy = True Or IE.readyState < 4: DoEvents: Wend ''(You can write it the way you feel comfortable)
Set HTML = IE.document ''place this line after the prevous line
Set addcheck = HTML.querySelector("#promo-modal a.continue")
If Not addcheck Is Nothing Then
addcheck.Click
End If
But, that is not a good idea cause it will lead you to some page where you might need to do some activity to get back on this data ridden page.
I suppose you should get rid of that popup blocker by ticking the cross button located on the top right area and continue to do what you are doing:
Dim HTML As HTMLDocument, addcheck As Object
While IE.Busy = True Or IE.readyState < 4: DoEvents: Wend ''(You can write it the way you feel comfortable)
Set HTML = IE.document ''place this line after the prevous line
Set addcheck = HTML.querySelector("#promo-modal span[title='Close")
If Not addcheck Is Nothing Then
addcheck.Click
End If
If I didn't understand what your intention was, do let me know. Thanks.

Using VBA to click a link

I'm trying next to click a link to view information on a page using VBA to then move on to edit that information with VBA, But trying to figure out how to write the code for it as the ID information changes with each search,
Any ideas on this?
I've looked around and can't seem to understand how to get VBA to pick this line up as the (ID=) and it isn't joined to the same ID as I'm searching for.
There is also serval references for
This is the line of code.
View
This is my current code to do the search for it. Without clicking on the view section yet.
Sub Test()
Dim ie As Object
Dim form As Variant
Dim button As Variant
Dim LR As Integer
Dim var As String
LR = Cells(Rows.Count, 1).End(xlUp).Row
For x = 2 To LR
var = Cells(x, 1).Value
Set ie = CreateObject("internetexplorer.application")
ie.Visible = True
With ie
.Visible = True
.navigate "*******"
While Not .readyState = READYSTATE_COMPLETE
Wend
End With
'Wait some to time for loading the page
While ie.Busy
DoEvents
Wend
Application.Wait (Now + TimeValue("0:00:02"))
ie.document.getElementById("quicksearch").Value = var
'code to click the button
Set form = ie.document.getElementsByTagName("form")
Application.Wait (Now + TimeValue("0:00:02"))
Set button = form(0).onsubmit
form(0).submit
'wait for page to load
While ie.Busy
DoEvents
Wend
Next x
End Sub
Edited
I've added in the code I think it should be following that link and a bit of tinkering to get it to not error with compiler errors :D, All seems to work but when it get's to the line to click the link it doesn't fail but doesn't even click it. It will then move on to the next one in the list in the spreed sheet, Which is expected.
Following it through with the debugger that shows nothing erroring or failing which is what I expect it to do if the code was wrong or link,
Any help, please ?
This is the code now
Sub Test1()
Dim ie As Object
Dim form As Variant
Dim button As Variant
Dim LR As Integer
Dim var As String
LR = Cells(Rows.Count, 1).End(xlUp).Row
For x = 2 To LR
var = Cells(x, 1).Value
Set ie = CreateObject("internetexplorer.application")
ie.Visible = True
Dim a
Dim linkhref
linkhref = "/?do_Action=ViewEntity&Entity_ID"
With ie
.Visible = True
.navigate "*******"
While Not .readyState = READYSTATE_COMPLETE
Wend
End With
'Wait some to time for loading the page
While ie.Busy
DoEvents
Wend
Application.Wait (Now + TimeValue("0:00:02"))
ie.document.getElementById("quicksearchbox").Value = var
'code to click the button
Set form = ie.document.getElementsByTagName("form")
Application.Wait (Now + TimeValue("0:00:02"))
Set button = form(0).onsubmit
form(0).submit
'wait for page to load
While ie.Busy
DoEvents
Wend
Application.Wait (Now + TimeValue("0:00:02"))
For Each a In ie.document.getElementsByTagName("a")
If (a.getAttribute("href")) = ("/?do_Action=ViewEntity&Entity_ID=") Then
a.Click
Exit For
Application.Wait (Now + TimeValue("0:00:02"))
While ie.Busy
DoEvents
Wend
End If
Next
Next x
End Sub
This is a copy of the code around the buttons,
This is the code surrounding the buttons,
View
Decom
Log</td>
Thank you.
Use a For to check every <a> tag element and make sure you click the right one. It's true your ID changes, but rest of string is constant, so that's 1 factor. Also, it looks like you always will click where it says View so that's another constant.
With both options, we can develop a simple For..Next that will check every <a> element and will check if those 2 options requirements are fulfilled:
For Each a In ie.document.getElementsByTagName("a")
If Left(a.href, 37) = "/?do_Action=ViewEntity&Entity_ID=" And a.innerText = "View" Then
a.Click
Exit For
Next a
Try it and let's see if this works for you.
If the element href is something like "/?do_Action=ViewEntity&Entity_ID=14287", this if statement is never going to evaluate to True:
(a.getAttribute("href")) = ("/?do_Action=ViewEntity&Entity_ID=")
So the element will never be clicked.
If you know the Entity_ID you want to click you can do:
Dim Entity_ID as Integer
Entity_ID = 14287
If (a.getAttribute("href")) = "/?do_Action=ViewEntity&Entity_ID=" & Cstr(myID) Then a.click
Otherwise just check if the element href contains that url:
If InStr(1, a.getAttribute("href"), linkhref) > 0 Then a.click
EDIT
Ok, using the HTML you posted I am able to access the specified a tag that you requested, by doing this
For Each ele In ie.document.getElementById("searchresults").getElementsByTagName("a")
If InStr(1, ele.href, "do_Action=ViewEntity") > 0 Then
MsgBox "The button is found!"
End If
Next

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

Excel VBA multiple For loop not working

I seem to be stuck in an weird issue. I have the Excel VBA code below to visit a website and enter a userID (from the userID column A in sheet 1) and retrieve the name of the user which shows up after hitting the submit button then continues with the rest of the userIDs.
Public Sub TEST()
TestPage = "http://test.com/"
Dim IE As New InternetExplorer
Dim Doc As HTMLDocument
Dim GetElem As Object
Dim GetElem2 As Object
IE.Visible = True
IE.navigate TestPage
Do
DoEvents
Loop Until IE.readyState = READYSTATE_COMPLETE
Application.Wait (Now + TimeValue("0:00:04"))
Set Doc = IE.document
CurRow = Sheet1.UsedRange.Rows.Count
Do While CurRow > 0
Application.Wait (Now + TimeValue("0:00:4"))
'Find/Get the userID textbox and enter the current userID
For Each GetElem In Doc.getElementsByTagName("input")
If GetElem.ID = "query" Then 'I could just do getElementByID later
GetElem.Value = Sheet1.Range("A" & CurRow).Value
End If
Next
'Find and click the submit button
For Each GetElem2 In Doc.getElementsByTagName("button")
If GetElem2.Type = "submit" Then
GetElem2.Click
Application.Wait (Now + TimeValue("0:00:03"))
End If
Next
CurRow = CurRow - 1
Loop
End Sub
The problem is the code works only once. It enters the first userID into the text box and hits Submit. When it loops and tries to enter the next userID though, the code get stuck in a loop.
If I remove the entire 2nd For-Next loop it works (although it doesn't submit, it enters each of the userIDs in the text box).
On top of that, if I use the F8 debugging the code step by step, everything works fine. Only getting problems when fully running the code.:(
Public Sub TEST()
TestPage = "http://test.com/"
Dim IE As New InternetExplorer
Dim Doc As HTMLDocument
Dim GetElem As Object
Dim GetElem2 As Object
IE.Visible = True
IE.navigate TestPage
Do
DoEvents
Loop Until IE.readyState = READYSTATE_COMPLETE
Application.Wait (Now + TimeValue("0:00:04"))
Set Doc = IE.document
CurRow = Sheet1.UsedRange.Rows.Count
For Each GetElem In Doc.getElementsByTagName("input")
If GetElem.ID = "query" Then 'I could just do getElementByID later
GetElem.Value = Sheet1.Range("A" & CurRow).Value
For Each GetElem2 In Doc.getElementsByTagName("button")
If GetElem2.Type = "submit" Then
GetElem2.Click
Application.Wait (Now + TimeValue("0:00:03"))
End If
Next GetElem2
End If
CurRow = CurRow + 1
Next GetElem
End Sub

Reference Cell in VBA Script

I was curious if there is a way to reference a specific cell within the following VBA script. The cell contains a date in yyyymmdd format, which would go in the commented section below.
Sub OpenData()
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = False
IE.navigate "http://website.com/'desired cell value'/subdirectory/file.txt"
'Check for good connection to web page loop!
Do
If IE.readyState = 4 Then
IE.Visible = True
Exit Do
Else
DoEvents
End If
Loop
'Wait for window to open!
Application.wait (Now + TimeValue("0:00:02"))
'MsgBox "Done"
IE.Visible = True
Eric
Have you tried format?
'...
IE.navigate "http://website.com/" & Format (Cells(1,1).Value, “dd/MM/yyyy”) & "/subdirectory/file.txt" '...