2013-11-12 3 views
7

Я знаю, что такие вопросы были заданы раньше, но мой немного отличается и был довольно тревожным. Я имею дело с веб-страницей с формой с несколькими событиями, которые загружают большую часть страницы, когда заполняются некоторые элементы в поле ввода. Когда эти события снова перезагружают страницу, но остаются с тем же URL-адресом с тем же именемprop. Я использую следующие типы методов как отдельно, так и в совокупности, чтобы обрабатывать ожидание загрузки страницы, но иногда VBA по-прежнему удается продолжить выполнение и установить переменную HTMLDocument на страницу без соответствующей информации, вызывающей макрос для отладки. Вот виды вещей, которые я пытался до сих пор:VBA Internet Explorer ждет загрузки веб-страницы

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 не узнает, что другая страница не на пути. Кажется, он загружается несколько раз, прежде чем он будет полностью выполнен.

Итак ... У кого-нибудь есть идеи?

EDIT: Нашли несколько новых вещей, чтобы попробовать. Тем не менее, нет кубиков. Было высказано предположение, что я добавляю эти попытки. Вот код, по какой-то причине экземпляр VBE и excel становятся невосприимчивыми при использовании этого подхода после запуска события, которое должно заполнить параметры на элементе select ... думать о попытке 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 становятся невосприимчивыми.

Надеюсь, что это поможет ... Я знаю, это не помогло мне ... Драты.

EDIT: Просто подумал, что я бы добавил это. Когда дело доходит до автоматизации веб-страницы, по большей части, я больше не использую IE. Я нашел, что это намного лучше, и полностью обойти эту проблему асинхронного материала, просто выполнить сообщения и получить себя. Не может быть лучшим решением в зависимости от того, что вы пытаетесь сделать, но он работает довольно надежно, если вы внимательно посмотрите на трафик и хорошо оцените параметры.

+2

Если вы имеете дело со страницей, которая динамически добавляет/удаляет компоненты интерфейса, то у вас действительно есть только два варианта: 1) добавьте фиксированное время ожидания х секунд для учета обновлений; 2) проверьте фактические элементы, которые вам нужны для взаимодействовать с помощью кода и цикл до тех пор, пока они не будут найдены. Я не думаю, что есть какой-либо способ надежно рассказать в общем смысле, когда (например, все ожидающие запросы AJAX завершены. –

+0

@TimWilliams Да, я думаю, это то, к чему я иду. Я думаю, что мне придется посмотреть на элементы ввода, но они действительно существуют до того, как будут запущены события, но у них нет опций. Итак, я думаю, что я застрял в подсчете вариантов, пока не станет доступным. – MattB

+0

Ну ... как оказалось, подсчет опций на входном элементе заставляет код становиться невосприимчивым. Так что я вроде как ручей. – MattB

ответ

7

После исчерпывающего поиска я определил, что запрос AJAX, код javascript, который выполняется асинхронно в фоновом режиме, не является чем-то, что я могу получить от любого сигнала. Кажется, он вызывает какое-то событие, когда он заканчивается загрузкой страницы, и это вариант, который я хотел бы изучить в будущем. Однако для моих целей я просто использовал тот же самый код, который я уже использовал, чтобы заполнить форму на моей странице, и я снова прохожу через каждое поле, чтобы проверить правильность значений до нажатия кнопки отправки. Это не идеальное решение, но это обходное решение, которое, по-видимому, позаботилось о моей проблеме в этом случае.

Я не уверен, что мое решение будет применимо к кому-то другому, занимающемуся этой проблемой, но там, если это поможет. Я думаю, что обходные пути для этой проблемы должны основываться на рассматриваемой заявке и веб-странице.

+1

@ Carlos André Velozo Trufini Нет, на самом деле не было удовлетворительного решения, но я смог обойти эту проблему. Есть что-то, что вы могли бы попробовать. Вы можете попытаться использовать jQuerry для проверки запросов AJAX ... это библиотека javascript, хотя ... но вы могли бы принести это с помощью метода ScriptControl: http://ramblings.mcpher.com/Home/excelquirks/snippets/scriptcontrol Good удачи. – MattB

+0

сам пришел к такому же выводу, и это помогает мне избежать траты времени. благодаря! – Orangesandlemons

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) 
0

Старый вопрос, я знаю, но я думаю, что это хороший ответ, который я убежище «Т видел о многом ...


У меня был similar problem; ожидая загрузки всех изображений в поисковой системе Google (это сложная вещь, так как загрузка изображений запрашивается AJAX и пользователем, прокручивающим страницу). Как было предложено в комментариях; my solution должен был ждать появления определенного элемента в окне просмотра (это область немного больше, чем экран монитора, и рассматривается как то, что вы можете «видеть»).

Это достигается с помощью метода getBoundingClientRect

Dim myDiv As HTMLDivElement: Set myDiv = currPage.getElementById("fbar") 'this should be the last element on your page to load 
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. Если этот элемент действительно является последним, что нужно загрузить (для моего поиска в Google это было Показать больше результатов button), затем , пока вы его загрузите в окно просмотра, когда оно загружено, вы сможете определить, когда он появляется на странице. .bottom затем возвращает ненулевое значение (что-то общее с фактическим положением элемента на странице - мне все равно, хотя для моих целей). Я заканчиваю .ScrollIntoView, но это не обязательно.

Смежные вопросы