【问题标题】:VBA interaction with internet explorerVBA 与 Internet Explorer 的交互
【发布时间】:2012-07-24 01:42:27
【问题描述】:

我正在构建的宏从 Excel 电子表格中获取名称,打开 Internet Explorer,然后搜索在线目录。搜索目录后,它会拉出一个 Java 表单,其中包含经理的姓名。我可以手动选择经理名称,右键单击,复制快捷方式,然后将其发布回电子表格。但是,我在使用一致的选项卡和复制快捷方式时遇到了问题。

  1. 有没有简单的方法让焦点回到 IE 窗口?
  2. 如何在不手动单击的情况下复制快捷方式?

代码:

Sub Macro1()
'
Dim ie As Object
Set ie = CreateObject("internetexplorer.application")

ie.Visible = True
ie.navigate "****url****"

While ie.busy
    DoEvents
Wend

ie.document.getElementById("SSOID").Value = "Z19516732"
ie.document.getElementById("Advanced").Checked = False
ie.document.all("Search").Click

'this loop is to slow the macro as the java form is filled from the search
For i = 1 To 400000000  
    i = i + 1
Next i

'ie.Object.Activate
ie.document.getElementById("Advanced").Checked = False
ie.document.getElementById("SSOID").Focus
Application.SendKeys "{TAB 6}" ', True

'bring up the control menu/right click
Application.SendKeys "+{F10}"

'copy shortcut is 8 items down on the list
Application.SendKeys "{DOWN}"
Application.SendKeys "{DOWN}"
Application.SendKeys "{DOWN}"
Application.SendKeys "{DOWN}"
Application.SendKeys "{DOWN}"
Application.SendKeys "{DOWN}"
Application.SendKeys "{DOWN}"
Application.SendKeys "{DOWN}"

'enter was not working so the shortcut for the menu is 't'
'SendKeys "{ENTER}"
Application.SendKeys "{t}"

Windows("Book21").Activate
Range("A1").Select
ActiveSheet.Paste

End Sub

【问题讨论】:

    标签: internet-explorer vba excel automation sendkeys


    【解决方案1】:

    在你的模块的开头,放这行代码:

    Public Declare Function SetForegroundWindow Lib "user32" (ByVal HWND As Long) As Long
    

    这称为Declare Statement,可让您访问Windows 内置的SetForegroundWindow 函数。该函数位于 Windows 系统的user32 DLL 中。实际上,VBA 可以通过这种方式访问​​多个 DLL 中的许多其他函数(有关更多示例,请参见链接)。

    在您的代码中,在与您的 IE 对象交互时,像这样记录HWND(handle 到那个窗口):

    Dim HWNDSrc As Long
    HWNDSrc = ie.HWND
    

    然后,在您与 Java 交互之后,使用它继续:

    SetForegroundWindow HWNDSrc
    

    这告诉Windows系统将HWND标识的窗口设置为前景窗口(顾名思义)。

    但是,这可能不是必需的,具体取决于您与 IE 交互的方式。换句话说,如果您不需要查看/触摸窗口,您仍然可以使用代码中已有的对象进行交互。

    有一些方法可以使用 GetElementById() 和 GetElementsByTagName() (see here for more info) 之类的代码获取您正在寻找的快捷方式,但这取决于源代码的创建方式。例如如果您知道 HTML 源代码,<a href="...> 链接应该相对容易拉取。


    第二次查看您的代码后,我注意到您使用循环来“减慢”宏。我有一个函数,我一直在使用我自己的类似方法。希望这将有助于您完成所需的工作。我已经从我自己的原始代码修改了下面的代码,因为我有其他不适用于您的案例的细节。如果有任何错误,我可以根据需要进行调整。

    Public Sub WaitForIE(myIEwindow As InternetExplorer, HWND As Long, WaitTime As Integer)
    
        ' Add pauses/waits so that window action can actually
        ' begin AND finish before trying to read from myIEWindow.
    
        ' myIEWindow is the IE object currently in use
        ' HWND is the HWND for myIEWindow
        ' The above two variables are both used for redundancy/failsafe purposes.
        ' WaitTime is the amount of time (in seconds) to wait at each step below. 
        ' This is variablized because some pages are known to take longer than 
        ' others to load, and some pages with frames may be partially loaded,
        ' which can incorrectly return an READYSTATE_COMPLETE status, etc.
    
        Dim OpenIETitle As SHDocVw.InternetExplorer
    
        Application.Wait DateAdd("s", WaitTime, Now())
    
        Do Until myIEwindow.ReadyState = READYSTATE_COMPLETE
            ' Wait until IE is done loading page and/or user actions are done.
        Loop
    
        Application.Wait DateAdd("s", WaitTime, Now())
    
        While myIEwindow.Busy
            DoEvents  ' Wait until IE is done loading page and/or user actions are done.
        Wend
    
        On Error Resume Next
        ' Make sure our window still exists and was not closed for some reason...
        For Each OpenIETitle In objShellWindows
            If OpenIETitle.HWND = HWND Then
                If Err.Number = 0 Then
                    Set myIEwindow = OpenIETitle
                    Exit For
                Else
                    Err.Clear
                End If
            End If
        Next OpenIETitle
        On Error GoTo 0
    
    End Sub
    

    【讨论】:

    • 我之前尝试过 setForegroundWindow,但这次成功了,谢谢!然而,html 源代码没有显示所需的链接。虽然链接并不是我所需要的。我需要文本(经理的姓名),但我无法通过右键单击来复制它。也许有一种简单的方法来突出显示文本?我打算只复制和粘贴链接,然后做一些快速的行来清理链接表单中的名称。
    • 谢谢加菲!窗口聚焦的第一部分非常棒。就像我说的我以前试过,但你一定有神奇的感觉。在我的问题的第二部分,创建快捷方式,我发现了我的错误。无论出于何种原因,我用于搜索组件的“.Focus”只是简单地聚焦而不是选择。因此,当我将其切换到“.select”并使用 application.sendkeys“~”(回车键)指定 hte sendkeys 时,一切都聚集在一起了!我第一次以用户身份使用 stackflow,而不仅仅是读者,而且非常恶心!谢谢!
    • @orangehairbandit 很高兴我能帮上忙!
    • 您为暂停而编辑的评论代码有误。声明 sub 时,您将 myIEwindow 作为 InternetExplorer。 InternetExplorer 是公认的数据类型或对象吗?我不断收到编译错误:未定义用户定义类型
    • @student 抱歉,不,我对那个对话没有任何经验。但我相信这里有人可以帮助你。祝你好运!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-30
    • 2020-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-18
    相关资源
    最近更新 更多