Hi I'm trying to dynamically create a web browser inside a spreadsheet and then use it but the WebBrowser functions don’t seem to work
Here is how I create the WebBrowser
Set myWebBrowser = Sheets("test").OLEObjects.Add(ClassType:="Shell.Explorer.2", Link:=False, DisplayAsIcon:=False, left:=147, top:=60.75, width:=141, height:=96)
This will work
myWebBrowser.top = 10
But this will give me an error
myWebBrowser.Navigate ("about:blank")
Any ideas on what should I do thank you
UPDATE:
This will also don't work and give an error:
myWebBrowser.Object.Document.body.Scroll = "no"
myWebBrowser.Object.Silent = True
myWebBrowser.Object.Navigate ("about:blank")
While myWebBrowser.Object.ReadyState <> READYSTATE_COMPLETE
Application.Wait (Now + TimeValue("0:00:01"))
Wend
myWebBrowser.Object.Refresh
UPDATE 2 (almost there):
Now I need a way to remove the Sheet2.Activate Sheet1.Activate
Sheet2.Activate
Sheet1.Activate
Set wb = myWebBrowser.Object
With wb
.Silent = True
.Navigate "about:blank"
Do While .ReadyState <> READYSTATE_COMPLETE
Application.Wait (Now + TimeValue("0:00:01"))
Loop
.Document.Open "text/html"
Do While .ReadyState <> READYSTATE_COMPLETE
Application.Wait (Now + TimeValue("0:00:01"))
Loop
.Document.write html
.Document.Close
.Document.body.Scroll = "no"
.Refresh
Debug.Print .Document.body.innerHTML
End With
myWebBrowser.Object.Navigate "http://www.google.com"
more complete example:
Sub AddWebBroswerToWorksheet()
Dim myWebBrowser
Dim wb, doc, x As Long
Sheet2.Activate
Sheet1.OLEObjects(1).Delete
Set myWebBrowser = Sheet1.OLEObjects.Add(ClassType:="Shell.Explorer.2", _
Left:=147, Top:=60.75, Width:=400, Height:=400)
Set wb = myWebBrowser.Object
With wb
.Navigate "about:blank"
.Document.Open "text/html"
For x = 1 To 100
.Document.write "hello world<br>"
Next x
.Document.Close
.Document.body.Scroll = "no"
Debug.Print .Document.body.innerHTML
End With
Sheet1.Activate 'switching back to the sheet seems to
' ' trigger the display of the object
End Sub
You need to pump Windows messages inside your WebBrowser.ReadyState <> READYSTATE_COMPLETE loop for this to work. Calling DoEvents/Sleep inside the loops does that, but has its own implications. Check these answers for further details and sample code:
https://stackoverflow.com/a/19019200/1768303
https://stackoverflow.com/a/19308865/1768303
Related
I'm working on VBA code in the last step to fill a web form. The problem is that the cell value which I passed to the date field does not match the format. Even if I try to pass string "yyyy-mm-dd".
When I click the field there is a popup calendar for picking up a date.
Below is my codes and web html and screenshot:
Error:
HTML Code:
Sub AuditBookings()
Dim IE As New SHDocVw.InternetExplorer
Dim HTMLDoc As MSHTML.HTMLDocument
Dim HTMLTable As MSHTML.IHTMLElement
Dim HTMLTables As MSHTML.IHTMLElementCollection
Dim i, j, n As Integer
Dim DataWs As Worksheet
Dim DataRange, CFRange As Range
Dim WebCF, WebCODate As String
IE.Visible = True
IE.navigate "https://xxx/ebkassembly/login.aspx"
Do While IE.readyState <> READYSTATE_COMPLETE Or IE.Busy
Loop
Set HTMLDoc = IE.document
If IE.LocationURL <> "https://xxx/Ebooking/Entry/Index2.aspx" Then 'check login URL
HTMLDoc.getElementById("userName").Value = ThisWorkbook.Worksheets("Menu").Range("B1").Value 'fill the username
HTMLDoc.getElementById("userPwd").Value = ThisWorkbook.Worksheets("Menu").Range("B2").Value 'fill the password
HTMLDoc.getElementById("accSubmit").Click
Do While IE.readyState <> READYSTATE_COMPLETE Or IE.Busy
Loop
Application.Wait (Now + TimeValue("0:00:10"))
IE.navigate "https://xxx/ebksettlement/HotelAudit/hotelAuditIndex.aspx"
Do While IE.readyState <> READYSTATE_COMPLETE Or IE.Busy
Loop
Application.Wait (Now + TimeValue("0:00:10"))
Else
IE.navigate "https://xxx/ebksettlement/HotelAudit/hotelAuditIndex.aspx"
Do While IE.readyState <> READYSTATE_COMPLETE Or IE.Busy
Loop
Application.Wait (Now + TimeValue("0:00:10"))
End If
Set DataWs = ThisWorkbook.Worksheets("CtripReport")
DataWs.Activate
i = 1
Set HTMLTable = HTMLDoc.getElementById("pendingtb")
n = HTMLTable.Children(0).Children.Length 'get QTY of unaudited bookings
For i = i To n - 1
WebCF = HTMLTable.Children(0).Children(i).Children(7).all(0).innerText 'get confirmation number from web
If WebCF <> "" Then
Set DataRange = DataWs.Range("K2", "K" & n) 'set search range
Set CFRange = DataRange.Find(what:=WebCF, lookat:=xlPart)'start matching
If Not CFRange Is Nothing Then
CFRange.Select
HTMLTable.Children(0).Children(i).Children(1).all(5).Click 'click check-out button
Application.Wait (Now + TimeValue("0:00:02"))
'HTMLTable.Children(0).Children(i).Children(3).all(3).Value = CFRange.Offset(0, -4).Value ' fill check-out date
HTMLTable.Children(0).Children(i).Children(3).all(3).Click
HTMLTable.Children(0).Children(i).Children(3).all(3).Value = "2019-08-27"
HTMLTable.Children(0).Children(i).Children(4).all(1).innerText = CFRange.Offset(0, -3).Value ' fill guest name
HTMLTable.Children(0).Children(i).Children(6).all(0).Value = CFRange.Offset(0, -1).Value ' fill room number
'HTMLTable.Children(0).Children(i).Children(7).all.innerText = CFRange.Value ' fill confirmation number
'HTMLTable.Children(0).Children(i).Children(9).all(1).Click ' click save button
End If
End If
Next
'MsgBox "Total " & ThisWorkbook.Worksheets("CtripReport").Range("A2", Range("A1").End(xlDown)).Count & " records are scraped"
End Sub
For some reason I am not able to access elements inside iframe.
I have tried:
ie.Document.getElementById("sisaltosivu").contentDocument.getElementById("uusihaku")(0).Click
Here is my code:
Sub ChechAutomate()
Dim ie As New InternetExplorer, url As String, ws As Worksheet
Set ws = ThisWorkbook.Sheets("Other Data")
url = "https://www.asiakastieto.fi/data/atdb"
With ie
.Visible = True
.Navigate2 url
While .Busy Or .ReadyState < 4: DoEvents: Wend
With .Document
If .querySelectorAll("#btnb").Length > 0 Then
Else
.querySelector("[name=user1]").Value = "x"
.querySelector("[name=user2]").Value = "x"
.querySelector("[name=passwd]").Value = "x"
.querySelector("[class=btnb]").Click
Application.Wait (Now + TimeValue("00:00:01"))
ie.Navigate2 "https://www.asiakastieto.fi/sopimusasiakas/kotimaa?lang=FI"
Application.Wait (Now + TimeValue("00:00:01"))
ie.Document.getElementById("sisaltosivu").contentDocument.getElementById("uusihaku")(0).Click
End If
End With
End With
End Sub
You are no longer outside the iframe when you navigate to the src of the iframe. This line:
ie.Navigate2 "https://www.asiakastieto.fi/sopimusasiakas/kotimaa?lang=FI"
should mean you are now in the document referenced within the iframe and should access direct with:
.document.getElementById("uusihaku")(0).Click
I have a problem when trying to scrape data from website. It is Run-time error '424': Object required
My code:
Option Explicit
Sub GetData()
Dim IE As New SHDocVw.InternetExplorer
IE.Visible = True
IE.Navigate "abc.com"
Do While IE.ReadyState <> READYSTATE_COMPLETE
Loop
IE.Document.forms("vinSearchForm").elements("vin").Value =
"******"
IE.Document.forms("vinSearchForm").elements("vinSearch").Click
Sheets("Sheet1").Select
Range("A10").Select
IE.Document.forms("vinSummaryForm").elements
("test_vinSummary_carSpecification_$4").Value = Range("A10").Value
End Sub
What I want is that to show result "2004*********" in Range("A10").
Pls kindly help me accordingly. Thanks.
Although not the best way but should work for you
Option Explicit
Sub Autocheck()
Dim IE As New SHDocVw.InternetExplorer
IE.Visible = True
IE.Navigate "Autocheck.com"
Do While IE.ReadyState <> READYSTATE_COMPLETE Or IE.Busy
DoEvents
Loop
Application.Wait Now + TimeSerial(0, 0, 5)
IE.Document.forms("vinSearchForm").elements("vin").Value = "JTDKB22U140021007"
IE.Document.forms("vinSearchForm").elements("vinSearch").Click
Do While IE.ReadyState <> READYSTATE_COMPLETE Or IE.Busy
DoEvents
Loop
Application.Wait Now + TimeSerial(0, 0, 5)
Range("A10").Value = Split(IE.Document.getelementbyid("test_vinSummary_carSpecification_$4").innerText, vbNewLine)(1)
IE.Quit
Set IE = Nothing
End Sub
I'm trying to click a button multiple times to get my page loaded fully. Webpage contains a button SHOW MORE instead of next page so in html coding behind the button remains same.
I am using the following excel-vba code to hit that button. It actually did click that button, but instead of showing the next results it shows the same result over and over again.
Could you please kindly show me how to make it right. Thanks in advance!
**' VARIABLE DECLARATION
Dim IE As Object
Dim county As String
Dim htmlDoc As Object
' CREATING OBJECT
Set IE = CreateObject("internetexplorer.application")
' WEBPAGE NAVIGATION
With IE
.navigate ("http://www.physiofirst.org.uk/find-physio/search-physio.html")
.Visible = True
End With
' WAITING FOR WEBPAGE TO LOAD
Do
DoEvents
Loop Until IE.readystate = 4
' SEARCHING ALL THE THE INDIVIDUAL STATE PHYSICIANS
Set htmlDoc = IE.document
Set searchbarvalue = htmlDoc.getelementsbyclassname("form-control mod-text-display")
i = 0
For Each classSearch In searchbarvalue
searchbarvalue(i).Value = "BRISTOL"
Next classSearch
While IE.busy
DoEvents
Wend
Set buttonclick = htmlDoc.getelementsbyclassname("btn btn-search")
i = 0
For Each buttonsearch In buttonclick
buttonclick(i).Click
Next buttonsearch
While IE.busy
DoEvents
Wend
Do
htmlDoc.getelementbyid("load-more-practice").Click
While IE.busy
DoEvents
Wend
Loop Until htmlDoc.getelementbyid("load-more-practice").Click = True
End Sub**
Try this code that Do Until data-page is = "1", because it starts on 2 and go to 1 when is completely loaded, with all Show More clicked.
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Sub test()
Dim IE As Object
Dim county As String
Dim htmlDoc As Object
Dim sURL As String
' CREATING OBJECT
Set IE = CreateObject("internetexplorer.application")
sURL = "http://www.physiofirst.org.uk/find-physio/search-physio.html"
' WEBPAGE NAVIGATION
With IE
.navigate (sURL)
.Visible = True
End With
WaitIE IE, 2000
' SEARCHING ALL THE THE INDIVIDUAL STATE PHYSICIANS
Set htmlDoc = IE.document
Set searchbarvalue = htmlDoc.getElementsByClassName("form-control mod-text-display")
i = 0
For Each classSearch In searchbarvalue
searchbarvalue(i).Value = "BRISTOL"
Next classSearch
WaitIE IE, 1000
Set buttonclick = htmlDoc.getElementsByClassName("btn btn-search")
buttonclick(0).Click
WaitIE IE, 1000
Set ShowMore = htmlDoc.getElementById("load-more-practice")
Do
ShowMore.Click
WaitIE IE, 2000
Loop Until ShowMore.getAttribute("data-page") = 1
'IE.Quit
'Set IE = Nothing
End Sub
Sub WaitIE(IE As Object, Optional time As Long = 250)
'Code from: https://stackoverflow.com/questions/33808000/run-time-error-91-object-variable-or-with-block-variable-not-set
Dim i As Long
Do
Sleep time
Debug.Print CStr(i) & vbTab & "Ready: " & CStr(IE.readyState = 4) & _
vbCrLf & vbTab & "Busy: " & CStr(IE.Busy)
i = i + 1
Loop Until IE.readyState = 4 Or Not IE.Busy
End Sub
Quick question I hope there is an easy answer.
I have a sub routine that navigates through a webpage. "Sub Navigate()"
Dim ie As Object
Set ie = CreateObject("internetexplorer.application")
ie.Visible = True
and so on.....
This part works fine and I successfully navigate through IE as needed. My next step comes from a separate sub routine "Sub copyimage()" I have designed where I pull images off the active page. However I cannot figure out how to use the open webpage for this.
The "Sub Copyimage()" sub works if I navigate directly to the URL within this sub. But I want to be able to get there from the work of my "Sub Navigate()" code.
I would like to be able to call the Copyimage() subroutine from the navigate() subroutine.
Please help
Here is full code from the first sub:
Sub FMSWebsite()
Dim strURL
Dim ie As Object
Set ie = CreateObject("InternetExplorer.Application")
strURL = "https://functionalmovement.com/login?return=%2F"
ie.Navigate strURL
ie.Visible = True
Do While (ie.Busy Or ie.READYSTATE <> 4)
DoEvents
Loop
ie.Document.forms(0).all("Username").Value = Worksheets("Cover").Range("E8")
ie.Document.forms(0).all("Password").Value = Worksheets("Cover").Range("E10")
Do While (ie.Busy Or ie.READYSTATE <> 4)
DoEvents
Loop
ie.Document.forms(0).submit
Do While (ie.Busy Or ie.READYSTATE <> 4)
DoEvents
Loop
Application.Wait (now + TimeValue("0:00:01"))
ie.Navigate ("http://functionalmovement.com/pro/clients")
Do While (ie.Busy Or ie.READYSTATE <> 4)
DoEvents
Loop
ie.Document.forms(1).all("gvClients$DXFREditorcol1").Value = Worksheets("Template").Range("X2")
ie.Document.forms(1).all("gvClients$DXFREditorcol1").Select
SendKeys String:="{enter}", Wait:=True
Application.Wait (now + TimeValue("0:00:03"))
Do While (ie.Busy Or ie.READYSTATE <> 4)
DoEvents
Loop
Dim e
For Each e In ie.Document.getElementsByTagName("strong")
If e.innerText = "Client Workouts" Then
e.ParentElement.Click
Exit For
End If
Next
Application.Wait (now + TimeValue("0:00:01"))
Do While (ie.Busy Or ie.READYSTATE <> 4)
DoEvents
Loop
For Each e In ie.Document.getElementsByTagName("span")
If e.innerText = "Create a New Workout" Then
e.ParentElement.Click
Exit For
End If
Next
Do While (ie.Busy Or ie.READYSTATE <> 4)
DoEvents
Loop
Application.Wait (now + TimeValue("0:00:01"))
For Each e In ie.Document.getElementsByTagName("span")
If e.innerText = "NEXT" Then
e.ParentElement.Click
Exit For
End If
Next
Do While (ie.Busy Or ie.READYSTATE <> 4)
DoEvents
Loop
Application.Wait (now + TimeValue("0:00:01"))
Set goBtn = ie.Document.getElementById("newscreen")
goBtn.Click
Application.Wait (now + TimeValue("0:00:01"))
Do While (ie.Busy Or ie.READYSTATE <> 4)
DoEvents
Loop
Fast Forward some code it ends like so:
For Each e In ie.Document.getElementsByTagName("span")
If e.innerText = "Complete" Then
e.ParentElement.Click
Exit For
End If
Next
Do While (ie.Busy Or ie.READYSTATE <> 4)
DoEvents
Loop
Application.Wait (now + TimeValue("0:00:03"))
Do While (ie.Busy Or ie.READYSTATE <> 4)
DoEvents
Loop
For Each e In ie.Document.getElementsByTagName("span")
If e.innerText = "View Assigned Workout" Then
e.ParentElement.Click
Exit For
End If
Next
End Sub
My next sub starts with
Sub findimageA ()
For Each Elem In ie.Document.getElementsByTagName("img")
If Elem.getAttribute("title") = "Step 1" Then
How do I reference the web address I ended with in the first sub?
I believe you have in Navigate() something like:
Dim ieDocument as Object
which represent a web page (web document). If so, you need to create Copyimage() subroutine with argument, like this:
Sub Copyimage(ieDocImages as object)
and call this sub from previous one passing document (ieDocument) as a parameter:
Call Copyimage(ieDocument)
or do something similar depending of variables you use.
EDIT, based on additional code in question
First sub- add the following line before End Sub or before you terminate ie object:
Call findimagA(ie.Document)
and change the second sub as follows:
Sub findimageA(ieDocument As Object)
For Each Elem In ieDocument.getElementsByTagName("img")
Not tested but I'm sure it is ok.