将VBA代码转换为VB.NET以在SSIS脚本任务

时间:2018-04-15 22:53:01

标签: vb.net vba ssis ui-automation ie-automation

这样做的目的是使用IE Automation和UI Automation从Internet Explorer下载excel文件,以使用Internet Explorer中的Frame Notification Bar。

在VBA中花了很长时间使用UI Automation之后,我已经成功地将其用于工作。

我现在需要在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)

1 个答案:

答案 0 :(得分:0)

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

#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()