0

这样做的目的是使用 IE 自动化和 UI 自动化从 Internet Explorer 下载一个 excel 文件,以便与 Internet Explorer 中的帧通知栏一起使用。

在 VBA 中使用 UI 自动化花费了相当长的时间后,我已经成功地让它工作了。

我现在需要在 VB 中编写它,以便在脚本任务中作为更大的 SSIS 包的一部分使用。在尝试修改它后,我遇到了让它工作的问题。我在 Excel 和 SSIS 脚本任务中添加了 UIAutomation 引用。

这是我的工作 Excel VBA 代码:

Option Explicit


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

Public xl As Excel.Application
Public ie As InternetExplorerMedium
Public iePage As HTMLDocument
Public msbExport As HTMLLinkElement

Public CUIAuto As IUIAutomation
Public WindowHandleElement As IUIAutomationElement
Public windowHandle As Long
Public tCnd As IUIAutomationCondition
Public bCnd As IUIAutomationCondition
Public tCtl As IUIAutomationElement
Public bCtl As IUIAutomationElement
Public dlStatus As String
Dim fName As String
Public InvokePattern As IUIAutomationInvokePattern


Public Sub getReport()
Set ie = New InternetExplorerMedium
ie.Visible = True
ie.navigate ("https://www.fincen.gov/fcn/financial_institutions/msb/msbstateselector.html#")

 Do: Application.Wait Now + #12:00:01 AM#: Loop Until ie.readyState = tagREADYSTATE.READYSTATE_COMPLETE And ie.Busy = False
 Set iePage = ie.document

iePage.getElementById("ExportExcelLink").Click

    Do
    'On Error Resume Next
    windowHandle = ie.Hwnd
    windowHandle = FindWindowEx(windowHandle, 0, "Frame Notification Bar", vbNullString)
    Application.Wait Now + #12:00:01 AM#
    Loop Until windowHandle > 0



Set CUIAuto = New CUIAutomation
Set WindowHandleElement = CUIAuto.ElementFromHandle(ByVal windowHandle)

Set tCnd = CUIAuto.CreatePropertyCondition(UIA_ControlTypePropertyId, UIA_TextControlTypeId)
Set tCtl = WindowHandleElement.FindFirst(TreeScope_Subtree, tCnd)
dlStatus = tCtl.GetCurrentPropertyValue(UIA_ValueValuePropertyId)
fName = Mid(dlStatus, InStr(dlStatus, "1"), 14)
Debug.Print dlStatus ' leave this to see download progress in immediate window


Set bCnd = CUIAuto.CreatePropertyCondition(UIA_NamePropertyId, "Save")
Set bCtl = WindowHandleElement.FindFirst(TreeScope_Subtree, bCnd)
Set InvokePattern = bCtl.GetCurrentPattern(UIA_InvokePatternId)
InvokePattern.Invoke

Do
dlStatus = tCtl.GetCurrentPropertyValue(UIA_ValueValuePropertyId)
Debug.Print dlStatus
DoEvents
Application.Wait Now + #12:00:01 AM#
Loop Until Right(Trim(dlStatus), 10) = "completed."
Stop


End Sub

这是我的 VB 代码的 UIAutomation 部分不起作用:

#Region "Imports"
Imports System.Threading.Thread
Imports UIAutomationClient
Imports UIAutomationClient.UIA_PropertyIds
Imports UIAutomationClient.UIA_PatternIds
#End Region




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

Public CUIAuto As IUIAutomation
Public WindowHandleElement As IUIAutomationElement
Public windowHandle As Long
Public tCnd As IUIAutomationCondition
Public bCnd As IUIAutomationCondition
Public tCtl As IUIAutomationElement
Public bCtl As IUIAutomationElement
Public dlStatus As String
Public InvokePattern As IUIAutomationInvokePattern
Do

windowHandle = IE.HWND
windowHandle = CLng(FindWindowEx(windowHandle, 0, "Frame Notification Bar", vbNullString))
Sleep(1000)
Loop Until windowHandle > 0



CUIAuto = New CUIAutomation
WindowHandleElement = CUIAuto.ElementFromHandle(CType(windowHandle, IntPtr))

tCnd = CUIAuto.CreatePropertyCondition(UIA_ControlTypePropertyId, UIA_ControlTypeIds.UIA_TextControlTypeId)
tCtl = WindowHandleElement.FindFirst(TreeScope.TreeScope_Subtree, tCnd)
dlStatus = CType(tCtl.GetCurrentPropertyValue(UIA_ValueValuePropertyId), String) 'get download status

bCnd = CUIAuto.CreatePropertyCondition(UIA_NamePropertyId, "Save")
bCtl = WindowHandleElement.FindFirst(TreeScope.TreeScope_Subtree, bCnd) ' The error seems to be happening here, there is no object after running this line
InvokePattern = CType(bCtl.GetCurrentPattern(UIA_InvokePatternId), IUIAutomationInvokePattern)
InvokePattern.Invoke()


End Sub

在 VB 脚本任务中似乎不起作用的部分是这一行

bCtl = WindowHandleElement.FindFirst(TreeScope.TreeScope_Subtree, bCnd)
4

1 回答 1

0

我能够解决这个问题。这是我的 VB.NET 代码的 UI 自动化部分。这种方法比使用 sendkeys 好得多,因为它适用于实际对象。我使用框架通知栏中的文本来确定文件何时完成下载。只需添加一个“循环,直到文本读取完成。您需要阅读每个循环上的文本,以便它可以跟踪下载进度。

#Region "Imports"
Imports System.Threading.Thread
Imports UIAutomationClient
Imports UIAutomationClient.UIA_PropertyIds
Imports UIAutomationClient.UIA_PatternIds
'Imports UIAutomationClient.IUIAutomationElement
#End Region

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

    Public CUIAuto As IUIAutomation
    Public WindowHandleElement As IUIAutomationElement
    Public windowHandle As Long
    Public tCnd As IUIAutomationCondition
    Public bCnd As IUIAutomationCondition
    Public tCtl As IUIAutomationElement
    Public bCtl As IUIAutomationElement
    Public dlStatus As String
    Public InvokePattern As IUIAutomationInvokePattern


        Do
            'On Error Resume Next
            windowHandle = IE.HWND
            windowHandle = CLng(FindWindowEx(windowHandle, 0, "Frame Notification Bar", vbNullString))
            Sleep(1000)
        Loop Until windowHandle > 0



        CUIAuto = New CUIAutomation
        WindowHandleElement = CUIAuto.ElementFromHandle(CType(windowHandle, IntPtr))

        tCnd = CUIAuto.CreatePropertyCondition(UIA_ControlTypePropertyId, UIA_ControlTypeIds.UIA_TextControlTypeId)
        tCtl = WindowHandleElement.FindFirst(TreeScope.TreeScope_Subtree, tCnd)
        dlStatus = CType(tCtl.GetCurrentPropertyValue(UIA_ValueValuePropertyId), String)

        bCnd = CUIAuto.CreatePropertyCondition(UIA_NamePropertyId, "Save")
        bCtl = WindowHandleElement.FindFirst(TreeScope.TreeScope_Subtree, bCnd)
        InvokePattern = CType(bCtl.GetCurrentPattern(UIA_InvokePatternId), IUIAutomationInvokePattern)
        InvokePattern.Invoke()
于 2018-04-15T23:01:36.283 回答