【问题标题】:How does one wait for an Internet Explorer 9 frame to load using VBA Excel?如何使用 VBA Excel 等待 Internet Explorer 9 框架加载?
【发布时间】:2012-06-12 20:18:57
【问题描述】:

有许多在线资源说明如何在 VBA Excel 中使用 Microsoft Internet Explorer 控件来执行基本的 IE 自动化任务。当网页具有基本结构时,这些工作。但是,当网页包含多个框架时,它们可能难以使用。

我需要确定网页中的单个框架是否已完全加载。例如,此 VBA Excel 代码打开 IE,加载网页,循环通过 Excel 表将数据放入网页字段,执行搜索,然后将 IE 结果数据返回到 Excel(我很抱歉省略了站点地址)。

目标网页包含两个框架:

1) 搜索值输入和执行搜索的searchbar.asp框架

2) 显示搜索结果的searchresults.asp框架

在此构造中,搜索栏是静态的,而搜索结果会根据输入条件而变化。由于网页是以这种方式构建的,因此无法使用 IEApp.ReadyState 和 IEApp.Busy 来确定 IEfr1 框架加载完成,因为这些属性在初始 search.asp 加载后不会更改。因此,我使用较大的静态等待时间来避免随着互联网流量波动而出现运行时错误。这段代码确实有效,但速度很慢。请注意 cmdGO 语句后的 10 秒等待。我想通过添加可靠的逻辑来确定帧加载进度来提高性能。

如何确定自主框架是否已完成加载?

' NOTE: you must add a VBA project reference to "Internet Explorer Controls"
' in order for this code to work
Dim IEapp As Object
Dim IEfr0 As Object
Dim IEfr1 As Object

' Set new IE instance
Set IEapp = New InternetExplorer

' With IE object
With IEapp
    ' Make visible on desktop
    .Visible = True
    ' Load target webpage
    .Navigate "http://www.MyTargetWebpage.com/search.asp"
    ' Loop until IE finishes loading
    While .ReadyState <> READYSTATE_COMPLETE
        DoEvents
    Wend
End With

' Set the searchbar.asp frame0
Set IEfr0 = IEapp.Document.frames(0).Document 

' For each row in my worksheet
For i = 1 To 9999                

    ' Input search values into IEfr0 (frame0)
    IEfr0.getElementById("SearchVal1").Value = Cells(i, 5)
    IEfr0.getElementById("SearchVal2").Value = Cells(i, 6)

    ' Execute search
    IEfr0.all("cmdGo").Click        

    ' Wait a fixed 10sec
    Application.Wait (Now() + TimeValue("00:00:10"))

    ' Set the searchresults.asp frame1
    Set IEfr1 = IEapp.Document.frames(1).Document

    ' Retrieve webpage results data
    Cells(i, 7) = Trim(IEfr1.all.Item(26).innerText)
    Cells(i, 8) = Trim(IEfr1.all.Item(35).innerText)

Next

【问题讨论】:

  • 你能贴出实际的网址吗?没有它就很难诊断。

标签: excel vba internet-explorer-9


【解决方案1】:

正如@JimmyPena 所说。如果我们能看到 URL,那么提供帮助会容易得多。

如果我们做不到,希望这篇概述可以为您指明正确的方向:

  1. 等待页面加载(IEApp.ReadyState 和 IEApp.Busy)
  2. 从 IE 对象中获取文档对象。 (完成)
  3. 循环直到文档对象不为空。
  4. 从文档对象中获取框架对象。
  5. 循环直到框架对象不为空。

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    我使用循环选项检查字段值,直到它像这样填充

    执行 IE.Document.getElementById("USERID").Value "test3" IE.Document.getElementById("USERID").Value = "test3" 循环

    【讨论】:

      【解决方案3】:

      这是一个非常古老的帖子,但我想我会发布我的发现,因为我来这里是为了寻找答案......

      查看本地窗口,我可以看到“readystate”变量只是 IE 应用程序本身的“READYSTATE_COMPLETE”。但对于 iframe,它是小写的“完整”
      所以我通过在我正在使用的框架的 .readystate 上使用 debug.print 循环来探索这一点。

      Dim IE As Object
      Dim doc As MSHTML.HTMLDocument
      Set doc = IE.Document
      Dim iframeDoc As MSHTML.HTMLDocument
      Set iframeDoc = doc.Frames("TheFrameIwasWaitingFor").Document
      
      ' then, after I had filled in the form and fired the submit event, 
      
      Debug.Print iframeDoc.readyState
         Do Until iframeDoc.readyState = "complete"
           Debug.Print iframeDoc.readyState 
           DoEvents
         Loop
      

      因此,这将在即时窗口中显示“正在加载”的一行一行,最终显示“完成”并结束循环。当然可以删减 debug.prints。

      另一件事:

      debug.print iframeDoc.readystate ' is the same as...
      debug.print doc.frames("TheFrameIwasWaitingFor").Document.readystate
      ' however, you cant use...
      IE.Document.frames("TheFrameIwasWaitingFor").Document.readystate ' for some reason...
      

      如果所有这些都是常识,请原谅我。我真的是在几天前才开始学习 VBA 脚本......

      【讨论】:

        猜你喜欢
        • 2013-11-24
        • 2012-10-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-02
        相关资源
        最近更新 更多