Scott
Scott

Reputation: 191

VBA to click IE11 Save As dialogue in Win7x64

I'm trying to get VBA to automate saving a file from IE. Thanks to various posts on these forums, I can login, navigate pages, and click the download link. The Save prompt appears at the bottom of IE, then I'm stuck:

IE11 Save Dialogue

I've been trying to use the code samples from https://www.mrexcel.com/forum/excel-questions/502298-need-help-regarding-ie-automation-using-vba-post3272730.html#post3272730, but the second FindWindow always returns 0:

hWnd = FindWindowEx(hWnd, 0, "DUIViewWndClassName", vbNullString) 

I'm using VBA 7.0 in Excel 14, and IE11.

There is advice at the top of the original post:

'Note - IE may block the download, displaying its Information Bar at the top of the tab, and preventing this program from 'automatically downloading the file. To prevent this, add NRLDC to IE's Trusted sites (Tools - Internet Options - 'Security - Trusted sites - Sites)

I can't access the trusted sites list due to IT policy, but the download prompt appears, so I don't think this is the issue.

The code I've taken is from Doongie's reply, which indicates it's updated for Windows 7:

Private Sub File_Download_Click_Save()

    Dim hWnd As Long
    Dim timeout As Date

    Debug.Print "File_Download_Click_Save"

    'Find the File Download window, waiting a maximum of 30 seconds for it to appear

    timeout = Now + TimeValue("00:00:30")
    Do
        hWnd = FindWindow("#32770", "") 'returns various numbers on different runs: 20001h 10440h
        DoEvents
        Sleep 200
    Loop Until hWnd Or Now > timeout

    Debug.Print "   File Download window "; Hex(hWnd)

    If hWnd Then
        SetForegroundWindow hWnd

        'Find the child DUIViewWndClassName window
        hWnd = FindWindowEx(hWnd, 0, "DUIViewWndClassName", vbNullString)    'always returns 0
        Debug.Print "   DUIViewWndClassName "; Hex(hWnd)
    End If

    If hWnd Then
        'Find the child DirectUIHWND window
        hWnd = FindWindowEx(hWnd, 0, "DirectUIHWND", "")
        Debug.Print "   DirectUIHWND "; Hex(hWnd)
    End If

    If hWnd Then
        'Find the child FloatNotifySink window
        hWnd = FindWindowEx(hWnd, 0, "FloatNotifySink", "")
        Debug.Print "   FloatNotifySink "; Hex(hWnd)
    End If

    If hWnd Then
        'Find the child ComboBox window
        hWnd = FindWindowEx(hWnd, 0, "ComboBox", "")
        Debug.Print "   ComboBox "; Hex(hWnd)
    End If

    If hWnd Then
        SetForegroundWindow hWnd

        'Find the child Edit window
        hWnd = FindWindowEx(hWnd, 0, "Edit", "")
        Debug.Print "   Edit "; Hex(hWnd)
    End If

    If hWnd Then        
        'Click the Save button
        SetForegroundWindow hWnd
        Sleep 600  'this sleep is required and 600 milliseconds seems to be the minimum that works
        SendMessage hWnd, BM_CLICK, 0, 0
    End If

End Sub

Is there any way (that won't get me in trouble with IT!) that I can inspect the handle numbers of the IE elements? Code inspector only shows me the page code, not IE dialogues.

Is there a list of possible element names for lpsz1 defined somewhere, as they apply to elements of IE?

Public Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
    (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long

Upvotes: 2

Views: 3331

Answers (3)

Ricardo A
Ricardo A

Reputation: 1815

You could try the urlmon library. Change the url and file name + extension to what you need to.

It will probably not work on a website where you have to log in to get to the file.

Public Declare Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" (ByVal pCaller As Long, _
    ByVal szURL As String, ByVal szFileName As String, ByVal dwReserved As Long, _
    ByVal lpfnCB As Long) As Long
Public Function DownloadFile(URL As String, LocalFilename As String) As Boolean
    Dim errValue As Long
    errValue = URLDownloadToFile(0, URL, LocalFilename, 0, 0)
    If errValue = 0 Then
        MsgBox "Download Completed, saved at: " & LocalFilename
    Else
        MsgBox "There was an error downloading the file"
    End If
End Function
Sub DoIt()
    DownloadFile "http://www.blahblahblah.com/somefolder/somefiles.xlsx", "C:\Users\Public\Documents\SavedFile.xlsx"
End Sub

Upvotes: 0

QHarr
QHarr

Reputation: 84475

Have you tried the dreaded sendkeys?

Application.SendKeys "%{S}"
Application.SendKeys "%{O}"

Upvotes: 1

nagarajannd
nagarajannd

Reputation: 715

In my IE Automation used below code to save file from IE. Below code requires VBA reference to UIAutomationCore.dll and can be found at

%windir%/sysWow64/UIAutomationCore.dll

and enable trust access to vba by

File -> Options -> Trust Center -> Trust Center Settings -> Macro Settings -> Check Trust access to the VBA

Private Sub InvokeSaveButton(IEHwnd As Long)
Dim o As IUIAutomation
Dim e As IUIAutomationElement
Set o = New CUIAutomation
Dim h As Long
h = IEHwnd
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
End Sub

Upvotes: 0

Related Questions