【问题标题】:VBA:IE-How to assign pathname to file input tag without popup file upload form?VBA:IE-如何在没有弹出文件上传表单的情况下为文件输入标签分配路径名?
【发布时间】:2016-04-20 14:55:09
【问题描述】:

我目前正在做文件上传的自动化

下面是输入文件标签的HTML标签:

 <input name="file" title="Type the path of the file or click the Browse button to find the file." id="file" type="file" size="20">

下面是按钮 HTML 标签:

<input name="Attach" title="Attach File (New Window)" class="btn" id="Attach" onclick="javascript:setLastMousePosition(event); window.openPopup('/widg/uploadwaiting.jsp', 'uploadWaiting', 400, 130, 'width=400,height=130,resizable=no,toolbar=no,status=no,scrollbars=no,menubar=no,directories=no,location=no,dependant=no', true);" type="submit" value="Attach File">

我的 VBA 编码是:

Dim filee As Object
Set filee = mydoc.getElementById("file")
filee.Value = filenamepath

Set attach = mydoc.getElementsByName("Attach")
attach(0).Click

当我运行这个编码时,输入文件路径框没有分配路径名,所以我选择了文件路径。

查找附件截图。

最后我尝试了下面的代码,但是发送键没有执行

Dim filee As Object
    Set filee = mydoc.getElementById("file")
    filee.Click

obj.SetText filename
obj.PutInClipboard
SendKeys "^v"
SendKeys "{ENTER}"

Set attach = mydoc.getElementsByName("Attach")
    attach(0).Click

Set finall = mydoc.getElementsByName("cancel")
    finall(0).Click

请告诉我 windows API 程序在 fine name: 输入框中分配我的文件名目录打开 Choose File to Open 资源管理器并单击 open 按钮。

【问题讨论】:

  • 您不能以编程方式为“文件”类型的输入赋值。一些与安全相关的非常好的原因。
  • @TimWilliams 我必须先浏览.. click 事件之后我应该运行此代码还是在打开文件上传表单后如何分配值?
  • 请提供任何其他解决方案来实现此自动化。
  • @TimWilliams 我可以使用 Selenium webdriver 和 Firefox 来完成这个自动化吗?
  • 我不知道 - 我从未使用过 Selenium。

标签: windows vba excel internet-explorer automation


【解决方案1】:

我通过运行包含文件路径的外部 VBScript 解决了这个问题,在发送 Enter Key 后使用 SendKeys 方法将其设置为“选择要上传的文件”弹出窗口以关闭此弹出窗口,并且此运行成功,因为 extranl VBScript 运行在另一个进程,因此它不会卡在 VBA 代码上。

注意事项: 1-我从 VBA 代码动态创建外部 VBScript 并将其保存在 Temp 文件夹中,之后我使用 WScript.Shell.Run 运行此脚本以在另一个线程上执行它 1- 在外部 VBScript 开始时,我设置了 1 秒延迟,以确保“选择要上传的文件”弹出窗口已经从 VBA 打开。

这是完整的代码:

....
....

Set filee = mydoc.getElementById("file")

    CompleteUploadThread MyFilePath
    filee.Foucs
    filee.Click

....
....

Private Sub CompleteUploadThread(ByVal fName As String)
    Dim strScript As String, sFileName As String, wsh As Object
    Set wsh = VBA.CreateObject("WScript.Shell")
    '---Create VBscript String---
    strScript = "WScript.Sleep 1000" & vbCrLf & _
                "Dim wsh" & vbCrLf & _
                "Set wsh = CreateObject(""WScript.Shell"")" & vbCrLf & _
                "wsh.SendKeys """ & fName & """" & vbCrLf & _
                "wsh.SendKeys ""{ENTER}""" & vbCrLf & _
                "Set wsh = Nothing"
    '---Save the VBscript String to file---
    sFileName = wsh.ExpandEnvironmentStrings("%Temp%") & "\zz_automation.vbs"
    Open sFileName For Output As #1
    Print #1, strScript
    Close #1
    '---Execute the VBscript file asynchronously---
    wsh.Run """" & sFileName & """"
    Set wsh = Nothing
End Sub

【讨论】:

    【解决方案2】:

    由于安全原因无法设置文件输入元素的值,“发送密钥”方法似乎是使用 IE API 自动上传文件的唯一选项。

    我刚刚偶然发现Click 之后的代码似乎没有被执行——也就是说,除非对话框关闭。这表明Click 方法处于阻塞状态,无法从宏内部与对话框进行交互。

    我可以通过使用不同的方法打开对话框来解决这个问题:使用Focus 将焦点设置到文件元素,并使用SendKeys 发送空格键。

    在你的情况下,替换

    filee.Click
    

    filee.Focus
    SendKeys " "
    

    【讨论】:

      【解决方案3】:

      leemes 的方法(向 IE 上的文件选择按钮发送密钥)是一种自动化文件选择过程的简单方法。

      此外,如果 IEObject.Visible 有时无法将焦点赋予 IE Window, 在使用“SendKeys”之前,我们最好使用 Windows API 将 IE 窗口发送到最顶部的位置,如下所示:

      #If VBA7 Then
          Declare PtrSafe Function SetForegroundWindow Lib "user32" (ByVal hwnd As LongPtr) As LongPtr
          Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Any, ByVal lpWindowName As Any) As LongPtr
      #Else
          Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
          Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Any, ByVal lpWindowName As Any) As Long
      #End If
      
      Sub Test()
      
         'first create or get IE object
         Set IE= ...
         ...
      
         'second, send IE window to the foreground
         Dim TargetWnd
         TargetWnd = FindWindow("IEFrame", vbNullString)  'find IE window
         If TargetWnd = 0 Then Debug.Print "Window not found." 'Else Debug.Print TargetWnd
         SetForegroundWindow (TargetWnd)
      
         'sendkeys
         set filee = getElement....
         filee.Focus
         SendKeys " "     'send Space key instead of .Click method
         SendKeys "filePath"     ' "C:\path\filename"  ' Type-in the filename 
         SendKeys "{Enter}"    'closes the file dialog
      
         'finally submit       
         ...
         ...
      
      end Sub
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-08-26
        • 2015-04-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-07
        相关资源
        最近更新 更多