VBA Automation isn't working on new IE tab - excel

It's my first question and I'm new on VBA.
I was trying to run a macro to automatize some procedures on IE. My macro worked very well when opened on diferent windows, but when I tried to run the same macro on tabs it didn't work. It seems (maybe) the macro isn't recognizing the actual tab. Could anyone help me, please?
Sub Test1()
Dim IE As Object
Dim doc As HTMLDocument
Set IE = CreateObject("InternetExplorer.Application")
For intRow = 1 To 3
If intRow = 1 Then
With IE
.Visible = True
.navigate "https://gru.inpi.gov.br/pePI/jsp/patentes/PatenteSearchBasico.jsp"
Do While IE.Busy Or IE.readyState <> 4
Application.Wait DateAdd("s", 1, Now)
Loop
Set doc = IE.document
IE.document.getElementById("principal").Children(4). _
getElementsByTagName("tbody")(0).getElementsByTagName("tr")(5). _
getElementsByTagName("td")(1).getElementsByTagName("font")(0). _
getElementsByTagName("input")(0).Value = "intRow"
Application.Wait DateAdd("s", 2, Now)
End With
Else
With IE
.Visible = True
.navigate "https://gru.inpi.gov.br/pePI/jsp/patentes/PatenteSearchBasico.jsp", 2048&
Do While IE.Busy Or IE.readyState <> 4
Application.Wait DateAdd("s", 1, Now)
Loop
.document.getElementById("principal").Children(4). _
getElementsByTagName("tbody")(0).getElementsByTagName("tr")(5). _
getElementsByTagName("td")(1).getElementsByTagName("font")(0). _
getElementsByTagName("input")(0).Value = "intRow"
Application.Wait DateAdd("s", 2, Now)
End With
End If
Next
End Sub

According to your code and the website, it seems that you want to open multiple tab (with the same URL), and then fill a value in the text box. We should pay attention to the following point:
How to access the web page elements.
How to switch tabs and focus to the new tab.
To access the web page elements, from your web page resource (use F12 developer tools to check it), I notice that the table contains 6 rows, but the last row doesn't contain the input element. So, using your code, I can't find the input element. I found that the input elements contain the class property. So, I suggest you could use the getElementsByClassName method to find the element.
To switch the IE browser tab, we could loop through the opened tabs and compare the URL, and then set focus on the related tab.
More detail steps, please check the following sample code:
Sub Test1()
Dim IE As Object
Set IE = CreateObject("InternetExplorer.Application")
Dim intRow As Integer
For intRow = 1 To 3
If intRow = 1 Then
With IE
.Visible = True
.navigate "https://gru.inpi.gov.br/pePI/jsp/patentes/PatenteSearchBasico.jsp"
Do While IE.Busy Or IE.readyState <> 4
Application.Wait DateAdd("s", 1, Now)
Loop
Set doc = IE.document
IE.document.getElementsByClassName("basic")(0).Value = "intRow" & intRow
Application.Wait DateAdd("s", 3, Now)
End With
Else
With IE
.Visible = True
.navigate "https://gru.inpi.gov.br/pePI/jsp/patentes/PatenteSearchBasico.jsp", 2048&
Do While IE.Busy Or IE.readyState <> 4
Application.Wait DateAdd("s", 1, Now)
Loop
Application.Wait DateAdd("s", 3, Now)
Set IE = GetIE("https://gru.inpi.gov.br/pePI/jsp/patentes/PatenteSearchBasico.jsp")
Application.Wait DateAdd("s", 3, Now)
IE.document.getElementsByClassName("basic")(0).Value = "intRow" & intRow
End With
End If
Next
End Sub
Function GetIE(sLocation As String) As Object
Dim retVal As Object
Dim my_url As String, my_title As String
Set objShell = CreateObject("Shell.Application")
IE_count = objShell.Windows.Count
'loop through the window and find the tab
For x = 0 To (IE_count - 1)
On Error Resume Next
'get the location and title
my_url = objShell.Windows(x).document.Location
my_title = objShell.Windows(x).document.Title
'debug to check the value
Debug.Print x
Debug.Print my_url
'find the special tab based on the title.
If my_url Like sLocation Then
Set retVal = objShell.Windows(x)
'IE.Quit 'call the Quit method to close the tab.
'Exit For 'exit the for loop
Else
End If
Next
Set GetIE = retVal
End Function
After running the above script, it will open three tabs and fill a value in the Login input text. Please see the following screenshot:
Reference:
Common VBA Methods & Properties used in web automation

Related

VBA Automation (macro) isn't working very well on IE tabs

I'm new here and on VBA, it's my 2nd post and I don't speak english very well. So, please, take easy on me =D
Last week I was having some troubles trying to automatize some procedures on IE. My macro worked very well when opened on new windows, but when I tried to run the same macro on tabs it wasn't working. It seemed (maybe) the macro wasn't recognizing the actual tab. I post that problem here and a wonderfull guy called Deepak-MSFT helped me a lot. He taught me how to run the macro on tabs and it worked almost 100%.
Problems:
1 - The macro sometimes work, sometimes doesn't. Yesterday, for example, I was getting errors 424, 91 and, sometimes, it just opened another tab without insert the value (perheaps because of the "On Error Resume Next"). I think it was because one of the websites was slow. I tried to increase the TimeValue until 7 seconds but, even so, it didn't work. I tested during the whole day and it was extremely unstable, sometimes worked, and somtimes it doesn't. But today it's working (all the websites are stable). Any idea how to solve this instability?
2 - There are 2 websites (2nd and 3rd) where I use querySelector to find the box to insert the value. Both of them work on 70% of the PC's of my company and only those 2 websites doesn't work on the other 30%. I installed the same version of IE (11.0.9600), Excel (2007, SP3) and Windows (W7) on all of them, but even so, only those 2 websites with queryselector don't work. There are no errors. The macro just don't insert the value. Perhaps I'm missing something that make queryselector works on those PC's, but all the references match. I dig the first 5 pages on google trying to find a solution but I failed. I think there's a witch flying around those PC's. Could you help me?
3 - I have total instability trying to run my macros on Excel 2016 or other versions of Excel higher than 2007 at Windows 10. Does anyone have a good solution to adapt the program to run on Excel 2016 (all my company will run this version next year) without have to do all over again?
Thank you very much guys. Here is my code:
Sub ademo()
Dim i As Long
Dim URL As String
Dim IE As Object
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
'TAB 1
URL = "https://servicos.ibama.gov.br/ctf/publico/areasembargadas/ConsultaPublicaAreasEmbargadas.php"
IE.Navigate2 URL
Do While IE.readyState = 4: DoEvents: Loop 'Do While
Do Until IE.readyState = 4: DoEvents: Loop 'Do Until
IE.document.getElementById("num_cpf_cnpj").Value = "demo1" 'Sheets("Main").Range("C10")
IE.document.getElementById("Emitir_Certificado").Click
'TAB 2 - DAP
On Error Resume Next
IE.Visible = True
IE.Navigate2 "http://smap14.mda.gov.br/extratodap/", 2048&
Application.Wait (Now + TimeValue("0:00:04"))
Set IE = GetIE("http://smap14.mda.gov.br/extratodap/")
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
Set doc = IE.document
On Error Resume Next
Set Target = IE.document.querySelector("#corpo > div > div > div:nth-child(1) > button")
Target.Click
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
doc.getElementById("txtCPF_CNPJ").Value = "demo2"
'TAB 3 - CNDT
IE.Visible = True
On Error Resume Next
IE.Navigate2 "http://aplicacao.jt.jus.br/cndtCertidao/inicio.faces", 2048&
Application.Wait (Now + TimeValue("0:00:04"))
Set IE = GetIE("http://aplicacao.jt.jus.br/cndtCertidao/inicio.faces")
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
Set doc = IE.document
On Error Resume Next
Set target2 = IE.document.querySelector("#corpo > div > div:nth-child(2) > input:nth-child(1)")
target2.Click
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
doc.getElementById("gerarCertidaoForm:cpfCnpj").Value = "demo3"
'TAB 4 - CND
On Error Resume Next
IE.Visible = True
IE.Navigate2 "http://servicos.receita.fazenda.gov.br/Servicos/certidao/CNDConjuntaInter/InformaNICertidao.asp?tipo=2", 2048&
Application.Wait (Now + TimeValue("0:00:04"))
Set IE = GetIE("http://servicos.receita.fazenda.gov.br/Servicos/certidao/CNDConjuntaInter/InformaNICertidao.asp?tipo=2")
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
Set doc = IE.document
On Error Resume Next
IE.document.getElementsByName("NI")(0).Value = "demo4"
'TAB 5 - IMPROBIDADE
IE.Visible = True
IE.Navigate2 "http://www.cnj.jus.br/improbidade_adm/consultar_requerido.php?validar=form", 2048&
Application.Wait (Now + TimeValue("0:00:04"))
Set IE = GetIE("http://www.cnj.jus.br/improbidade_adm/consultar_requerido.php?validar=form")
IE.document.getElementById("num_cpf_cnpj").Value = "demo5"
End Sub
Function GetIE(sLocation As String) As Object
Dim objShell As Object, objShellWindows As Object, o As Object
Dim sURL As String
Dim retVal As Object
Set retVal = Nothing
Set objShell = CreateObject("Shell.Application")
Set objShellWindows = objShell.Windows
For Each o In objShellWindows
sURL = ""
On Error Resume Next 'because may not have a "document" property
'Check the URL and if it's the one you want then
' assign the window object to the return value and exit the loop
sURL = o.document.Location
On Error GoTo 0
If sURL Like sLocation & "*" Then
Set retVal = o
Exit For
End If
Next o
Set GetIE = retVal
End Function

Right Clicking on a particular Web Page in VBA

I am trying to Right click on Google Maps page, So far I am able to create the object ie, navigate to the page and search for a particular address.
But in the next step I have to click on the bottom of Address marker (Blue Dot)
After the click, I want to select What's Here from the options.
After the selection, I use the line
ie.document.getElementsByClassName("link-like widget-reveal-card-lat-lng")(0).innerText to get the co-ordinates of the Place.
Code so Far:
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = True
ie.navigate "https://www.google.com/maps"
Do While ie.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
Application.Wait DateAdd("s", 1, Now)
ie.document.getElementById("searchboxinput").Value = "Signature Tower GurGaon"
ie.document.getElementById("searchbox-searchbutton").Click
MsgBox "After Manually clicking What's Here, press ok"
Basically I want to automate that Manual part. What are the elements that needs to be clicked for the right click and how do I identify the point where to click.
Alternate:
Just found that, those lat-long are also part of the a href by
ie.document.getElementsByClassName("gb_9d gb_2 gb_ob")(0).href
So there is no need to right click.
But I am still interested to know how to Right Click it.
Note that you can put the search term directly into the first navigate.
IE.navigate "https://www.google.com/maps" & "/search/Signature Tower GurGaon"
Your wait loop should check .Busy and .ReadyState
Do While IE.Busy Or IE.ReadyState <> 4
And as you already found out the coordinates are in the source code
Option Explicit
Public Sub Test()
Dim IE As Object
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.navigate "https://www.google.com/maps" & "/search/Signature Tower GurGaon"
Do While IE.Busy Or IE.ReadyState <> 4
Application.Wait DateAdd("s", 1, Now)
Loop
Application.Wait DateAdd("s", 1, Now)
Dim GetLocation As String
GetLocation = IE.document.getElementsByClassName("gb_9d gb_2 gb_ob")(0).href
GetLocation = Right$(GetLocation, Len(GetLocation) - InStr(1, GetLocation, "%40") - 2)
GetLocation = Left$(GetLocation, InStr(1, GetLocation, "&") - 1)
Dim Location() As String
Location = Split(GetLocation, "%2C")
Debug.Print "Lat", Location(0)
Debug.Print "Lon", Location(1)
Debug.Print "zoom", Location(2)
End Sub
Will result in
Lat 28.4636862
Lon 77.054257
zoom 16z

Error automating website data entry as the website is still loading

I have code which picks up data from multiple columns from ThisWorkbook and puts in various field in website in internet explorer. The website loads after clicking on line1 (Search button). Then the code throws an error at line2 where it clicks on checkbox, as there is no checkbox yet if the website is still loading. (I think the website is built on Sharepoint and is poorly coded.)
Is there any code which repeats line 2 after 2-3 seconds and continues further whenever the error appears? I tried error handler to repeat the code but didn't work.
Sub CSA_Upload()
Dim test1 As Long, test2 As Long
test1 = Timer
Dim n As Long
Range("A1").Select
n = Selection.End(xlDown).Row
ThisWorkbook.Sheets("Data").Range("A2:A" & n).Interior.ColorIndex = 0
Dim IE As Object
Dim doc As Object
Dim htmlTable As htmlTable
Set IE = New InternetExplorerMedium
'Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
'Navigate to CSA tool Home Page
IE.navigate "https://csa.abcdefg.com/Collector_view.aspx/"
'Wait till it loads
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
Set doc = CreateObject("htmlfile")
Set doc = IE.document
'Enter Invoice Number in SearchBy box
doc.getElementById("ContentPlaceHolder1_ddlSearch").Value = "[Inv Number]"
Range("A1").Select
'Count the number of rows in the data list
Dim X As Long
Range("A1").Select
X = Selection.End(xlDown).Row
'For each invoice number the loop starts here
For rowNo = 2 To X
ActiveCell.Offset(1).Select
'Fill Blue colour in active processing invoice number cell
ThisWorkbook.Sheets("Data").Range("A" & rowNo).Interior.ColorIndex = 37
'Input the invoice number
doc.getElementById("ContentPlaceHolder1_txtSearch").Value = ThisWorkbook.Sheets("Data").Range("A" & rowNo).Value
'Click the Search button
'This is the Line1
doc.getElementById("ContentPlaceHolder1_search").Click
'Wait till it loads
Do While IE.Busy
Application.Wait DateAdd("s", 5, Now)
Loop
'Checkbox select all
'This is the Line2
doc.getElementById("ContentPlaceHolder1_GridView1_chkboxSelectAll").Click
'Wait 3 seconds till it selects all the checkboxes
Application.Wait DateAdd("s", 3, Now)
'Enter rest of the data
doc.getElementById("ContentPlaceHolder1_ddlaction").Value = ThisWorkbook.Sheets("Data").Range("B" & rowNo).Value 'Input Action
doc.getElementById("ContentPlaceHolder1_txtToDoDate").Value = ThisWorkbook.Sheets("Data").Range("C" & rowNo).Value 'Input Action Date
doc.getElementById("ContentPlaceHolder1_ddlstatus").Value = ThisWorkbook.Sheets("Data").Range("D" & rowNo).Value 'Input Root Cause
doc.getElementById("ContentPlaceHolder1_txtcomments").Value = ThisWorkbook.Sheets("Data").Range("E" & rowNo).Value 'Input Comments
doc.getElementById("ContentPlaceHolder1_btn_Comments").Click 'Click Submit button
Application.Wait DateAdd("s", 3, Now)
'Hit enter on MessegeBox
Application.SendKeys "{ENTER}"
'Fill Green colour in the active cell when all entries are passed
ThisWorkbook.Sheets("Data").Range("A" & rowNo).Interior.ColorIndex = 35
Next 'Proceed to next invoice number
IE.Quit 'Quit Internet explorer
test2 = Timer
MsgBox (X - 1) & " Invoices have been updated and it took " & Format((test2 - test1) / 86400, "hh:mm:ss") & " Seconds."
End Sub
revised on 2019-03-25
I think the error is thrown because the doc is changed.
Rewrite
' This is the Line2
doc.getElementById("ContentPlaceHolder1_GridView1_chkboxSelectAll").Click
'Wait 3 seconds till it selects all the checkboxes
Application.Wait DateAdd("s", 3, Now)
as
' This is the Line2
application.wait Application.Wait DateAdd("s", 1, Now)
set doc = IE.document
doc.getElementById("ContentPlaceHolder1_GridView1_chkboxSelectAll").Click
'Wait 3 seconds till it selects all the checkboxes
Application.Wait DateAdd("s", 3, Now)
maybe helpful.
Use proper page load waits after each .Navigate and .Click.
While ie.Busy Or ie.readyState < 4: DoEvents: Wend
Also, you can wrap elements that are throwing errors, related to timings, in timed loops which attempt to set the object reference
Dim t As Date, ele As Object
Const MAX_WAIT_SEC As Long = 10
t = Timer
Do
On Error Resume Next
Set ele = doc.getElementById("ContentPlaceHolder1_GridView1_chkboxSelectAll")
On Error GoTo 0
If Timer - t > MAX_WAIT_SEC Then Exit Do
Loop While ele Is Nothing
If Not ele Is Nothing Then
ele.Click
End If
I have removed below wait loop after line 1.
'Wait till it loads
Do While IE.Busy
Application.Wait DateAdd("s", 5, Now)
Loop
and added fix 10 seconds wait time Application.Wait DateAdd("s", 10, Now) just before
doc.getElementById("ContentPlaceHolder1_GridView1_chkboxSelectAll").Click
'Wait 3 seconds till it selects all the checkboxes
Application.Wait DateAdd("s", 3, Now)
So the final piece of code is as below and it's working!
'This is the Line1
doc.getElementById("ContentPlaceHolder1_search").Click
'Checkbox select all
'This is the Line2
Application.Wait DateAdd("s", 10, Now)
doc.getElementById("ContentPlaceHolder1_GridView1_chkboxSelectAll").Click
'Wait 3 seconds till it selects all the checkboxes
Application.Wait DateAdd("s", 3, Now)

Excel VB Macro to scrape webpage. Can't code to click html button

I have a short excel macro that is designed to:
1) Open Internet Explorer and navigate to "http://www.puco.ohio.gov/pucogis/address/search.cfm"
2) Fill out a form on that site with data from the excel workbook
3) Click a button to submit the form
4) Scrape some innertext from the website and place it in a cell in the workbook
5) Close Internet Explorer
I can not get step 3 to work. That is, I can not get the click/submit function to work with this website. When the button is clicked the website populates with information specific to the information entered in the form. Everything else in the code is working. I have searched for an answer and tried the submit verses click approach with no luck.
Thanks for you help.
Code below:
Private Sub SiteData()
Dim ie As Object
Dim utility As Variant
Dim HTMLButton
Set ie = CreateObject("InternetExplorer.Application")
ie.Navigate "http://www.puco.ohio.gov/pucogis/address/search.cfm"
ie.Visible = True
While ie.Busy
DoEvents
Wend
ie.Document.all("address").Value = ThisWorkbook.Sheets("Site Info").Range("D14")
While ie.Busy
DoEvents
Wend
Set HTMLButton = ie.Document.getElementsByTagName("input")(1)
HTMLButton.Click
While ie.Busy
DoEvents
Wend
Set utility = ie.Document.getElementById("supName")
ThisWorkbook.Sheets("Site Info").Range("D50") = utility.innerText
ie.Quit
Set ie = Nothing
End Sub
Try this solution, which I found from this answer to a similar question. That answer was not accepted, but I have tested this with your code and seems to be working.
Private Sub SiteData()
Dim ie As Object
Dim utility As Variant
Dim HTMLButton
Set ie = CreateObject("InternetExplorer.Application")
ie.Navigate "http://www.puco.ohio.gov/pucogis/address/search.cfm"
ie.Visible = True
While ie.Busy
DoEvents
Wend
ie.Document.all("address").Value = ThisWorkbook.Sheets("Site Info").Range("D14")
While ie.Busy
DoEvents
Wend
Call ie.Document.parentWindow.execScript("codeAddress()")
While ie.Busy
DoEvents
Wend
Set utility = ie.Document.getElementById("supName")
ThisWorkbook.Sheets("Site Info").Range("D50") = utility.innerText
ie.Quit
Set ie = Nothing
End Sub
If you don't know or can't reasonably anticipate the function call codeAddress(), then you can try something like this to derive it from the button's onclick property:
Dim fn$
fn = HTMLButton.onclick
fn = Mid(fn, InStr(fn, "{"))
fn = Trim(Replace(Replace(Replace(fn, "{", vbNullString), "}", vbNullString), vbLf, vbNullString))
Call ie.Document.parentWindow.execScript(fn)
You can call the JavaScript directly. try this it will work
Instead of:
Set HTMLButton = ie.Document.getElementsByTagName("input")(2)
HTMLButton.Click
use
ie.Document.parentWindow.execScript code:="codeAddress()"
note that IE may prompt you to confirm every run so you may need to
stop showing this message for smooth operation
Private Sub CommandButton1_Click()
Dim ie As Object
Dim utility As Variant
Dim HTMLButton
Set ie = CreateObject("InternetExplorer.Application")
ie.Navigate "http://www.puco.ohio.gov/pucogis/address/search.cfm"
ie.Visible = True
While ie.Busy
DoEvents
Wend
ie.Document.all("address").Value = ThisWorkbook.Sheets("Site Info").Range("D14")
While ie.Busy
DoEvents
Wend
ie.Document.parentWindow.execScript code:="codeAddress()"
'Set HTMLButton = ie.Document.getElementsByTagName("input")(2)
'HTMLButton.Click
While ie.Busy
DoEvents
Wend
Set utility = ie.Document.getElementById("supName")
ThisWorkbook.Sheets("Site Info").Range("D16") = utility.innerText
ie.Quit
Set ie = Nothing
End Sub
thanks also to this article helped me to solve your problem
How to find and call javascript method from vba

Excel VBA object required error with IE automation

So I have some code to go to a website and then login. Then I need it to go to the password change URL. Sometimes when I run the code, I get the following error:
Runtime Error 424: Object Required
Sometimes the debugger says it is the first getelementbyid statement, but most times it says the issue is the last three getelementbyid statements. The code is below:
Dim ie As Variant
Dim strURL As String
Sub login()
Set ie = New SHDocVw.InternetExplorer
ie.Visible = True
ie.navigate "https://minecraft.net/profile"
While ie.Busy
DoEvents
Wend
ie.document.getElementById("username").Value = "ddd"
ie.document.getElementById("password").Value = "ddddddddddd"
Dim htmlForm As HTMLFormElement
Set htmlForm = ie.document.getElementById("loginForm")
htmlForm.submit
' **********************************************************************
'IE.Document.getElementById("username").Value = "ddddd"
' IE.Document.getElementById("password").Value = "ddddd"
' IE.Document.getElementById("signin").Click
'**********************************************************************
'Pause while page loads
Application.Wait (Now + #12:00:03 AM#)
ie.navigate "https://minecraft.net/profile/password"
ie.document.getElementById("oldPassword").Value = "oldpass"
ie.document.getElementById("password").Value = "enwapss"
ie.document.getElementById("passwordConfirmation").Value = "enwapss"
Set htmlForm = ie.document.getElementById("loginForm")
htmlForm.submit
End Sub
Thanks in advance!
It may be that the website isn't in a ready state, as in the site hasn't fully loaded when it's attempting to input the values.
After
ie.navigate "https://minecraft.net/profile/password"
Try adding
Do Until Not ie.Busy And ie.readyState = 4
DoEvents
Loop
This will loop until the webpage has loaded similar, to the way you've done it in your above code with
Application.Wait (Now + #12:00:03 AM#)

Resources