7

我知道以前有人问过这样的问题,但我的有点不同,而且相当令人不安。我正在处理的是一个带有一些事件的网页,当输入框中的某些项目被填写时,这些事件会加载更多的页面。当这些事件触发时,页面会再次加载,但仍使用相同的 URL 和相同的 nameprop。我一直在分别使用以下类型的方法并串在一起处理等待页面加载,但有时 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 知道另一个页面不在它的方式上的方法。它似乎在完全完成之前加载了几次。

所以...有人有什么想法吗?

编辑:发现了一些新的尝试。仍然,没有骰子。有人建议我添加这些尝试。这是代码,由于某种原因,在触发应该填充 select 元素上的选项的事件后使用此方法时,VBE 和 excel 实例变得无响应......正在考虑尝试 xml......这是代码:

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。我发现它好多了,并且完全回避了这个异步问题,简单地执行帖子并让自己得到。根据您要执行的操作,可能不是最佳解决方案,但如果您仔细查看流量并很好地参数化,它会非常可靠地工作。

4

3 回答 3

7

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

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

于 2013-11-14T16:35:22.590 回答
2

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


我有类似的问题;等待谷歌图像搜索中的所有图像加载(这是一件棘手的事情,因为图像加载是由 AJAX 提示和用户滚动页面)。正如评论中所建议的那样;我的解决方案是等待某个元素出现在视口中(这是一个比监视器屏幕稍大的区域,被视为您实际上可以“看到”的区域)。

这是通过该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,直到元素位于视图中。

元素是立即加载的东西(如页面的框架/模板)。但是直到所有内容都加载完毕后你才能真正看到它,因为它就在底部。

如果该元素确实是最后要加载的东西(对于我的谷歌搜索,它是Show More Results按钮),那么只要在加载时将它放入视口,您应该能够检测到它何时出现在页面上。.bottom然后返回一个非零值(与页面上元素的实际位置有关 - 尽管出于我的目的,我并不真正关心)。我以 a 结束.ScrollIntoView,但这不是必需的。

于 2017-06-15T12:53:55.327 回答
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)
于 2015-02-21T13:38:50.053 回答