-1

I'm new with IE automation. Although I'm able to scrape data based on td/tr but I'm unable to get a click on the link to download the file.

How do I click on the link to download the file using VBA??

Inspect element of the link where I need to click on "download file":

 <div id = "export">
<imgsrc = "image url">
<a onclick = "core.essres.exportres();" href = "JavaScript: void (0);">"download file" </a>
QHarr
  • 83,427
  • 12
  • 54
  • 101
  • 2
    Good to know. • But what is your question? You didn't ask one. Please read [ask] and [mcve] then [edit] your question include what you have tried so far and improve it. – Pᴇʜ Apr 04 '19 at 06:29
  • Hi PEH, I have updated the question. Sorry I'm new to this forum. – learneronthego Apr 04 '19 at 06:35
  • Have you tried anything so far? Where is your initial attempt @learneronthego? – SIM Apr 04 '19 at 08:16

2 Answers2

0

Something like that

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

Declare PtrSafe Sub Sleep Lib "kernel32" _
    (ByVal dwMilliseconds As Long)

Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _
    (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr

Declare PtrSafe Function GetNextWindow Lib "user32" Alias "GetWindow" _
                (ByVal hWnd As LongPtr, ByVal wFlag As Long) As LongPtr

Declare PtrSafe Function SetForegroundWindow Lib "user32" _
    (ByVal hWnd As LongPtr) As Long

Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" _
    (ByVal hWnd As LongPtr, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Declare PtrSafe Function SendMessageByString Lib "user32" Alias "SendMessageA" _
    (ByVal hWnd As LongPtr, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long

Declare PtrSafe Function PostMessage Lib "user32" Alias "PostMessageA" _
    (ByVal hWnd As LongPtr, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Declare PtrSafe Sub keybd_event Lib "user32" _
    (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)


Public Const GHND = &H42
Public Const CF_TEXT = 1
Public Const MAXSIZE = 4096

Public Const BM_CLICK = &HF5
Public Const WM_SETTEXT = &HC
Public Const WM_GETTEXT = &HD
Public Const WM_GETTEXTLENGTH = &HE

Public Const VK_KEYDOWN = &H0
Public Const VK_KEYUP = &H2
Public Const VK_CONTROL = &H11

Public Const GW_HWNDNEXT = 2



Sub Download()
    Dim IeApp As InternetExplorer
    Dim IeDoc As Object
    Dim ieTable As Object
    Dim objElement As IHTMLElement
    ' here if you have problems with IE you must kill all IE windows
    'downloadF = Environ("USERPROFILE") & "\Downloads\"  ' this is your download folder
    Set IeApp = New InternetExplorer
        IeApp.Visible = True
        IeApp.Navigate "http://www.yoursite.com"
            Do Until IeApp.Busy = False And IeApp.readyState = READYSTATE_COMPLETE: DoEvents: Loop
        Set IeDoc = IeApp.Document
        IeDoc.GetElementById("export").click
        ' or IeDoc.GetElementById("export").FireEvent ("onclick") or else depending on page requerments
        Download_Default IeApp ' auto pressing Save button
        Application.Wait (Now + TimeValue("0:00:10")) ' wait for download
End Sub


Private Sub Download_Default(ByRef oBrowser As InternetExplorer)
 'AddReference
    Dim AutomationObj As IUIAutomation
    Dim WindowElement As IUIAutomationElement
    Dim Button As IUIAutomationElement
    Dim hWnd As LongPtr

    Set AutomationObj = New CUIAutomation

    Do While oBrowser.Busy: DoEvents: Loop  ' Or oBrowser.readyState <> 4
    Application.Wait (Now + TimeValue("0:00:05"))
    hWnd = oBrowser.hWnd
    hWnd = FindWindowEx(hWnd, 0, "Frame Notification Bar", vbNullString)
    If hWnd = 0 Then MsgBox " Not exist": Exit Sub

    Set WindowElement = AutomationObj.ElementFromHandle(ByVal hWnd)
        Dim iCnd As IUIAutomationCondition
        Set iCnd = AutomationObj.CreatePropertyCondition(UIA_NamePropertyId, "Save")
            Set Button = WindowElement.FindFirst(TreeScope_Subtree, iCnd)
                Dim InvokePattern As IUIAutomationInvokePattern
                Set InvokePattern = Button.GetCurrentPattern(UIA_InvokePatternId)
        InvokePattern.Invoke


End Sub
Dmitrij Holkin
  • 1,995
  • 3
  • 39
  • 86
0

Internet Explorer:

You can click using the id

ie.document.querySelector("#export").click

Or attribute = value selector

ie.document.querySelector("[onclick='core.essres.exportres();']").click

Or even try executing the onclick function direct

ie.document.parentWindow.execScript "core.essres.exportres();"

The other answer shows you how to handle the SaveAs dialog.


Direct download:

You could also use dev tools when clicking download to see if there is an url in the network tab associated with the download which you could pass direct to urlmon or binary download


Selenium:

You could switch to selenium vba and have a choice of browsers such as chrome, where you don't have the save/open dialog, where you can specify a default download location, or even just leave to download to your current default

Option Explicit
'download selenium https://github.com/florentbr/SeleniumBasic/releases/tag/v2.0.9.0
'Ensure latest applicable driver e.g. ChromeDriver.exe in Selenium folder
'VBE > Tools > References > Add reference to selenium type library
Public Sub DownloadFile()
    Dim d As WebDriver
    Set d = New ChromeDriver
    Const URL = "url"

    With d
        .Start "Chrome"
        .get URL
        .FindElementById("export").Click
        Application.Wait Now + TimeSerial(0, 1, 0) ' leave time to download before exiting or _
        loop download folder checking for when new file appears (or expected file by name/part of file name
        .Quit
    End With
End Sub
QHarr
  • 83,427
  • 12
  • 54
  • 101