【问题标题】:Convert VBA Code to VB.NET for use in SSIS Script Task将 VBA 代码转换为 VB.NET 以用于 SSIS 脚本任务
【发布时间】:2018-04-15 22:53:01
【问题描述】:

这样做的目的是使用 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 Script 任务中似乎不起作用的部分是这一行

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

【问题讨论】:

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


    【解决方案1】:

    我能够解决这个问题。这是我的 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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-14
      • 2018-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-18
      相关资源
      最近更新 更多