Will go to the school page and click on the like button. I'm going to the page object htmldivelement feature does not click the button. My commands are running with IE10, but it doesn't work with IE11.
Set hIE = CreateObject("InternetExplorer.Application")
hURL = "http://mukerremalikayanilkokulu.meb.k12.tr/icerikler/eglen-dusun-bul_6506730.html"
With hIE
.Navigate hURL
.Visible = True
Do While hIE.Busy
Loop
End With
Set haberss = hIE.document.getElementsByClassName("begen")
For Each haberbb In haberss
If haberbb = "begen" Then
Do While hIE.Busy
Loop
haberbb.Click
Set hIE = hIE.Quit
Exit For
Else
Do While hIE.Busy
Loop
haberbb.Click
Set hIE = hIE.Quit
Exit For
End If
The haberbb button works on IE10, but on IE11 it does not work.
I don’t know if that is functional or needs some form of login. I cannot manually click like.
Here are 3 code ways:
Ie.document.querySelector(".begen").click
Ie.document.querySelector(".begen").FireEvent "OnClick"
Ie.document.parentWindow.execScript "document.querySelector('.begen').click;"
Option Explicit
Public Sub AttemptClick()
Dim ie As New InternetExplorer
With ie
.Visible = True
.Navigate2 "http://mukerremalikayanilkokulu.meb.k12.tr/icerikler/eglen-dusun-bul_6506730.html"
While .Busy Or .readyState < 4: DoEvents: Wend
.document.querySelector(".begen").FireEvent "onclick"
.document.querySelector(".begen").Click
.document.parentWindow.execScript "document.querySelector('.begen').click();"
Stop
.Quit
End With
End Sub
In addition to QHarr's answer, your Do While...Loop isn't quite right.
You should do something in the loop, otherwise you are just going to spike the CPU usage. You should at least add a DoEvents in between to allow windows to process other programs/messages.
It doesn't look like you are waiting for the page load to complete. Try adding Or ReadyState < READYSTATE_COMPLETE to the loop condition.
Putting it together, the loop should look like:
Do While IE.Busy Or IE.ReadyState < READYSTATE_COMPLETE ' = 4
DoEvents
Loop
Here are some other references that might help:
Failproof Wait for IE to load
How to wait for the page to load after click
Related
I am relatively new at VBA (I know the basics, but not much else) and I am trying to get some code set up that will fill out online forms for me, but when I run my code I get a 438 error:
object doesnt support this property or method
when it gets to
ie.document.getElementById ("q")
I have added the HTML object library and Microsoft internet controls to my references. I have looked at tons of online forums. I have even copied and pasted an entire script directly into VBA. Nothing will make it use getElementById(). Here is my code:
Sub internetstuff()
Dim ie As Object
Set ie = CreateObject("internetexplorer.application")
ie.Visible = True
ie.navigate ("https://www.google.com/")
Set searchbx = ie.document.getElementById("q")
searchbx.Value = "Howdy!"
End Sub
What should happen is that it should open InternetExplorer, go to Google, and populate the search bar with "Howdy!".
Instead, It only opens google, then I get the error message and it stops running.
Because "q" is not an ID, it's a Name.
You have to use GetElementsByName and select the 1st Element
try this:
Sub internetstuff()
Dim ie As Object
Set ie = CreateObject("internetexplorer.application")
ie.Visible = True
ie.Navigate ("https://www.google.com/")
Do Until ie.ReadyState >= 4
DoEvents
Loop
Set searchbx = ie.document.getElementsByName("q")(0)
searchbx.Value = "Howdy!"
End Sub
I have also added a waiting Event, in case it takes time to load Google.
Result:
A more concise and efficient way is to use querySelector to return first match for the name attribute
Option Explicit
Public Sub internetstuff()
Dim ie As Object
Set ie = CreateObject("InternetExplorer.Application")
With ie
.Visible = True
.Navigate2 "https://www.google.com/"
While .Busy Or .readyState < 4: DoEvents: Wend
.document.querySelector("[name=q]").Value = "Howdy"
Stop '<delete me later
.Quit
End With
End Sub
I have some VBA to launch a company intranet site which will bring me directly to the document I am searching for. I need to wait for the page to finish loading, and then hit the "Print" button which will open the document in a Adobe Reader supported IE tab, and from there I save it as a PDF to a drive.
My issue is that the loop I have to wait until the webpage is loaded does not properly wait. Doing some research on SO, I've seen this is a known issue with newer versions of IE. I have since tried playing with some XMLHTTP methods, but I am unfamiliar with those, and my attempts with it have also fallen short (not sure how I would navigate to the next page by hitting the Print link using XMLHTTP).
My current VBA is as follows, and ieApp is New InternetExplorerMedium.
Set objShell = CreateObject("Shell.Application")
IE_Count = 0
IE_Count = objShell.Windows.Count
For x = 0 To (IE_Count - 1)
On Error Resume Next
my_url = ""
my_title = ""
my_url = objShell.Windows(x).Document.Location
my_title = objShell.Windows(x).Document.Title
If my_url Like "http://ctdayppv002/Home/DocViewer?" & "*" Then
Set ie = objShell.Windows(x)
Do While ieApp.ReadyState <> 4 And ie.Busy
DoEvents
Loop
For Each ee In ie.Document.getElementsByTagName("a")
If ee.ID = "printDocLink" Then
ee.Click: DoEvents: Sleep 1500
Do While ie.ReadyState <> 4 And ie.Busy
DoEvents
Loop
Exit For
End If
Next ee
Exit For
Else
End If
Next
If I add a bunch of Sleep time, then it will wait, until a document comes up that exceeds the time I told it to Sleep, so obviously that isn't a reliable solution.
Using the following questions for reference, I have tried to use XMLHTTP, but also noticed comments that this method may not work with JavaScript sites.
VBA hanging on ie.busy and readystate check
web scraping with vba using XMLHTTP
One of my attempts with XMLHTTP:
Public ieApp As MSXML2.XMLHTTP60
Set ieApp = New MSXML2.XMLHTTP60
With ieApp
.Open "GET", urlString, False
.send
While ieApp.ReadyState <> 4
DoEvents
Wend
Dim HTMLDoc As MSHTML.HTMLDocument
Dim HTMLBody As MSHTML.HTMLBody
Set HTMLDoc = New MSHTML.HTMLDocument
Set HTMLBody = HTMLDoc.body
HTMLBody.innerHTML = ieApp.responseText
Debug.Print HTMLBody.innerHTML
End With
Within the resulting HTMLBody.innerHTML I do not see the "printDocLink" element.
FYI - I have been emailing a rep from the company that created the website database, and they do not believe there is an API call that can directly export as a PDF, which I was hoping would be available to skip over the "Print" button entirely.
Following the advice from Tim Williams and QHarr, I found a solution that works for me.
I added a Do Until, and also a timer for 6 seconds:
t = Now + TimeValue("0:00:6")
Do Until .Document.getElementById("printDocLink") <> 0
DoEvents: Sleep 1000
If Now > t Then
Call Not_Found_PPV(N, searchitem)
.Quit
Set ieApp = Nothing
GoTo NxtInv
End If
Loop
I want to create a code in Excel Vba to help me click a js image button in a website.
Here is what i have tried.
Sub test()
Dim ie As Object
Set ie = New InternetExplorer
WebPage = "http://myweb.com" 'a makeup link, not really my site
ie.Visible = True
ie.Navigate WebPage
Application.Wait (Now() + TimeValue("00:00:05"))
ie.Document.getElementById("ctl00_ContentPlaceHolder1_tcSearchRoute_tabSearchRoute2_ibtnSearchR2").Click
End Sub
When I run the code, it says
RunTime Error '-2147217848(80010108)'
Automation error
The object invoked has disconnected from its clients.
Here is the html code for that js image button
<input type="image" name="ctl00$ContentPlaceHolder1$tcSearchRoute$tabSearchRoute2$ibtnSearchR2" id="ctl00_ContentPlaceHolder1_tcSearchRoute_tabSearchRoute2_ibtnSearchR2" src="../Images/button/btn_searchAccount.png" alt="Search Account" style="border-width:0px;">
Your .Click line seems ok to me. Have you been using ie.Quit, before the End Sub, to close off instances each time you run your code? Check how many InternetExplorer instances you have running for starters.
Use a proper page load wait of:
While ie.Busy Or ie.readyState < 4: DoEvents: Wend
Then you could also try
ie.Navigate2 "http://myweb.com" & ie.Document.querySelector("#ctl00_ContentPlaceHolder1_tcSearchRoute_tabSearchRoute2_ibtnSearchR2").src
While ie.Busy Or ie.readyState < 4: DoEvents: Wend
Or just retry you existing line.
You can try to create and set IE object like below.
Set ie = CreateObject("InternetExplorer.Application")
or try
Dim ie As SHDocVw.InternetExplorer
Set ie = New InternetExplorerMedium
or try
Set ie = GetObject("new:{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}")
You can try adding one of these wait loops after you set your IE object or anytime the IE page changes/refreshes.
Set ie = CreateObject("InternetExplorer.Application")
Do While ie.readyState <> READYSTATE_COMPLETE
DoEvents
Loop
While ie.busy
DoEvents
Wend
Do While IE.ReadyState = 4: DoEvents: Loop
Do Until IE.ReadyState = 4: DoEvents: Loop
Further, you can try to disable the enable enhanced protected mode option in IE settings.
Go to Tools-> IE options -> Advanced tab -> Security section - disable
"enable enhanced protected mode".
Reference:
VBA Error: The object invoked has disconnected from its clients
I want to download an Excel file from an url.
Unfortunately, I only have the url that contains the "download button", because once I click the button, the url isn't .../file.xls but one, if I go to, will not activate the download process.
Is there were a way with VBA go to this url and click on the button to download the file.
Dim IE As InternetExplorer
Sub Test()
' Create InternetExplorer Object
Set IE = CreateObject("InternetExplorer.Application")
' You can uncoment Next line To see form results
IE.Visible = True
' Send the form data To URL As POST binary request
IE.navigate "http://webpage.com/"
' Wait while IE loading...
While IE.Busy
DoEvents
Wend
Set objInputs = IE.Document.getElementsByTagName("link")
For Each ele In objInputs
If ele.Title Like "List of control sheets having one or more declared Then alert(s)." Then 'Text on the link
ele.Click
End If
Next
End Sub
However, I think the object I'm aiming at is more like a link than a button, because in the source, there are only several lines of these:
<LINK rel=stylesheet type=text/css href="/frm/wdk/theme/documentum/css/webforms.css">
you can use this to access the page using IE:
Dim ie As Object
Set ie = CreateObject("InternetExplorer.application")
With ie
.Visible = True
.Navigate ("http://yourlink")
While .Busy Or .ReadyState <> 4: DoEvents: Wend
End With
And then use the command SendKeys "{TAB}", True to go to the button and the command SendKeys "{ENTER}", True to click on it
I am trying to download a table of proprietary investments/positions/pricing from Nationwide. The code seems to do what I want, EXCEPT for producing an "object required" error when I attempt to select a particular account (click)
I thought I had the proper code to tell my macro to wait until IE was ready to go on, but clearly I am missing something.
In the code, the relevant line is highlighted. If I enter a STOP above the error line, I can wait until I "see" the link appear, then "continue" the code and it runs as expected.
Because this goes to my financial accounts, I cannot provide the user name and password to allow someone to replicate the exact problem, but here is the code, and the error message and highlight. Suggestions appreciated.
Option Explicit
'set Reference to Microsoft Internet Controls
Sub DownLoadFunds()
Dim IE As InternetExplorer
Dim sHTML
Const sURL As String = "https://www.nationwide.com/access/web/login.htm"
Const sURL2 As String = "https://isc.nwservicecenter.com/iApp/isc/app/ia/balanceDetail.do?basho.menuNodeId=12245"
Dim wsTemp As Worksheet
Set wsTemp = Worksheets("Scratch")
Set IE = New InternetExplorer
With IE
.Navigate sURL
.Visible = True 'for debugging
Do While .ReadyState <> READYSTATE_COMPLETE
DoEvents
Loop
Do While .Busy = True
DoEvents
Loop
'Login: User Name and Password "remembered" by IE
.Document.all("submitButton").Click
Do While .ReadyState <> READYSTATE_COMPLETE
DoEvents
Loop
Do While .Busy = True
DoEvents
Loop
'Select this account to show
.Document.all("RothIRA_#########").Click '<--Error at this line
Do While .ReadyState <> READYSTATE_COMPLETE
DoEvents
Loop
Do While .Busy = True
DoEvents
Loop
.Navigate sURL2
Do While .ReadyState <> READYSTATE_COMPLETE
DoEvents
Loop
Do While .Busy = True
DoEvents
Loop
Set sHTML = .Document.GetElementByID("fundByFundOnly")
With wsTemp
.Cells.Clear
.Range("a2") = sHTML.innertext
End With
.Quit
End With
Set IE = Nothing
End Sub
This is the error message:
This shows the highlighted line:
EDIT:
At Tim Williams suggestion, I added a loop to test for the presence of the desired element. This seems to work:
...
On Error Resume Next
Do
Err.Clear
DoEvents
Application.Wait (Time + TimeSerial(0, 0, 1))
.Document.getelementbyid("RothIRA_#########").Click
Loop Until Err.Number = 0
On Error GoTo 0
....
IE.Document.all("#RothIRA_....") is returning Nothing (null in more refined languages), so calling the Click method is causing the error.
Your code is the same as doing this:
Dim rothElement As Whatever
rothElement = IE.Document.all("#RothIRA_....")
rothElement.Click
...when you should do this:
Dim rothElement As Whatever
rothElement = IE.Document.all("#RothIRA_....")
If rothElement <> Nothing Then
rothElement.Click
End If
I suggest using the modern document.GetElementById method instead of the deprecated (if not obsolete) document.All API.
It's possible/likely that the page is using script to dynamically load some content or generate some layout after your "wait" loop has finished. That loop only waits until all linked content/resources have been loaded - it does not wait for scripts on the loaded page to finish, etc.
One approach is to loop your code waiting for the desired element to be rendered:
Const MAX_WAIT_SEC as Long = 5 'limit on how long to wait...
Dim t
t = Timer
Do While .Document.all("RothIRA_#########") Is Nothing
DoEvents
'or you can Sleep here
If Timer - t > MAX_WAIT_SEC Then Exit Do
Loop
'carry on...