VBA - losing control of internet exploror - ms-access

I have a function that loads a website prompting a user to login. This works on everyone's computers except one person and I cannot figure it out. I get a runtime error on the line Do Until ieApp.ReadyState = 4: DoEvents: Loop that reads "Automation error. The object invoked has disconnected from its clients."
Function Firewall_Login() As Boolean
Dim ieApp As Object
Dim ieDoc As Object
Dim ieTable As Object
Dim ieDocResult As Object
Dim start_time
Set ieApp = CreateObject("internetexplorer.application")
start_time = Now()
ieApp.Navigate "http://awebsite.com/"
Do While ieApp.ReadyState = 4: DoEvents: Loop
Do Until ieApp.ReadyState = 4: DoEvents: Loop 'errors here just on the one computer
Set ieDoc = ieApp.Document
...
'do some stuff
...
ieDoc.Close
Set ieDoc = Nothing
ieApp.Quit
Set ieApp = Nothing
Firewall_Login = True
End Function
Seems like the object ieApp simply loses the instance of IE and can't do anything. Anyone have any suggestions?
All users are on the same version of IE -- 11.0.9600.18816

This code is taken from my blog. The code loops through shell windows looking to match the title bar which for IE will be the url. This way the reference is reacquired. Sometimes the reference can be lost due to a change of security zone etc.
Option Explicit
'* Tools - References
'* MSHTML Microsoft HTML Object Library C:\Windows\SysWOW64\mshtml.tlb
'* SHDocVw Microsoft Internet Controls C:\Windows\SysWOW64\ieframe.dll
'* Shell32 Microsoft Shell Controls And Automation C:\Windows\SysWOW64\shell32.dll
Private Function ReacquireInternetExplorer(ByVal sMatch As String) As Object
Dim oShell As Shell32.Shell: Set oShell = New Shell32.Shell
Dim wins As Object: Set wins = oShell.Windows
Dim winLoop As Variant
For Each winLoop In oShell.Windows
If "C:\Program Files (x86)\Internet Explorer\IEXPLORE.EXE" = winLoop.FullName Then
Dim sFile2 As String
sFile2 = "file:///" & VBA.Replace(sMatch, "\", "/")
If StrComp(sFile2, winLoop.LocationURL, vbTextCompare) = 0 Then
Set ReacquireInternetExplorer = winLoop.Application
GoTo SingleExit
End If
End If
Next
SingleExit:
End Function

Related

How to deal with Hidden Elements on VBA Selenium [duplicate]

I am trying to automate a report through VBA. I have worked in VBA but not able to login in iTunes website through codes. Someone told me that it is written in IFrame, but i have no idea. Even i am not able to put my username in input box of login page.
https://itunesconnect.apple.com/login
Dim HTMLdoc As HTMLDocument
Dim MyBrowser As InternetExplorer
Sub check()
Dim MyHTML_element As IHTMLElement
Dim MyURL As String
MyURL = "https://itunesconnect.apple.com/login"
Set MyBrowser = New InternetExplorer
MyBrowser.Silent = True
MyBrowser.navigate MyURL
MyBrowser.Visible = True
Do
Loop Until MyBrowser.readyState = READYSTATE_COMPLETE
Set HTMLdoc = MyBrowser.document
HTMLdoc.getElementsByID("account_name_text_field").Value = "username#outlook.com"
HTMLdoc.all.Password.Value = "password"
For Each MyHTML_element In HTMLdoc.getElementsByTagName("input")
If MyHTML_element.Type = "sign-in" Then MyHTML_element.Click: Exit For
Next
Err_Clear:
If Err <> 0 Then
Err.Clear
Resume Next
End If
End Sub
API sounds like a good idea. The whole page is very slow loading (for me at least) and there is an iframe to navigate.
I would go with selenium basic wrapper for vba and switch to the iframe. I will try to improve this when I have time but for now this works.
After installing selenium you will need to add a reference via VBE > Tools > References to Selenium Type library.
Option Explicit
Public Sub EnterInfo()
Dim d As WebDriver, t As Date, ele As Object
Set d = New ChromeDriver
Const URL = "https://itunesconnect.apple.com/login"
Const WAIT_TIME_SECS As Long = 30
t = Timer
With d
.Start "Chrome"
.get URL
Do
DoEvents
If Timer - t > WAIT_TIME_SECS Then Exit Do
On Error Resume Next
.SwitchToFrame "aid-auth-widget-iFrame"
Set ele = .FindElementByCss("#account_name_text_field")
On Error GoTo 0
Loop While ele Is Nothing
If ele Is Nothing Then Exit Sub
ele.SendKeys "Joe.Bloggs#aol.com"
.FindElementByCss("#sign-in").Click
'Other code....
Stop '<=Delete me later
.Quit
End With
End Sub

Can we fetch the specific data via using urls in vba

I have 15 different URLs, and I need to fetch price from the particular website in Excel a particular column, can you please help me out. It's my first VBA program and I try but it show my syntax error.
Sub myfile()
Dim IE As New InternetExplorer Dim url As String Dim item As
HTMLHtmlElement Dim Doc As HTMLDocument Dim tagElements As Object
Dim element As Object Dim lastRow Application.ScreenUpdating =
False Application.DisplayAlerts = False Application.EnableEvents =
False Application.Calculation = xlCalculationManual url =
"https://wtb.app.channeliq.com/buyonline/D_nhoFMJcUal_LOXlInI_g/TOA-60?html=true"
IE.navigate url IE.Visible = True Do DoEvents Loop Until
IE.readyState = READYSTATE_COMPLETE
Set Doc = IE.document
lastRow = Sheet1.UsedRange.Rows.Count + 1 Set tagElements =
Doc.all.tags("tr") For Each element In tagElements
If InStr(element.innerText, "ciq-price")> 0 And
InStr(element.className, "ciq-product-name") > 0 Then
Sheet1.Cells(lastRow, 1).Value = element.innerText
' Exit the for loop once you get the temperature to avoid unnecessary processing
Exit For End If Next
IE.Quit Set IE = Nothing Application.ScreenUpdating = True
Application.DisplayAlerts = True Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
End Sub
You can't copy any web scraping macro for your purposes. Every page has it's own HTML code structure. So you must write for every page an own web scraping macro.
I can't explain all about web scraping with VBA here. Please start your recherche for information with "excel vba web scraping" and "document object model". Further you need knowlege about HTML and CSS. In best case also about JavaScript:
The error message user-defined type not defined ocours because you use early binding without a reference to the libraries Microsoft HTML Object Library and Microsoft Internet Controls. You can read here how to set a reference via Tools -> References... and about the differences between early and late binding Early Binding v/s Late Binding and here deeper information from Microsoft Using early binding and late binding in Automation
To get the prices from the shown url you can use the following macro. I use late binding:
Option Explicit
Sub myfile()
Dim IE As Object
Dim url As String
Dim tagElements As Object
Dim element As Object
Dim item As Object
Dim lastRow As Long
lastRow = ActiveSheet.UsedRange.Rows.Count + 1
url = "https://wtb.app.channeliq.com/buyonline/D_nhoFMJcUal_LOXlInI_g/TOA-60?html=true"
Set IE = CreateObject("internetexplorer.application")
IE.navigate url
IE.Visible = True
Do: DoEvents: Loop Until IE.readyState = 4
Set tagElements = IE.document.getElementsByClassName("ciq-online-offer-item ")
For Each element In tagElements
Set item = element.getElementsByTagName("td")(1)
ActiveSheet.Cells(lastRow, 1).Value = Trim(item.innerText)
lastRow = lastRow + 1
Next
IE.Quit
Set IE = Nothing
End Sub
Edit for a second Example:
The new link leads to an offer. I assume the price of the product is to be fetched. No loop is needed for this. You just have to find out in which HTML segment the price is and then you can decide how to get it. In the end there are only two lines of VBA that write the price into the Excel spreadsheet.
I'm in Germany and Excel has automatically set the currency sign from Dollar to Euro. This is of course wrong. Depending on where you are, this may have to be intercepted.
Sub myfile2()
Dim IE As Object
Dim url As String
Dim tagElements As Object
Dim lastRow As Long
lastRow = ActiveSheet.UsedRange.Rows.Count + 1
url = "https://www.wayfair.com/kitchen-tabletop/pdx/cuisinart-air-fryer-toaster-oven-cui3490.html"
Set IE = CreateObject("internetexplorer.application")
IE.navigate url
IE.Visible = True
Do: DoEvents: Loop Until IE.readyState = 4
'Break for 3 seconds
Application.Wait (Now + TimeSerial(0, 0, 3))
Set tagElements = IE.document.getElementsByClassName("BasePriceBlock BasePriceBlock--highlight")(0)
ActiveSheet.Cells(lastRow, 1).Value = Trim(tagElements.innerText)
IE.Quit
Set IE = Nothing
End Sub

How to resolve runtime error when trying to execute Element.Click command

I am attempting to run a macro that clicks on an IE webpage to download a file. When running my macro I encounter Runtime Error 91: Object variable or with block variable not set I removed my url string for security purposes
The line that is highlighted is Element.Click How can I resolve this
Sub Playthissub()
Call Scrape("myurl") '' change the website here and execute this sub.
End Sub
Sub Scrape(url As String)
Dim Browser As InternetExplorer
Dim Document As HTMLDocument
Dim Elements As IHTMLElementCollection
Dim Element As HTMLGenericElement
Set Browser = New InternetExplorerMedium
Browser.Visible = True
Browser.Navigate url
Do While Browser.Busy And Not Browser.readyState = READYSTATE_COMPLETE
DoEvents
Loop
Set Document = Browser.Document
Set Elements = Document.getElementsByTagName("navPipeline")
Element.Click
Browser.Quit
End Sub

Excel VBA code to click web button

Need help how to create excel vba code for this
I'll be needing the codes so I can complete my macro.
Thanks in advance
First, you will need to create a reference to:
Microsoft Internet Controls
Microsoft HTML Object Library
In VBE, click Tools > References
Sub clickLink()
Dim ie As New InternetExplorer, Url$, doc As HTMLDocument
Url = "http://UrlToYourLink.com"
With ie
.navigate Url
Do While .Busy Or .readyState < READYSTATE_COMPLETE
DoEvents
Loop
doc = .document
.Visible = True
End With
Dim myBtn As Object
Set myBtn = doc.getElementsByClassName("button rounded")(0)
myBtn.Click
End Sub
The Internet control is used to browse the webpage and the HTML Objects are used to identify the username and password textboxes and submit the text using the control button.
Dim HTMLDoc As HTMLDocument
Dim oBrowser As InternetExplorer
Sub Login_2_Website()
Dim oHTML_Element As IHTMLElement
Dim sURL As String
On Error GoTo Err_Clear
sURL = "https://www.google.com/accounts/Login"
Set oBrowser = New InternetExplorer
oBrowser.Silent = True
oBrowser.timeout = 60
oBrowser.navigate sURL
oBrowser.Visible = True
Do
' Wait till the Browser is loaded
Loop Until oBrowser.readyState = READYSTATE_COMPLETE
Set HTMLDoc = oBrowser.Document
HTMLDoc.all.Email.Value = "sample#vbadud.com"
HTMLDoc.all.passwd.Value = "*****"
For Each oHTML_Element In HTMLDoc.getElementsByTagName("input")
If oHTML_Element.Type = "submit" Then oHTML_Element.Click: Exit For
Next
' oBrowser.Refresh ' Refresh If Needed
Err_Clear:
If Err <> 0 Then
Debug.Assert Err = 0
Err.Clear
Resume Next
End If
End Sub
The program requires references to the following:
1 Microsoft Internet Controls
2. Microsoft HTML Object Library
Microsoft internet controls are a great way to do this, but if you aren't allowed to add new references, here is another way to go about web scraping.
This methode ain't as 'clean' as Microsoft internet controls and HTML object but it gets the job done.
Sub GoogleSearch()
Dim ie As Object
Dim objSearchBnt As Object
Dim objCollection As Object
Dim i As Integer
'initialize counter
i = 0
'Create InternetExplorer Object
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = True
'navigate to the url
ie.navigate "Www.google.com"
'Statusbar shows in the buttom corner of excel
Application.StatusBar = "Loading, please wait..."
'Wait until page is ready
Do While ie.busy
Application.Wait DateAdd("s", 1, Now)
Loop
'Store all the elements with input tag
Set objCollection = ie.Document.getElementsByTagName("input")
'Go through all input elements
While i < objCollection.Length
'input search field
If objCollection(i).Name = "q" Then
objCollection(i).Value = "Hello World"
End If
'search button
If objCollection(i).Type = "submit" Then
Set objSearchBnt = objCollection(i)
End If
i = i + 1
Wend
objSearchBnt.Click
'Clean up
Set objSearchBnt = Nothing
Set objCollection = Nothing
Set ie = Nothing
'Give excel control over the status bar agian
Application.StatusBar = ""
End Sub

VBA Grab data from webpage into variable

I am able to pass the excel values to the website and click it through vba. But it opens up another page with title "Results - Research Randomizer" and I dont know how I retrieve those values inside "Set#1". Can anyone give me some idea to retrieve those values into a variable. My code is
Sub OpenPage()
Const myPageTitle As String = "Research Randomizer Form v4.0"
Const myPageURL As String = "http://www.randomizer.org/form.htm"
Dim NoofSet, NoPSet, RangeBeg, RangeEnd As String
NoofSet = Range("b3").Value
NoPSet = Range("c3").Value
RangeBeg = Range("d3").Value
RangeEnd = Range("e3").Value
Dim myIE As SHDocVw.InternetExplorer
Dim doc As HTMLDocument
Dim PageForm As HTMLFormElement
Dim UserIdBox As HTMLInputElement
Dim PasswordBox As HTMLInputElement
Dim HrangeBeg, HrangeEnd As HTMLInputElement
Dim FormButton As HTMLInputButtonElement
Dim Elem As IHTMLElement
'check if page is already open
Set myIE = GetOpenIEByTitle(myPageTitle, False)
If myIE Is Nothing Then
'page isn't open yet
'create new IE instance
Set myIE = GetNewIE
'make IE window visible
myIE.Visible = True
'load page
If LoadWebPage(myIE, myPageURL) = False Then
'page wasn't loaded
MsgBox "Couldn't open page"
Exit Sub
End If
End If
Do
DoEvents
Loop Until myIE.readyState = READYSTATE_COMPLETE
Set doc = myIE.document
Set PageForm = doc.forms(0)
'Get the User Id textbox
'< input class="TextBox" maxlength="15" name="UserName" size="12">
Set UserIdBox = PageForm.elements("numofsets")
'Set the User Id
UserIdBox.Value = NoofSet
'Get the password textbox
'< input class="TextBox" type="password" maxlength="10" name="Password" size="12">
Set PasswordBox = PageForm.elements("numperset")
'Set the password
PasswordBox.Value = NoPSet
Set HrangeBeg = PageForm.elements("rangebeg")
HrangeBeg.Value = RangeBeg
Set HrangeEnd = PageForm.elements("rangeend")
HrangeEnd.Value = RangeEnd
'Submit the form (like clicking the 'Submit' button) to navigate to next page
PageForm.Button.Click
'Wait for the new page to load
Do
DoEvents
Loop Until myIE.readyState = READYSTATE_COMPLETE
myIE.Visible = True
'Working fine till here
'Need to pull the data from the 2nd webisite
End Sub
'returns new instance of Internet Explorer
Function GetNewIE() As SHDocVw.InternetExplorer
'create new IE instance
Set GetNewIE = New SHDocVw.InternetExplorer
'start with a blank page
GetNewIE.Navigate2 "about:Blank"
End Function
'loads a web page and returns True or False depending on
'whether the page could be loaded or not
Function LoadWebPage(i_IE As SHDocVw.InternetExplorer, _
i_URL As String) As Boolean
With i_IE
'open page
.navigate i_URL
'wait until IE finished loading the page
Do While .readyState <> READYSTATE_COMPLETE
Application.Wait Now + TimeValue("0:00:01")
Loop
'check if page could be loaded
If .document.URL = i_URL Then
LoadWebPage = True
End If
End With
End Function
'finds an open IE site by checking the URL
Function GetOpenIEByURL(ByVal i_URL As String) As SHDocVw.InternetExplorer
Dim objShellWindows As New SHDocVw.ShellWindows
'ignore errors when accessing the document property
On Error Resume Next
'loop over all Shell-Windows
For Each GetOpenIEByURL In objShellWindows
'if the document is of type HTMLDocument, it is an IE window
If TypeName(GetOpenIEByURL.document) = "HTMLDocument" Then
'check the URL
If GetOpenIEByURL.document.URL = i_URL Then
'leave, we found the right window
Exit Function
End If
End If
Next
End Function
'finds an open IE site by checking the title
Function GetOpenIEByTitle(i_Title As String, _
Optional ByVal i_ExactMatch As Boolean = True) As SHDocVw.InternetExplorer
Dim objShellWindows As New SHDocVw.ShellWindows
If i_ExactMatch = False Then i_Title = "*" & i_Title & "*"
'ignore errors when accessing the document property
On Error Resume Next
'loop over all Shell-Windows
For Each GetOpenIEByTitle In objShellWindows
'if the document is of type HTMLDocument, it is an IE window
If TypeName(GetOpenIEByTitle.document) = "HTMLDocument" Then
'check the title
If GetOpenIEByTitle.document.Title Like i_Title Then
'leave, we found the right window
Exit Function
End If
End If
Next
End Function
This code will find and identify the open "Results" window and then assign the source code behind it to a variable (my_var). You can then extract what you want from the variable.
' Find the open instance of IE that contains the "Results"
Set objShell = CreateObject("Shell.Application")
IE_count = objShell.Windows.Count
For x = 0 To (IE_count - 1)
On Error Resume Next
my_url = objShell.Windows(x).document.Location
my_title = objShell.Windows(x).document.Title
If my_title Like "Results - Research Randomizer" Then
Set ie = objShell.Windows(x)
Exit For
Else
End If
Next
my_var = ie.document.body.innerhtml