VBA IE自动化-等待下载完成 [英] VBA IE automation - wait for the download to complete

查看:133
本文介绍了VBA IE自动化-等待下载完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使通过Internet Explorer完成的一些任务自动化,包括下载文件,然后将其复制到其他目录并重命名。
我或多或少地成功找到了有关执行此操作的信息的方法,该代码正在运行,但是它有例外,因此,如果有人可以帮助我改进此代码,我将不胜感激。

I am trying to automate some tasks which are being done through Internet explorer, which include downloading a file and then copying it to a different directory and renaming it. I was more or less successful in finding the information on how to do this, the code is working, but it has exceptions, therefore I would be grateful if someone could help me to improve this code.

我想做两件事:


  1. 插入一个循环,以便脚本将等待某些元素出现,然后才继续执行。我在页面上找到了一些东西,但是,我也想建立一个最大的等待时间,就像这里建议的那样。

  2. 由于代码正在下载文件,因此它还应该等待下载完成,然后才继续。当前,我正在使用等待命令,但是下载时间可能会有所不同,在这种情况下脚本将停止。我也找到了解决方案,方法是等到出现打开文件夹按钮,但是我不确定如何在我的代码中实现它。这是我找到的代码:链接

  1. Insert a loop, so that the script would wait for certain elements to appear and only then would proceed with execution. I have found something on this page, however, I also would like to built in a maximum wait time, like it is suggested there.
  2. As the code is downloading a file, it should also wait for the download to be finished, and only then proceed. Currently I am using "wait" command, but the download times may vary and the script will stop in that case. I have also found a solution to this, by waiting till the button "Open folder" appears, but I am not sure how to implement it in my code. Here is the code that i have found: Link

另外,也许还有另一种解决方案,不是将文件保存在默认下载位置,而是执行保存 ,然后以这种方式定义目录和文件名?

Also, maybe there is another solution, not to save file in a default download location, but do a "Save as" instead and then defining the directory and file name in that way?

预先感谢您!

下面是我现在正在使用的源代码。例如,我使用Microsoft页面下载示例文件。

Below is my source code, that I am using right now. As an example, I am using Microsoft page with sample file download.

    Option Explicit
#If VBA7 Then
    Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds 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

#Else
    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
#End If

Sub MyIEauto()

    Dim ieApp As InternetExplorer
    Dim ieDoc As Object

    Set ieApp = New InternetExplorer

    ieApp.Visible = True
    ieApp.navigate "https://docs.microsoft.com/en-us/power-bi/sample-financial-download"
    Do While ieApp.Busy: DoEvents: Loop
    Do Until ieApp.readyState = READYSTATE_COMPLETE: DoEvents: Loop

    ieApp.navigate "http://go.microsoft.com/fwlink/?LinkID=521962"
    Do While ieApp.Busy: DoEvents: Loop
    Do Until ieApp.readyState = READYSTATE_COMPLETE: DoEvents: Loop

    Dim AutomationObj As IUIAutomation
    Dim WindowElement As IUIAutomationElement
    Dim Button As IUIAutomationElement
    Dim hWnd As LongPtr

    Set AutomationObj = New CUIAutomation

    Do While ieApp.Busy Or ieApp.readyState <> 4: DoEvents: Loop
    Application.Wait (Now + TimeValue("0:00:05"))
    hWnd = ieApp.hWnd
    hWnd = FindWindowEx(hWnd, 0, "Frame Notification Bar", vbNullString)
    If hWnd = 0 Then 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
    Application.Wait (Now + TimeValue("0:00:05"))

    FileCopy "C:\Users\Name\Downloads\Financial Sample.xlsx", "C:\Users\Name\Desktop\Financial Sample.xlsx"
    Name "C:\Users\Name\Desktop\Financial Sample.xlsx" As "C:\Users\Name\Desktop\Hello.xlsx"
    Application.Wait (Now + TimeValue("0:00:01"))

    Dim KillFile As String
    KillFile = "C:\Users\Name\Downloads\Financial Sample.xlsx"
    If Len(Dir$(KillFile)) > 0 Then
    SetAttr KillFile, vbNormal
     Kill KillFile
End If

End Sub


推荐答案

因此,在花了一些时间之后,我能够以期望的方式解决我的问题,并在下面发布了解决方案。
我感谢大家的建议,并希望所有建议的解决方案将来都会对其他人有帮助:)

So, after spending some additional time I was able to solve my problem in the way I was expecting, and I am posting the solution below. I thank everyone for the suggestions, and I hope that all of the suggested solutions will be a great find for others in the future :)

那代码,然后转到网站,点击下载链接,然后按保存按钮,下载开始。然后,脚本正在等待打开文件夹按钮出现,这意味着下载已完成。
下载文件后,脚本将文件复制到桌面上,重命名文件,然后从下载文件夹中删除原始文件。

So what the code does, it is going to a website, pressing on the download link, then pressing "Save" button, and the download is starting. Then Script is waiting for the "Open folder" button to appear, which means that the download has finished. After downloading the file, script copies the file to desktop, renames it and then deleted the original from the Downloads folder.

  Option Explicit
#If VBA7 Then
Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds 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

#Else
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
#End If

Sub MyIEauto()

Dim ieApp As InternetExplorer
Dim ieDoc As Object
Const DebugMode As Boolean = False

Set ieApp = New InternetExplorer

ieApp.Visible = True
ieApp.navigate "https://docs.microsoft.com/en-us/power-bi/sample-financial-download"
Do While ieApp.Busy: DoEvents: Loop
Do Until ieApp.readyState = READYSTATE_COMPLETE: DoEvents: Loop

ieApp.navigate "http://go.microsoft.com/fwlink/?LinkID=521962"
Do While ieApp.Busy: DoEvents: Loop
Do Until ieApp.readyState = READYSTATE_COMPLETE: DoEvents: Loop

Dim AutomationObj As IUIAutomation
Dim WindowElement As IUIAutomationElement
Dim Button As IUIAutomationElement
Dim hWnd As LongPtr

Set AutomationObj = New CUIAutomation

Do While ieApp.Busy Or ieApp.readyState <> 4: DoEvents: Loop
Application.Wait (Now + TimeValue("0:00:05"))
hWnd = ieApp.hWnd
hWnd = FindWindowEx(hWnd, 0, "Frame Notification Bar", vbNullString)
If hWnd = 0 Then 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

Do
Set iCnd = AutomationObj.CreatePropertyCondition(UIA_NamePropertyId, "Open folder")
Set Button = WindowElement.FindFirst(TreeScope_Subtree, iCnd)
    Sleep 200
    If DebugMode Then Debug.Print Format(Now, "hh:mm:ss"); "Open folder"
    DoEvents
Loop While Button Is Nothing


  FileCopy "C:\Users\" & Environ("UserName") & "\Downloads\Financial Sample.xlsx", "C:\Users\" & Environ("UserName") & "\Desktop\Financial Sample.xlsx"
Name "C:\Users\" & Environ("UserName") & "\Desktop\Financial Sample.xlsx" As "C:\Users\" & Environ("UserName") & "\Desktop\Hello.xlsx"
Application.Wait (Now + TimeValue("0:00:01"))

Dim KillFile As String
KillFile = "C:\Users\" & Environ("UserName") & "\Downloads\Financial Sample.xlsx"
If Len(Dir$(KillFile)) > 0 Then
SetAttr KillFile, vbNormal
 Kill KillFile
End If

End Sub

另外,如果有人要搜索如何循环代码直到出现一个元素,这是下面的代码。它会循环四行,然后显示一条消息。

Additionally, if someone will be searching how to loop the code until an element appears, here is the code below. It loops the lines four times and then displays a message.

intCounter = 0

Do Until IsObject(objIE.document.getElementById("btnLogIn")) = True Or intCounter > 3
DoEvents
Application.Wait (Now + TimeValue("0:00:01"))
intCounter = intCounter + 1
If intCounter = 4 Then
MsgBox "Time out."
End If
Loop

这篇关于VBA IE自动化-等待下载完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆