私はこのような質問が以前に尋ねられたことを知っていますが、私のものは少し異なり、かなり厄介です。私が扱っているのは、入力ボックスの特定の項目が入力されたときにページのより多くをロードするいくつかのイベントを含むフォームを備えたWebページです。これらのイベントが発生すると、ページが再度読み込まれますが、同じ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オブジェクトを設定するのに十分な時間待機することはできません。次の入力要素を設定し、コードを進めるために何もチェックしないことを検討しましたが、通常、入力要素はHTMLに存在しますが、適切なイベントが発生するまで非表示になるため、100%成功することはありません。 、これは問題にはなりませんが、イベントが発生するまで、可能な選択をロードしません。奇妙なページかもしれません。
とにかく...他に何を追加するかわからない。見るのに役立つかもしれない何か他のものがあれば、ただ尋ねてください。私が探しているのは、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
Webページで何が起こっているかを見ると、VBEとExcelが応答しなくなるのはこのループのどこかにあることがわかります。
それが役に立てば幸い...私はそれが私を助けなかったことを知っています...ドラッツ。
編集:私がこれを追加すると思っただけです。 Webページの自動化に関しては、ほとんどの場合、IEを使用していません。私はそれがはるかに優れていることを発見し、単に投稿を実行して自分自身を取得するために、非同期のもののこの問題を完全に回避します。何をしようとしているのかによっては最善の解決策ではないかもしれませんが、トラフィックを注意深く観察し、物事を適切にパラメータ化すれば、かなり確実に機能します。
徹底的な検索の結果、AJAXリクエスト、バックグラウンドで非同期に実行されるjavascriptコードは、何らかの方法でシグナルを取得できるものではないと判断しました。トリガーされているようです。ページの読み込みが終了したときのイベント。これは、将来検討したいオプションです。ただし、私の目的では、ページのフォームに入力するためにすでに使用していたのと同じコードを使用しただけです。送信ボタンをクリックする前に、各フィールドを再度ループして値がまだ正しいかどうかを確認します。これは理想的な解決策ではありませんが、この場合は問題を解決したように見える回避策です。
私の解決策がこの問題を扱っている他の誰かに適用できるかどうかはわかりませんが、それが役立つかどうかはわかります。この問題の回避策は、問題のアプリケーションとWebページに基づいている必要があると思います。
私が知っている古い質問ですが、これは私があまり見たことがない良い答えだと思います...
私は 同様の問題 ;グーグル画像検索のすべての画像が読み込まれるのを待っています(画像の読み込みは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
はゼロ以外の値を返します(ページ上の要素の実際の位置と関係があります-私は自分の目的のために本当に気にしませんでした)。最後に.ScrollIntoView
で終わりますが、それは必須ではありません。
私のウェブページでも同じ問題が発生しました。
最初のオプションは
While Ie.**document**.readystate="complete"
DoEvents
Wend
ボタンをクリックした後、または別のボックスで起動した後にオプションがロードされたボックスはほとんどありませんでした...私はこのようなコードを配置しました。
Do Until IE.document.getelementbyid("Next box").Lenght>0
DoEvents
Loop
Application.wait Now+Timevalue("00:00:02)