VBA to Activate Internet Explorer Window - vba

I'm making a macro that opens Internet Explorer, navigates and logs into a website. Everything works fine, but I need to bring the IE Window up front, and activate it, so I can use SendKeyson it.
I've found websites and videos with different approaches on a command called AppActivate and i've tried many of them, but even if I copy the entire code (which works for the author) it won't work for me, I always get an error: Invalid Procedure Call or Argument - Error 5
A list of everything I've found and tried:
Dim objIE As InternetExplorerMedium
Set objIE = New InternetExplorerMedium
objIE.navigate "http://google.com"
'makes it visible, but not active
objIE.Visible = True
'A list of ways I've tried:
objIE.AppActivate "Google - Internet Explorer"
AppActivate "Google - internet Explorer"
'the above supposedly looks for the title of the page
AppActivate objIE
AppActivate (objIE)
AppActivate "objIE"
observations: I'm running this inside Excel 2013 and I'm using Windows 7 with IE 11.

I always just make IE an untyped object, like so
Sub test()
Dim IE As Object
Set IE = Nothing
Set IE = CreateObject("InternetExplorer.Application")
IE.Navigate "www.google.com"
IE.Visible = True
End Sub
The IE window has focus when this finishes running on my end.

Someone write similar things here:
Get existing IE via VBA
With a little modification: (SetForegroundWindow Lib "user32" )
So that after it search for the Existing IE, it will appear on the top of our screen
*PtrSafe / LongPtr is to be used in 64-bit system
*You may delete it if you are using 32-bit
Call Library
Public Declare PtrSafe Function SetForegroundWindow Lib "user32" (ByVal HWND As LongPtr) As LongPtr
Main Sub
Sub Test1()
Dim IE1 As Object
Set IE1 = ThisIE
IE1.navigate "http://stackoverflow.com"
Do While IE1.readyState <> READYSTATE_COMPLETE
Loop
SetForegroundWindow (IE1.HWND)
End Sub
Function to be called
Function ThisIE() As Object
For Each ThisIE In CreateObject("Shell.Application").Windows()
If (Not ThisIE Is Nothing) And ThisIE.Name = "Internet Explorer" Then Exit For
Next ThisIE
If ThisIE Is Nothing Then Set ThisIE = CreateObject("InternetExplorer.Application")
ThisIE.Visible = True
End Function

Related

Find value stored in IE object in VBA

I have declared an object named IE in my VBA code.
Set IE = CreateObject("InternetExplorer.Application")
Sometimes user may close the browser linked to IE object. How can i write code to find if the browser is closed or open?
As shown in below image, software shows Internet Explorer when i place cursor on IE object during run time. Can this value be used to determine if browser is closed or open? If not, any other way?
Create a custom class to capture the Internet Explorer events using WithEvents. You'll need to set a reference to Microsoft Internet Controls.
Option Explicit
Private WithEvents IE As InternetExplorer
Private Sub IE_OnQuit()
End Sub
Private Sub IE_OnVisible(ByVal Visible As Boolean)
End Sub
Private Sub Class_Initialize()
Set IE = New InternetExplorer
End Sub
If the object is closed, then accessing some of it's members should give you an error.
Dim isOpen As Boolean ' False by default
On Error Resume Next
If IE.HWND > 0 Then isOpen = True
On Error Goto 0

Controlling IE11 "Do you want to Open/Save" dialogue window buttons in VBA

We need to download file from a NASDAQ website automatically. My existing VBA code is opening an IE "Do you want to Open/Save" dialogue window. How to click on that save button and give a path via VBA ?
I have tried various windows api methods described in this link here also but that is giving a result of "Window Not Found".
My current code is as below:
Sub MyIEauto()
Dim ieApp As InternetExplorer
Dim ieDoc As Object
'Dim ieTable As Object
'create a new instance of ie
Set ieApp = New InternetExplorer
'you don’t need this, but it’s good for debugging
ieApp.Visible = True
'assume we’re not logged in and just go directly to the login page
ieApp.Navigate "https://indexes.nasdaqomx.com/Account/LogOn"
Do While ieApp.Busy: DoEvents: Loop
Do Until ieApp.readyState = READYSTATE_COMPLETE: DoEvents: Loop
Set ieDoc = ieApp.Document
'fill in the login form – View Source from your browser to get the control names
With ieDoc.forms(0)
.UserName.Value = "xxxxxxx"
.Password.Value = "xxxxxxx"
.submit
End With
Do While ieApp.Busy: DoEvents: Loop
Do Until ieApp.readyState = READYSTATE_COMPLETE: DoEvents: Loop
'now that we’re in, go to the page we want
ieApp.Navigate "https://indexes.nasdaqomx.com/Index/ExportWeightings/NDX?tradeDate=2015-08-19T00:00:00.000&timeOfDay=SOD/SODWeightings_2015"
'next below line commented as it is failing
'ieApp.ExecWB 4, 2, "D:\VBA code work\SODWeightings_20150819_NDX.xlsx"
set ieApp=Nothing
set ieDoc=Nothing
End Sub
The screenshot below shows where I have reached. How do I progress from here?
It's solved finally...
Option Explicit
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
(ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, _
ByVal lpsz2 As String) As Long
Public Sub AddReference()
ThisWorkbook.VBProject.References.AddFromFile "C:\Windows\SysWOW64\UIAutomationCore.dll"
End Sub
'after my original code as posted in question then this below lines
Dim o As IUIAutomation
Dim e As IUIAutomationElement
Set o = New CUIAutomation
Dim h As Long
h = ieApp.hWnd
h = FindWindowEx(h, 0, "Frame Notification Bar", vbNullString)
If h = 0 Then Exit Sub
Set e = o.ElementFromHandle(ByVal h)
Dim iCnd As IUIAutomationCondition
Set iCnd = o.CreatePropertyCondition(UIA_NamePropertyId, "Save")
Dim Button As IUIAutomationElement
Set Button = e.FindFirst(TreeScope_Subtree, iCnd)
Dim InvokePattern As IUIAutomationInvokePattern
Set InvokePattern = Button.GetCurrentPattern(UIA_InvokePatternId)
InvokePattern.Invoke
Another way to do this is to send the keystrokes of the shortcut keys to click the save button in IE11. I should note your IE window will need to be the active window for this to work. Thus, it won't work while in debug mode.
The code below calls the shortcut key. I'm just showing the shortcut key so you have a better idea what's happening.
Shortcut key:Alt+S
VBA: Application.SendKeys "%{S}"
as ieApp.hWnd in a 64bit environment is LongLong, where h is Long
this yields a Type Mismatch which can easily been solved by
h = Clng(ieApp.hWnd)
SendKeys was the solution for me.
myfile = "C:\Users\User\Downloads\myfile.xls"
checkmyfile = Dir(myfile, vbArchive)
Do While checkmyfile = ""
On Error Resume Next
checkmyfile = Dir(myfile , vbArchive)
If checkmyfile = "myfile.xls" Then Exit Do
AppActivate "Title - Internet Explorer"
SendKeys "%(g)"
Application.Wait Now + TimeValue("0:0:1")
Loop

VBA IE automation, To trigger some action in VBA before whenever i navigate to other page in website

I need a VBA code which can do some action in VBA when the webpage frame is just about to navigate to other page.for example when i click on some link,button it navigates to other page i want to take screen shot of the page before frame navigates to other.i have done something like this but it is taking screen shot of the blank page and its only working for onetime as the page is navigated and object gets changed. please help me with this i have been searching for this since 2 weeks help me.
Sub pageLoad()
Set ie2 = GetIE("https://xyz.com")
Dim LinkFound As Boolean
Dim linkCollection
Dim IEfr0 As Object
i = 0
Dim Link As MSHTML.HTMLAnchorElement
'HTMLInputElement
Set wordapp = CreateObject("word.Application")
wordapp.Visible = True
Set wrdDoc = wordapp.Documents.Add
Set IEfr0 = ie2.document.frames(0).document
Set linkCollection = IEfr0.getElementsByTagName("a")
Do While ie2.Visible = True
For Each Link In linkCollection
If ie2.document.frames(2).document.readyState = "interactive" Then
sai1
End If
If IEfr0.readyState = 1 Then
sai1
End If
Next
Loop
End Sub
Sub sai1()
Application.SendKeys "{PRTSC}"
wordapp.Selection.Paste
Do While ie2.Busy
Loop
End Sub
Here's a possible solution. Only showing you how to create the object and specify the BeforeNavigate2 event. This requires you to reference Microsoft Internet Controls and create the IE object (this will not work with late binding). This code must be in an object module (worksheet or workbook) because you cannot use WithEvents in a standard module.
Option Explicit
Dim WithEvents ie As InternetExplorer
Sub Example()
Set ie = New InternetExplorer
ie.Visible = True
ie.Navigate "Your URL Here..."
Do Until ie.ReadyState = READYSTATE_COMPLETE: DoEvents: Loop
End Sub
Private Sub ie_BeforeNavigate2(ByVal pDisp As Object, URL As Variant, Flags As Variant, TargetFrameName As Variant, PostData As Variant, Headers As Variant, Cancel As Boolean)
'Place code to run before navigating here.
End Sub
An issue you may see with this is that for some websites, the BeforeNavigate2 event will actually fire multiple times due to additional calls for resources when loading.

taking control of an open browser instance

Set Browser = New SHDocVw.InternetExplorer
Once you create a new browser instance, how do you refer to that instance, instead of closing and reopening, say If I activate Excel window, then I want to activate back to the browser, how is this done?
I looked into
AppActivate "Windows Internet Explorer"
But If I have more than one window open, that wont work right, I dont think
I think you mean:
Option Explicit
Public browser As SHDocVw.InternetExplorer
Sub NavigateTo()
Set browser = New SHDocVw.InternetExplorer
browser.Visible = True
browser.Navigate "http://stackoverflow.com"
End Sub
In other words, declare the browser variable at module level so it remains available.
You can also capture an instance like so:
Sub getIE()
Dim sh As Object, oWin As Object, IE As Object
Set sh = CreateObject("Shell.Application")
For Each oWin In sh.Windows
If TypeName(oWin.Document) = "HTMLDocument" Then
Set IE = oWin
Exit For
End If
Next
Debug.Print IE.Document.url
End Sub

IE 9 not accepting SendKeys

I posted on IE 9 not accepting SendKeys to download a file, but this problem is separate enough from the answer I received to justify another question. My problem is that I can't get IE 9 to accept any of the SendKeys. I have attempted Page Down, Tab, all of the F# keys, and none of them work.
Here is the code I am using:
Dim ie As Object
'This creates the IE object
Sub initializeIE()
'call this subprocedure to start internet explorer up
Set ie = CreateObject("internetexplorer.application")
pos = 1
End Sub
'Initialize the class object
Private Sub Class_Initialize()
initializeIE
End Sub
Function followLinkByText(thetext As String) As Boolean
'clicks the first link that has the specified text
Dim alink As Variant
'Loops through every anchor in html document until specified text is found
' then clicks the link
For Each alink In ie.document.Links
If alink.innerHTML = thetext Then
alink.Click
'waitForLoad
Application.Wait Now + TimeValue("00:00:01")
Application.SendKeys "{PGDN}", True
Application.SendKeys "{PGUP}", True
'I've also tried calling it without Application before it
SendKeys "{F1}", True
SendKeys "{F2}", True
'Etc... Each of these not being received by IE 9
followLinkByText = True
Exit Function
End If
Next
End Function
I'm at a total loss because it seems like most forums or tutorials don't do anything different for IE 9. The IE object is created in a class module and initialized in the Class_Initialize sub. I am not sure if that helps any, but I really have no idea why this isn't working and any help on how to send keys to IE would be greatly appreciated.
This is actually a copy of my answer to this question, but it may still apply.
Is the IE window active when you try your SendKeys? If not, this would explain it not working.
To activate your window:
At the beginning of your module, put this line of code:
Public Declare Function SetForegroundWindow Lib "user32" (ByVal HWND As Long) As Long
This will allow you to access the SetForegroundWindow function built into Windows.
In your code, while interacting with your IE object, record the HWND for that window like so:
Dim HWNDSrc As Long
HWNDSrc = ie.HWND
Then after you've loaded the page, use this to continue, then send your key actions:
SetForegroundWindow HWNDSrc
However, this may not be necessary, depending on how you are interacting with IE. In other words, if you don't need to see/touch the window (you do for SendKeys), you can still interact using the object in code.
Now, I see you using Application.Wait after you click, but that does not guarantee the IE page has loaded. This function should help with that.
Public Sub WaitForIE(myIEwindow As InternetExplorer, HWND As Long, WaitTime As Integer)
' Add pauses/waits so that window action can actually
' begin AND finish before trying to read from myIEWindow.
' myIEWindow is the IE object currently in use
' HWND is the HWND for myIEWindow
' The above two variables are both used for redundancy/failsafe purposes.
' WaitTime is the amount of time (in seconds) to wait at each step below.
' This is variablized because some pages are known to take longer than
' others to load, and some pages with frames may be partially loaded,
' which can incorrectly return an READYSTATE_COMPLETE status, etc.
Dim OpenIETitle As SHDocVw.InternetExplorer
Application.Wait DateAdd("s", WaitTime, Now())
Do Until myIEwindow.ReadyState = READYSTATE_COMPLETE
' Wait until IE is done loading page and/or user actions are done.
Loop
Application.Wait DateAdd("s", WaitTime, Now())
While myIEwindow.Busy
DoEvents ' Wait until IE is done loading page and/or user actions are done.
Wend
On Error Resume Next
' Make sure our window still exists and was not closed for some reason...
For Each OpenIETitle In objShellWindows
If OpenIETitle.HWND = HWND Then
If Err.Number = 0 Then
Set myIEwindow = OpenIETitle
Exit For
Else
Err.Clear
End If
End If
Next OpenIETitle
On Error GoTo 0
End Sub
At the risk of being long-winded, I've updated your code with these suggestions...
' Added by Gaffi
Public Declare Function SetForegroundWindow Lib "user32" (ByVal HWND As Long) As Long
Dim HWNDSrc As Long
Dim ie As Object
'This creates the IE object
Sub initializeIE()
'call this subprocedure to start internet explorer up
Set ie = CreateObject("internetexplorer.application")
' Added by Gaffi
HWNDSrc = ie.HWND
pos = 1
End Sub
'Initialize the class object
Private Sub Class_Initialize()
initializeIE
End Sub
Function followLinkByText(thetext As String) As Boolean
'clicks the first link that has the specified text
Dim alink As Variant
'Loops through every anchor in html document until specified text is found
' then clicks the link
For Each alink In ie.document.Links
If alink.innerHTML = thetext Then
alink.Click
'waitForLoad
' Added by Gaffi
WaitForIE ie, HWNDSrc, 1
SetForegroundWindow HWNDSrc
'Application.Wait Now + TimeValue("00:00:01")
Application.SendKeys "{PGDN}", True
Application.SendKeys "{PGUP}", True
'I've also tried calling it without Application before it
SendKeys "{F1}", True
SendKeys "{F2}", True
'Etc... Each of these not being received by IE 9
followLinkByText = True
Exit Function
End If
Next
End Function