0

I've got trouble saving a downloaded file in IE11 using a MS ACCESS macro.

This is where i want to click after i've been on the download link :

enter image description here

I need to log with a username / password to get on that page.

I'm currently using the SendKeys to get the file, and when i execute my macro manually, it works perfectly. However, when i launch my macro with a Windows planified task, Internet explorer loses the focus and the sendkeys execute on the desktop.

I tried several things, including :

-IE.Visible = true

-Execute the sendkeys with the Shell object

-tried Automation, but i can't make it work (i don't use the "sendkeys" anymore with that method). I saw there were several subjects on stack overflow that could help me, but i didn't succeded to make them work : Controlling IE11 "Do you want to Open/Save" dialogue window buttons in VBA or IE11 Frame Notification Bar Save button

-tried the download by link, but can't make it work

Here's my code, i've hidden important fields. Please excuse the french in the commentaries

Option Explicit
'Déclaration pour Sleep
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr) 'For 64 Bit Systems
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 'For 32 Bit Systems
#End If
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hWnd As Long) 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 Function Fct_Elemica()

        Dim IEObject                        As InternetExplorer  'Objet Internet Explorer
        Dim IEDoc                           As HTMLDocument      'Document HTML
        Dim Shell                           As Object  'Objet WSScript

        'Automations
        Dim o                               As IUIAutomation
        Dim e                               As IUIAutomationElement
        Dim iCnd                            As IUIAutomationCondition
        Dim Button                          As IUIAutomationElement
        Dim InvokePattern                   As IUIAutomationInvokePattern

        'Phase de login
        Dim InputLogin                      As HTMLInputElement  'Element HTML pour le controle du champ login
        Dim InputPassword                   As HTMLInputElement  'Element HTML pour le controle du champ password
        Dim SubmitButton                    As HTMLInputElement  'Element HTML pour le controle des boutons d'envoi de formulaire

        'Phase de generation du report
        Dim ProductSelection                As HTMLSelectElement 'Element HTML pour le controle du champ type de produit
        Dim DateEndSelection                As HTMLInputElement  'Element HTML pour le controle du champ date de fin

        'Phase de telechargement du lien
        Dim ObjLink                         As Object            'Element HTML pour le controle des liens href
        Dim strDownloadLink                 As String            'URL du fichier a telecharger

        'Variables parametrables
        Dim strDownloadFolder               As String
        Dim strLoginPageURL                 As String
        Dim strLogin                        As String
        Dim strPassword                     As String

        Dim HWNDSrc                         As Long
        Dim h                               As LongPtr
        Dim Child                           As LongPtr




        strDownloadFolder = Nz(DLookup("PAR_TXT_VAL", "tParam", "PAR_LIB = 'DOWNLOAD_PATH'"), "") 'Get the download path
        strLoginPageURL = "https://portal.elemica.com/jsp/index.jsp"                              'Get the link of the website
        strLogin = "**************"                                                               'Login
        strPassword = "***********"                                                               'Password


        'Instanciation de la varirable IE
        Set IEObject = CreateObject("InternetExplorer.Application")

        'Affichage de la fenetre IE
        IEObject.Visible = True



        'Chargement de la page de login du site elemica
        IEObject.Navigate strLoginPageURL

        'On attend le chargement complet de la page
        IE_LOADING_WAIT IEObject

        'On pointe la page courante
        Set IEDoc = IEObject.Document


        'On pointe nos differents controleurs
        Set InputLogin = IEDoc.all("username_id")
        Set InputPassword = IEDoc.all("passwordID")
        Set SubmitButton = IEDoc.all("submitbutton")

        'On definit le texte que l'on souhaite placer a l'interieur et on se loggue
        InputLogin.value = strLogin
        InputPassword.value = strPassword
        SubmitButton.Click

        'Chargement de la page Expeditions -> Tous
        IEObject.Navigate "https://portal.elemica.com/nav?cmd=SRAll&reset=1&groupSelected=-1"

        'On attend le chargement complet de la page
        IE_LOADING_WAIT IEObject

        'On repointe la page courante
        Set IEDoc = IEObject.Document

        'On entre les valeurs pour parametrer la sortie de l'extraction
        Set ProductSelection = IEDoc.getElementsByName("productGroupIDSelected")(0)
        Set DateEndSelection = IEDoc.getElementsByName("toDate")(0)
        Set SubmitButton = IEDoc.getElementsByName("btnView")(0)

        ProductSelection.value = "105"
        DateEndSelection.value = Format(Now() + 3, "dd/mm/yyyy")
        SubmitButton.Click


        'On attend le chargement complet de la page
        IE_LOADING_WAIT IEObject

        'On interrompt de rafraichissement dynamique
        IEObject.Stop

        'On recherche le l'adresse du lien "Telecharger dans Excel"
        For Each ObjLink In IEDoc.Links
            If ObjLink.innerText = "Télécharger dans Excel" Then
                strDownloadLink = ObjLink.href
            End If
        Next ObjLink

        'Navigate to the download link
        IEObject.Navigate strDownloadLink

        'Wait until the page is completely loaded
        IE_LOADING_WAIT IEObject

'        Set o = New CUIAutomation
'        h = IEObject.hWnd
'        Sleep 500
'        Child = FindWindowEx(h, 0, "Frame Notification Bar", vbNullString)
'        Set e = o.ElementFromHandle(ByVal h)
'
'        Set iCnd = o.CreatePropertyCondition(UIA_NamePropertyId, "&Apri")
'
'        Set Button = e.FindFirst(TreeScope_Subtree, iCnd)
'        Set InvokePattern = Button.GetCurrentPattern(UIA_InvokePatternId)
'        InvokePattern.Invoke

        Sleep 500
        SendKeys "^j"
        Sleep 500
        SendKeys "{RIGHT}"
        Sleep 500
        SendKeys "{RIGHT}"
        Sleep 500
        SendKeys "{RIGHT}"
        Sleep 500
        SendKeys "~"
        Sleep 500

        'Wait until the end of the download
        Sleep 20000

        'Close IE
        IEObject.Quit
        Shell ("taskkill /F /IM iexplore.exe")


        'Close vars
        Set InputLogin = Nothing
        Set InputPassword = Nothing
        Set SubmitButton = Nothing
        Set ProductSelection = Nothing
        Set DateEndSelection = Nothing
        Set IEDoc = Nothing
        Set IEObject = Nothing
        Set Shell = Nothing

End Function


Public Function IE_LOADING_WAIT(IEObject As InternetExplorer)

    'On boucle tant que la page n'est pas totalement chargee
    Do Until IEObject.ReadyState = READYSTATE_COMPLETE
        DoEvents
    Loop

End Function

Thanks in advance for your answers, have a good day !

braX
  • 11,506
  • 5
  • 20
  • 33
omnisius
  • 229
  • 5
  • 12
  • Check https://stackoverflow.com/a/24421350/9199828 – Foxfire And Burns And Burns May 06 '19 at 10:58
  • 1
    Have you considered using [selenium vba](https://github.com/florentbr/SeleniumBasic/releases/tag/v2.0.9.0)? So much easier when it comes to these tasks. You can use Chrome and avoid this hideous IE issue altogether, as well as specify download folder. – QHarr May 06 '19 at 10:58
  • First, thanks for your answers. I'm kinda new to the VBA, so i have no idea yet what selenium is yet, going to check your link. I can't use Chrome, because it's forbidden in the company i work in right now for security reasons. All i have is a VERY OLD version of firefox and the last version of IE 11. – omnisius May 06 '19 at 12:06

1 Answers1

1

You can try to refer steps and example code below and try to modify your code may help to solve the issue.

Copy file C:\Windows\System32\UIAutomationCore.dll file to users Documents i.e C:\Users\admin\Documents then add reference UIAutomationClient to your macro file.

Paste below code in your module:

    Option Explicit
    Dim ie As InternetExplorer
    Dim h As LongPtr
    Private 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

Sub Download()
    Dim o As IUIAutomation
    Dim e As IUIAutomationElement
    Set o = New CUIAutomation
    h = ie.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
End Sub   

Reference:

Automate saveas dialogue for IE9 (vba)

Deepak-MSFT
  • 10,379
  • 1
  • 12
  • 19
  • It's for IE9 right ? I use IE11. Will it work the same ? Going to try right anyway, thank you ! – omnisius May 06 '19 at 12:10
  • Actually, i realise that i already tried the solution you're giving me. When i reach this code : Set e = o.ElementFromHandle(ByVal h) There's nothing inside "e". But there's something in h. I added the reference you're asking me to add with this code : Sub MyUiAutomation() References.AddFromFile ("C:\Windows\SysWOW64\UIAutomationCore.dll") End Sub – omnisius May 06 '19 at 12:41
  • Did you try to copy that file to your documents folder and than try to add reference? If not than you can try to do that and again try to run the code to check the result. – Deepak-MSFT May 06 '19 at 13:26
  • The reference is well added, it's crossed in the reference pannel. I don't think the reference is the problem here. The thing is, the function "o.ElementFromHandle(ByVal h)" returns something empty. I'm searching why right now :) – omnisius May 06 '19 at 14:54
  • @omnisius, Did the issue solved? If not, can you please try to inform your current status about the issue? We will try to provide further suggestions. thanks for your understanding. – Deepak-MSFT May 13 '19 at 07:37
  • Hello, No, i'm currently continuing to find how i can do to solve my problem. If i happen to have updates on the situation, i'll post the solution i've found. What i'm trying right now is to use Selenium VBA and try the download possibilities in found in tutorial on youtube : youtube.com/watch?v=JPezrWwvsJM I think i'll re-write the code i've done. – omnisius May 13 '19 at 12:28
  • If you have any questions with your selenium test code than you can also try to create a new thread for it. We will try to check it and try to provide suggestions for that. – Deepak-MSFT May 16 '19 at 09:03
  • Hello Deepak-MSFT, After discussion with my chief today, i learnt that the website i'm going to download the file from will soon develop an API for this kind of requests. We decided to stop to try to download the file with the VBA code. That beeing said, i definitely think that Selenium is the best way to do this kind of things with VBA. I sadly have no code to give to help other people with that issue. Thanks a lot to you to have tried to help me, it's greatly appreciated. I'll accept your solution. Have a good day, Truely yours. – omnisius May 16 '19 at 13:57