VBA Internet Explorer等待加载网页

时间:2013-11-12 15:34:22

标签: internet-explorer vba dom automation

我知道之前曾经问过这样的问题,但我的情况有点不同,而且一直很麻烦。我正在处理的是一个带有表单的网页,当填写输入框中的某些项目时,这些表单会加载更多页面。当这些事件触发页面再次加载时,但保持在具有相同nameprop的相同URL。我一直在使用以下类型的方法单独和串联来处理等待页面加载,但有时VBA仍然设法继续执行并将HTMLDocument变量设置为页面,而没有相应的信息导致宏调试。以下是我到目前为止所尝试的各种事情:

While IE.Busy
    DoEvents
Wend

Do Until IE.statusText = "Done"
    DoEvents
Loop

Do Until IE.readyState = 4
    DoEvents
Loop

我甚至试图将这些事件放入如下所示的循环中,但它并不是很有效,因为lastModified属性只返回一个值到第二个并且宏在字段中旋转的速度足够快以至于它是在同一秒内返回一个新页面:

Do Until IE.statusText = "Done" And IE.Busy = False And IE.ReadyState = 4 _
And IE.document.lastModified > LastModified ----or---- IE.document.nameprop = _
"some known and expected name prop here"
    While IE.Busy
        DoEvents
    Wend
    Do Until IE.statusText = "Done"
        DoEvents
    Loop
    Do Until IE.readyState = 4
        DoEvents
    Loop
Loop

即使没有等待足够长的时间来设置HTMLDocument对象导致调试。我已经考虑过设置下一个输入元素并检查无需进一步代码,但即使这样也不会100%成功,因为通常输入元素存在于HTML中,但是在相应的事件被触发之前一直隐藏,这不会是一个问题,但他们不会加载他们可能的选择,直到事件被触发。这可能是一个奇怪的页面。

无论如何......不确定还要添加什么。如果有其他事情可能有助于看到问。我想我正在寻找的方法是让VBA等到IE知道另一个页面不在它的路上。它似乎在完成之前加载了几次。

所以......任何人都有任何想法吗?

编辑:发现了一些新的尝试。仍然没有骰子。有人建议我添加这些尝试。这是代码,由于某种原因,VBE和excel实例在触发应该填充select元素上的选项的事件后使用此方法时变得无响应...考虑尝试xml ...这里是代码:< / p>
intCounter = 0
Do until intCounter > 2
    Do Until IE.Busy = False: DoEvents: Loop
    Do Until IE.ReadyState = 4: DoEvents: Loop
    Set HTMLDoc = IE.Document
    Do Until HTMLDoc.ReadyState = "complete"
    Set HTMLSelect = HTMLDoc.getElementById("ctl00$ctl00$MainContent$ChildMainContent$ddlEmployeeBranchCodes")
    intCounter = 0
    For each Opt in HTMLSelect
        intCounter = intCounter + 1
    Next Opt
Loop

根据我在网页上看到的情况,我知道在这个循环中,VBE和Excel变得无响应。

希望有所帮助......我知道这对我没有帮助...... Drats。

编辑:我想我会加上这个。在自动化网页方面,在大多数情况下,我不再使用IE浏览器。我发现它好多了,完全回避了这个异步的问题,简单地执行帖子并获得自己。可能不是最好的解决方案,取决于您尝试做什么,但如果您仔细查看流量并将参数化很好,它就会非常可靠。

3 个答案:

答案 0 :(得分:7)

经过详尽的搜索,我确定AJAX请求,在后台异步运行的javascript代码不是我可以以任何方式获得信号的东西。它在加载页面时似乎会触发一些事件,这是我将来要探索的一个选项。但是,出于我的目的,我只使用了我已经使用的相同代码来填写我页面上的表单,然后我再次循环遍历每个字段,以便在单击提交按钮之前检查值是否仍然正确。它不是一个理想的解决方案,但它是一种解决方案,在这种情况下似乎已经解决了我的问题。

我不确定我的解决方案是否适用于处理此问题的其他人,但是如果它有帮助的话。我认为这个问题的解决方法必须基于相关的应用程序和网页。

答案 1 :(得分:1)

我的网页遇到了同样的问题.. 做的是......

第一个选项是

While Ie.**document**.readystate="complete"
DoEvents
Wend

在按钮点击/甚至在另一个框中点火后,几个框中的选项被加载...我jsst放置了这样的代码..

Do Until IE.document.getelementbyid("Next box").Lenght>0
DoEvents
Loop
Application.wait Now+Timevalue("00:00:02)

答案 2 :(得分:1)

老问题我知道,但我认为这是一个很好的答案,我没有看到太多......

我有similar problem;等待谷歌图像搜索中的所有图像加载(这是一个棘手的事情,因为图像加载是由AJAX和用户滚动页面提示的)。正如评论中所建议的那样; my solution是等待某个元素出现在视口中(这是一个比监视器屏幕略大的区域,并被视为您实际可以“看到”的内容)。

这是通过getBoundingClientRect方法

实现的
Dim myDiv As HTMLDivElement: Set myDiv = currPage.getElementById("fbar") 
'myDiv should some element in the page which will only be visible once everything else is loaded
Dim elemRect As IHTMLRect: Set elemRect = myDiv.getBoundingClientRect
Do Until elemRect.bottom > 0 'If the element is not in the viewport, then this returns 0
    DoEvents
    'Now run the code that triggers the Ajax requests
    'For me that was simply scrolling down by a big number
    Set elemRect = myDiv.getBoundingClientRect
Loop
myDiv.ScrollIntoView

我在链接的答案中详细解释了它是如何工作的,但基本上BoundingClientRect.bottom等于0,直到元素在vieport中。

元素是直接加载的东西(如页面的框架/模板)。但是直到所有内容都被加载后才真正看到它,因为它位于底部。

如果该元素确实是最后要加载的元素(对于我的谷歌搜索它是显示更多结果按钮),那么只要你进入视口时它就是加载,您应该能够检测到它何时出现在页面上。 .bottom然后返回一个非零值(与页面上元素的实际位置有关 - 我并不关心我的目的)。我用.ScrollIntoView完成,但这不是必需的。