这样做的目的是使用 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)