我在Visual Studio的SSIS中使用Visual Basic脚本任务来自动从https://www.fincen.gov/msb-registrant-search下载excel文件。
导航到网站并点击蓝色的“查看/下载”链接时,我没有任何问题。
我遇到的问题是黄色的“框架通知栏”出现时我需要以编程方式点击“保存”。 (我不想使用SendKeys方法。)
我正在使用UIAutomation参考来完成此任务。
除了使用UIAutomation关于如何下载此文件之外,我还对其他建议持开放态度 - 该解决方案必须能够用作SSIS包的一部分。
我已经在Excel VBA中编写了这段代码并且运行正常,但是我在将代码转换为VB时遇到了问题。
成功点击下载链接后,以下是我运行以执行以下操作的代码:
*我可以提供有效的Excel VBA代码。
#Region "Imports"
Imports System.Threading.Thread
Imports UIAutomationClient
Imports UIAutomationClient.UIA_PropertyIds
Imports UIAutomationClient.UIA_PatternIds
#End Region
<Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute()> _
<System.CLSCompliantAttribute(False)> _
Partial Public Class ScriptMain
Inherits Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
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
Public Sub Main()
getReport()
GC.Collect()
GC.WaitForPendingFinalizers()
Dts.TaskResult = ScriptResults.Success
End Sub
Public Sub getReport()
Dim IE As InternetExplorerMedium
Dim iePage As mshtml.HTMLDocument
Dim msbExport As IHTMLElement
IE = New InternetExplorerMedium
IE.Visible = True
IE.Navigate("https://www.fincen.gov/fcn/financial_institutions/msb/msbstateselector.html#")
Do : Sleep(1000) : Loop Until IE.ReadyState = tagREADYSTATE.READYSTATE_COMPLETE And IE.Busy = False
iePage = CType(IE.Document, mshtml.HTMLDocument)
msbExport = iePage.getElementById("ExportExcelLink")
msbExport.click()
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
#Region "ScriptResults declaration"
'This enum provides a convenient shorthand within the scope of this class for setting the
'result of the script.
'This code was generated automatically.
Enum ScriptResults
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
End Enum
#End Region
End Class
参考文献:
答案 0 :(得分:0)
我能够弄清楚这一点。这是整个工作代码。
#Region "Imports"
Imports System.Threading.Thread
Imports UIAutomationClient
Imports UIAutomationClient.UIA_PropertyIds
Imports UIAutomationClient.UIA_PatternIds
'Imports UIAutomationClient.IUIAutomationElement
#End Region
<Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute()> _
<System.CLSCompliantAttribute(False)> _
Partial Public Class ScriptMain
Inherits Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
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 fileName As String
Public InvokePattern As IUIAutomationInvokePattern
Public Sub Main()
getReport()
'deleteRows()
GC.Collect()
GC.WaitForPendingFinalizers()
Dts.TaskResult = ScriptResults.Success
End Sub
Sub deleteExistingExtract()
On Error Resume Next
Dim StrFile As String
Dim fPath As String
fPath = "C:\Users\" & Environ("username") & "\downloads\152*"
StrFile = Dir(fPath)
Do While Len(StrFile) > 0
Kill(fPath)
StrFile = Dir()
Loop
End Sub
Public Sub getReport()
Dim IE As InternetExplorerMedium
Dim iePage As mshtml.HTMLDocument
Dim msbExport As IHTMLElement
IE = New InternetExplorerMedium
IE.Visible = True
IE.Navigate("https://www.fincen.gov/fcn/financial_institutions/msb/msbstateselector.html#")
'On Error Resume Next
Do : Sleep(1000) : Loop Until IE.ReadyState = tagREADYSTATE.READYSTATE_COMPLETE And IE.Busy = False
iePage = CType(IE.Document, mshtml.HTMLDocument)
msbExport = iePage.getElementById("ExportExcelLink")
msbExport.click()
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)
fileName = Mid(dlStatus, InStr(dlStatus, "1"), 14)
bCnd = CUIAuto.CreatePropertyCondition(UIA_NamePropertyId, "Save")
bCtl = WindowHandleElement.FindFirst(TreeScope.TreeScope_Subtree, bCnd)
InvokePattern = CType(bCtl.GetCurrentPattern(UIA_InvokePatternId), IUIAutomationInvokePattern)
InvokePattern.Invoke()
Do
dlStatus = CType(tCtl.GetCurrentPropertyValue(UIA_ValueValuePropertyId), String)
Sleep(1000)
Loop Until Right(Trim(dlStatus), 10) = "completed."
IE.Quit()
End Sub
#Region "ScriptResults declaration"
'This enum provides a convenient shorthand within the scope of this class for setting the
'result of the script.
'This code was generated automatically.
Enum ScriptResults
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
End Enum
#End Region
End Class