Controlling IE11 “Do you want to Open/Save” VBA - vba

I have issues with a code I am writing on VBA. I am basically using vba to open a website, input information and then click a download button, which downloads a csv that I can then copy and put onto my excel file. I do manage to get everything done up to the clicking download button. When I do that a Dialogue window shows up for IE11 asking me whether I want to save or open the file. I have no idea how solve this issue and how to click open or save. I have tryed everything mentioned in a solution for the same problem in Controlling IE11 "Do you want to Open/Save" dialogue window buttons in VBA , but even though I use this solution, the code runs but just does not do anything.
I have tried using the UIAutomation but I have been unsuccessful . I used the solution provided in Controlling IE11 "Do you want to Open/Save" dialogue window buttons in VBA. I have also tried using Sendkeys but I am not entirely sure how to set the focus on Internet explorer so that the sendkeys do what they are supposed to.
Code is actually very simple
Sub GetHTMLDocument()
Dim ie As New SHDocVw.InternetExplorer
Dim HTMLDoc As HTMLDocument
Dim HTMLInput As MSHTML.IHTMLElement
Dim HTMLButtons As MSHTML.IHTMLElementCollection
Dim HTMLButton As MSHTML.IHTMLElement
ie.Visible = True
ie.Navigate "this is where i put the website"
Do While ie.ReadyState <> READYSTATE_COMPLETE
Loop
Set HTMLDoc = ie.Document
Set HTMLInput = HTMLDoc.getElementById("Search")
HTMLInput.Value = "Hello"
Set HTMLInput = HTMLDoc.getElementById("downloadCSV")
HTMLInput.Click
End Sub
Unfortunately I cannot give the website and I cannot use a public one, after that I get the message whether to open or save it on internet explorer

Possible duplicate of VBA interaction with internet explorer
Though this answer may be more clear for this specific question.
1) add this to top of your module - It creates a function that will allow you to give any window focus. I have no idea on the details.
Public Declare Function SetForegroundWindow Lib "user32" (ByVal HWND As Long) As Long
2) Modify this code to taste in order to use SendKeys
'give IE focus to prepare for SendKeys
' IE.HWND = the handle of the Windows Internet Explorer main window.
Dim HWNDSrc As Long
HWNDSrc = IE.HWND
SetForegroundWindow HWNDSrc
'Make sure IE is not busy
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
'send Alt-S to save
Application.SendKeys "%{S}"
'Make sure IE is not busy
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop

Related

Bring Internet Explorer Download Window to Focus - Foreground via VBA

I've got a macro which currently works but I'm trying to automate the final "quirk" that I have had to live with up till now. Basically it opens IE to a URL which then closes the window and spits back a download window and I have excel use SENDKEYS to download file.
I'm struggling to bring the download window to focus, currently my end users click on the DL window for sendkeys to work as expected.
I have read through the following and tried utilizing the code to no avail:
vbscript - Bring Internet Explorer Application window to front
VBA to Activate Internet Explorer Window
Bringing Internet Explorer window to foreground
Set Focus to Internet Explorer Object in Visual Basic
There a few things to note:
I can't download the file via batch as I need IE to pass along the credentials.
The file is not static, the URL runs a script on the backend and then presents the file back to end terminal
I can't have any requirement to "Enable Reference Library" on end users computers
The macro is as follows:
Public Sub DLFILE()
'This will load a webpage in IE
Dim i As Long
Dim URL As String
Dim ie As Object
Dim objElement As Object
Dim objCollection As Object
'Create InternetExplorer Object
Set ie = CreateObject("InternetExplorer.Application")
'Define URL
URL = "http://example.com/"
'Navigate to URL
ie.navigate URL
' Statusbar let's user know website is loading
Application.StatusBar = URL & " is loading. Please wait..."
'IE ReadyState = 4 signifies the webpage has loaded (the first loop is set to avoid inadvertently skipping over the second loop)
Do While ie.ReadyState = 4: DoEvents: Loop 'Do While
Application.Wait (Now() + TimeValue("00:00:04"))
SendKeys "{RIGHT}{RIGHT}{ENTER}{TAB}{TAB}{TAB}{TAB}{ENTER}"
'Do Until IE.ReadyState = 4: DoEvents: Loop 'Do Until
'Unload IE
Set ie = Nothing
Set objElement = Nothing
Set objCollection = Nothing
End Sub
Also note, this doesn't bring up the prompt in the bottom of the IE window, but closes that window and brings up the "Full Downloads Window" like below.
As the shortcut for the "View Downloads" window is Ctrl+J in IE so I think we can use sendkeys to click Ctrl+J to bring the window to the front.
Sample code:
Sub LOADIE()
Set ieA = CreateObject("InternetExplorer.Application")
ieA.Visible = True
ieA.navigate "https://www.bing.com/"
Do Until ieA.readyState = 4
DoEvents
Loop
Application.Wait (Now + TimeValue("00:00:03"))
Application.SendKeys "^{j}"
End Sub
Result:
What I ended up doing was using an ObjURL to open the IE instance and then a DLUrl which I opened after. This made a few important adjustments, it's similar to opening a second tab in IE which would close, but instead of using the "Downloads Window" it would use the prompt at the bottom of the IE Window. This allowed me to continue to control the IEObj as the original ObjURL was still open. I couldn't get excel VBA to consistently control the "Downloads Window", but I was able to get consistent results using the following snippets. Between the two adjustments I now have consistent results.
Public Declare Function SetForegroundWindow Lib "user32" (ByVal HWND As Long) As Long
And
'Bring IEObj to Focus
HWNDSrc = IEObj.HWND
SetForegroundWindow HWNDSrc
Full Sub:
Public Declare Function SetForegroundWindow Lib "user32" (ByVal HWND As Long) As Long
Public Sub DL_File_IE()
Dim DLUrl As String, ObjURL As String
Dim IEObj As Object, objElement As Object, objCollection As Object
Set IEObj = CreateObject("InternetExplorer.Application")
IEObj.Visible = True
ObjURL = "http://google.com"
DLUrl = "http://example.com/file
IEObj.navigate ObjURL
Do Until IEObj.readyState = 4
DoEvents
Loop
IEObj.navigate DLUrl
'Bring IEObj to Focus
HWNDSrc = IEObj.HWND
SetForegroundWindow HWNDSrc
Application.Wait (Now() + TimeValue("00:00:02"))
SendKeys "{TAB}{TAB}{ENTER}", True ' Select "Save" in DL Window
Application.Wait (Now() + TimeValue("00:00:02"))
SendKeys "%{f4}", True ' Alt + F4 = Close IEObj
'Unload IE
Set IEObj = Nothing
Set objElement = Nothing
Set objCollection = Nothing
End Sub

Get an active IE window by partial URL

I currently am running some VBA to navigate an intranet site, perform some actions, etc. I have completed the actions I need to take, and now I have 2 IE windows open. One window, my original, I want to remain open. The second window, I want to close.
I have been having issues closing the second window. Using simple SendKeys "%{F4}" doesn't close the window at all, although it would if I did the steps manually rather than through VBA. Also, ieApp.Quit keeps closing the first IE window, which I want to remain open to use again. Which is strange because it isn't the active window at the time.
My question is...is there a way to find/select an open IE window based on a partial URL? I know the URL will start with http://ctdayppv02/PVEShowDocPopup.aspx? but everything after that will change each time.
I've seen plenty online about launching IE with a URL, or returning the URL of an already open IE instance, but I'm not trying to do either of those at this point. I just want to activate a specific open IE window, so then I can close that one only.
Here is part of my code, which isn't closing anything as of now, but also doesn't result in any errors. It's the very last part that doesn't work, everything else is good.:
'***** Click the Search button *****
ieApp.Document.all.Item("btnSubmitProjectSearch").Click: DoEvents: Sleep 1000
'***** Click the Print button *****
ieApp.Document.all.Item("printLink").Click: DoEvents: Sleep 1000
'***** Setting variables for Windows API. Will be used to find the proper windows box by name *****
Dim windowHWND As LongPtr
Dim buttonHWND As LongPtr
Dim hwnd As String
Dim hwindow2 As String
''***** Will click the Print button. MUST HAVE MICROSOFT PDF AS DEFAULT PRINTER *****
windowHWND = getWindowPointer("Print", "#32770")
If windowHWND > 0 Then
'***** Add a small delay to allow the window to finish rendering if needed *****
Sleep 250
buttonHWND = FindWindowEx(windowHWND, 0, "Button", "&Print")
If buttonHWND > 0 Then
SendMessage buttonHWND, BM_CLICK, 0, 0
Else
Debug.Print "didn't find button!"
End If
End If
'***** Locate the "Save Print Output As" window, enter the filepath/filename and press ENTER *****
hwnd = FindWindow(vbNullString, "Save Print Output As")
Do
DoEvents
hwindow2 = FindWindow(vbNullString, "Save Print Output As")
Loop Until hwindow2 > 0
SendKeys "C:\Users\NAME\Documents\" & Range("G2").Value
SendKeys "{ENTER}"
'***** Locate the Viewer Control box that appears after saving and press ENTER to advance *****
hwnd = FindWindow(vbNullString, "PaperVision Document Viewer Control")
Do
DoEvents
hwindow2 = FindWindow(vbNullString, "PaperVision Document Viewer Control")
Loop Until hwindow2 > 0
SendKeys "{Enter}"
'***** Locate the "PaperVision - View Document" IE window and close it *****
hwnd = FindWindow(vbNullString, "PaperVision - View Document - Internet Explorer")
Do
DoEvents
hwindow2 = FindWindow(vbNullString, "PaperVision - View Document - Internet Explorer")
Loop Until hwindow2 > 0
'ieApp.Quit
SendKeys "%{F4}"
Any advice on how to close just that one page? Thanks in advance!
As per the first suggestion by QHarr, try...
Option Explicit
Sub test()
Dim oShell As Object
Dim oShellWindows As Object
Dim oShellWindow As Object
Dim sPartialURL As String
sPartialURL = "http://ctdayppv02/PVEShowDocPopup.aspx?"
Set oShell = CreateObject("Shell.Application")
Set oShellWindows = oShell.Windows
For Each oShellWindow In oShellWindows
If oShellWindow.Name = "Internet Explorer" Then
If InStr(oShellWindow.Document.URL, sPartialURL) > 0 Then
Exit For
End If
End If
Next oShellWindow
If Not oShellWindow Is Nothing Then
'Do stuff
'
'
oShellWindow.Quit
Else
MsgBox "The specified Internet Explorer window was not found!", vbExclamation
End If
Set oShell = Nothing
Set oShellWindows = Nothing
Set oShellWindow = Nothing
End Sub
I like Domenic's response more, but I wanted to post another way I came across online for anybody who may be looking at this down the road and wants another method.
This way uses a function that is called in the primary sub. The "View Document" is the wording that appears in the IE window caption, NOT in the URL. This will close any IE that contains that specific phrase somewhere in the window caption. I only tested this a few times but it seems to work.
Sub CloseWindow()
Do Until Not CloseIeIf("View Document"): Loop
End Sub
Function CloseIeIf(Str As String) As Boolean
Dim ie As Object
For Each ie In CreateObject("Shell.Application").Windows
If InStr(ie.LocationName, Str) <> 0 Then
ie.Quit
CloseIeIf = True
End If
Next
End Function

VBA with Excel and IE: Can't get the source right source code?

I'm currently trying to automate my IE at work with VBA and Excel, because we have some repetitive tasks to complete in an SAP System which is called within the Internet Explorer.
So far I am able to start IE and navigate to the starting page of our System.
I looked on the source code from the Sap System to search for an id from a div (lets say its 'SampleID'). But if I try to click it via VBA I only get returned 'nothing'. So I tried to print out the source code via VBA Debug.Print to look at the problem. And here's the thing:
The source code that gets printed is completely different from the Website's Source Code. In the printed code for example is a iframe that I can't find in the website source code. So that's the reason I can't find my div and any other objects, because they are not in the code that VBA is searching through.
Can anyone tell me what's going wrong? Why are the source codes completely different?
Sub stgGo(){
Dim i As Long
Dim IE As InternetExplorerMedium
Dim objElement As Object
Dim objCollection As Object
Set IE = New InternetExplorer
IE.Visible = True
IE.Navigate ("URL")
'waiting 10 seconds to be really sure javascript is ready
Application.Wait (Now + TimeValue("0:00:10"))
'printing out the false source code
Debug.Print strHTML = myIE.Document.body.innerHTML
Set objCollection = IE.document.getElementsByTagName("div")
i = 0
While i < objCollection.Length
If objCollection(i).ID = "SampleID" Then
objCollection(i).Click
End If
i = i + 1
Wend
End Sub

VBA - how to use google form on IE.navigate with process in the background

I'm currently using the following code to open an IE instance and navigate a complete-with-answers google form link. By accessing this link, the google form is immediately answered by the "entry.1102259784=XXXX" strings.
Private Sub Workbook_Open()
Application.ScreenUpdating = False
Dim IE As Object
Call Usernames
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = False
IE.Silent = True
IE.Navigate Cells(7, 1)
While IE.Busy
DoEvents
Wend
IE.Quit
Set IE = Nothing
End Sub
Its quite simple and works well (hidden and fast) except for this particular instance (google forms), as the IE opens and just stands there with the "Your form has been submitted" webpage on display.
The idea is to submit information about who is opening the file and when to a google spreadsheet.
I would appreciate any help on this matter.
Thank you very much!

vba can not find opening IE 11 Browser.

I have a vba code which can upload the data from an excel sheet to a website. However, the code works fine in Win7 System and IE browser 8,but it does not work on a win8 IE browser 11.
Here are part of the code:
Dim objIE As SHDocVw.InternetExplorer
Dim htmlDoc As MSHTML.HTMLDocument
Dim htmlFrame As MSHTML.HTMLFrameElement
Dim frame As HTMLIFrame
Dim htmlElement As HTMLDTElement
Dim myDoc As Object
Set curSheet = ActiveWorkbook.ActiveSheet
Set oShApp = CreateObject("Shell.Application")
For Each oWin In oShApp.Windows
If oWin.Name = "Windows Internet Explorer" Then
Set IE = oWin
Exit For
End If
Next
If IE Is Nothing Then
MsgBox ("Please sign into Avocado, then re-run this macro")
Set IE = New InternetExplorerMedium
IE.Visible = True
IE.navigate "https://www.google.com"
Exit Sub
End If
Sheets("Prepare").Select
fPathName = Cells(5, 5)
Call MakeFolders(fPathName)
Call MakeFolders2(fPathName)
Call MakeFolders3(fPathName)
'fFileName = fPathName & "\*.xls"
fFileName = Dir(fPathName & "\*.xls")
The code runs in a loop when enters the statement : "If IE Is Nothing Then"
Even when the google site is opened, the program still keeps prompting out the msgBox, and reopen the website again and again, and it never executes to the last part "Sheets("Prepare").Select". I am very confused because it works perfect in the IE 8 browsers. I am wondering if there is any difference between IE11 and IE8 in terms of vba IE function.
Please take a look up it and give me some ideas on this, your help is greatly appreciated. Thank you very much.
I ran into the identical problem and found, that the window name of the shell.application has changed in IE 11. Earlier versions had the name "Windows Internet Explorer", but IE 11 uses only "Internet Explorer"
If you change your if condition accordingly, it will work again ...
I think you are using an old version of internet explorer. Use the code I provided bellow and see if it works. Please make sure you have the following references added to your project:
Microsoft HTML Object Library
Microsoft Internet Controls.
If you are not sure how to add the references to your code check out this link.External References
Sub Test()
Dim objIE As InternetExplorer
Dim htmlDoc As HTMLDocument
Dim htmlFrame As HTMLFrameElement
Dim frame As HTMLIFrame
Dim htmlElement As HTMLDTElement
Dim myDoc As Object
Dim curSheet As Worksheet
' Set the variables
Set curSheet = ActiveWorkbook.ActiveSheet
Set objIE = New InternetExplorer
' Make the browser visible and navigate
With objIE
.Visible = True
.navigate "https://www.google.com"
End With
WaitForInternetToLoad objIE
Sheets("Prepare").Select
fPathName = Cells(5, 5).Value
Call MakeFolders(fPathName)
Call MakeFolders2(fPathName)
Call MakeFolders3(fPathName)
'fFileName = fPathName & "\*.xls"
fFileName = Dir(fPathName & "\*.xls")
End Sub
Sub WaitForInternetToLoad(ByRef ie As InternetExplorer)
Do
dovents
Loop While Not ie.readyState = READYSTATE_COMPLETE
End Sub
Extra Information.
Hi I see you are having some trouble with this and I want to extend my help.
Let's start by the fact that you are using two external libraries in your code; and you should have references set to them for the code to work properly. See my picture I have highlighted the libraries yellow.
What are the differences:
Microsoft Internet Controls
Is the one that takes care of the internet object. It creates an internet explorer application and it navigates to certain links. Once it finishes navigating to the url then " internet object" has a "document". This object cannot do anything else.
Microsoft HTML Object Library
This library takes care of the Html document. And as you probably guessed you will assign the "document" from the previous object (internet explorer) to a HTML document variable and then you can do further manipulation.