Страницы: 1
RSS
Выявление нового открытого окна браузера IE
 
Добрый день!

Прошу помочь в вопросе взаимодействия браузера с макросом.
Исполнение макроса происходит при уже открытом браузере, то есть, макрос запускается из книги Эксель, а браузер уже открыт заранее на нужном сайте. Открыто строго только одно окно браузера.
В ходе исполнения макроса происходит заполнение веб форм, нажатие кнопок типа submit и др. На последнем этапе макроса нажимается кнопка на сайте, которая приводит к открытию нового отдельного окна браузера (не вкладки, а именно окна). Новое окно открывается с задержкой в 2-5 секунд
Вопрос: можно ли каким-либо образом перехватить момент, когда в конце исполнения макроса открывается еще одно окно браузера, чтобы уже на него отправить команду?

На ум пришел вариант с паузой в исполнении макроса и уже после паузы проверить на количество открытых окон браузера, но проблема в том, что новое окно браузера может открыться с различной задержкой  - может 2 секунды, а может и 5, возможно, даже и больше. В связи с этим, пауза периодически может давать сбой или нужно будет ставить слишком большой интервал паузы.

Перед исполнением макроса, открытый браузер перехватываю при помощи следующего кода:
Код
Const sApplicationName As String = "Internet Explorer"
    Dim oShellWindows As New SHDocVw.ShellWindows
    Dim oIE As SHDocVw.WebBrowser
    Dim bFlag As Boolean
    If oShellWindows.Count = 0 Then
        MsgBox "IE не открыт!", vbCritical
        Exit Sub
    End If
    For Each oIE In oShellWindows
        If oIE.Application = sApplicationName Then
            bFlag = True
            oIE.document.Focus
            Exit For
        End If
    Next oIE
    If bFlag = False Then
        MsgBox "IE не открыт!", vbCritical
        Exit Sub
    End If


Спасибо!
Изменено: footballplayer - 13.08.2017 14:39:36
 
Извиняюсь за поднятие поста в топ своим же ответом.

Почитав форумы, на ум пришла мысль, что для данной задачи можно воспользоваться конструкцией, которая будет проверять условие и если оно не достигнуто, то будет ждать установленное время, а потом опять проверять совершилось ли условие и, если оно совершилось, то запускать код макроса дальше.

Подскажите, пожалуйста, можно ли такую конструкцию составить? Можно ли это сделать при помощи команды Sleep?
 
так?
Код
Sub TT()
Set Web1 = CreateObject("InternetExplorer.Application") 
Web1.Visible = True
Web1.Navigate "адрес сайта"
Do While Web1.ReadyState <> 4: DoEvents: Loop
MsgBox "IE открыт"
'...
End Sub  
это про создание совсем нового окна
но строка 5 отвечает за ожидание, пока страница в новом окне не прогрузится полностью...
***
для sleep()
надо 1-й строкой прописывать
Код
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
P.S.
ваш код, полагаю, отсюда ... в вопрос не вникаю (не считаю оптимальным) - думаю, может есть более рациональные варианты, чем ваш? - грузить html (функция GetHttpResponse), чем считать окна открытые... изучайте трафик вашего сайта через Fiddler...
Изменено: JeyCi - 14.08.2017 09:44:21
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Вариант для ТС такой сойдет:
Код
Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Const LocURL As String = "https://www.google.ru/"
Sub Test()
    Dim oShellWindows As New SHDocVw.ShellWindows
    Dim oIE As SHDocVw.WebBrowser
    If oShellWindows.Count = 0 Then
        MsgBox "IE не открыт!", vbCritical
        Exit Sub
    End If
    Do While True
        For Each oIE In oShellWindows
            If oIE.LocationURL = LocURL Then
                MsgBox "Открыт ГУГЛ!", vbInformation
                oIE.document.Focus
                Exit Do
            End If
        Next oIE
        DoEvents
        Sleep (100)
    Loop
End Sub

Открываем IE, запускаем макрос, вводим ссылку как в константе и ждем результата.
Вместо LocationURL можно использовать LocationName. Все зависит от web-страницы.
 
Jungl, спасибо за ответ!

Расположил Ваш код в конце макроса, т.к. новое окно открывается при окончании макроса и автоматическом нажатии на кнопку на сайте.
То есть, мне необходимо прямо в конце макроса перехватить открытие окна. Но макрос ругается на строку Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long), говоря, что не может в том месте быть Sub. А без этой строчки, насколько я понял, не работает Sleep(100).
Скажите, пожалуйста, как можно интегрировать Ваш код в существующий макрос, чтобы он срабатывал прямо последним в строках кода макроса?
 
footballplayer, операторы Declare необходимо располагать в самом начале модуля, за всеми процедурами/функциями.
Просто перенесите в начало кода.
 
Jungl, спасибо! Теперь все работает :-)

Но теперь возникла новая проблема :-)
Макрос срабатывает при открытии нового окна в IE с соответствующим URL, но, видимо, макрос видит новое окно уже на уровне процессов, а визуально новое окно браузера открывается чуть попозже, секунд через 5-10, по-разному каждый раз. И с новым окном сразу открывается маленькое окошко печати в IE.

Подскажите, пожалуйста, можно ли отследить именно визуальное открытие нового окна IE? Пробовал доработать Ваш макрос так (вставив проверку Wifth и Height браузера так:

Код
eclare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Const LocURL As String = "https://www.google.ru/"
Sub Test()
    Dim oShellWindows As New SHDocVw.ShellWindows
    Dim oIE As SHDocVw.WebBrowser
    If oShellWindows.Count = 0 Then
        MsgBox "IE не открыт!", vbCritical
        Exit Sub
    End If
    Do While True
        For Each oIE In oShellWindows
            If oIE.LocationURL = LocURL Then
                If IE.Width > 100 and IE.Height > 100 then
                IE.document.Focus
                Application.Sendkys "{ENTER}"
                Exit Do
            End If
        Next oIE
        DoEvents
        Sleep (100)
    Loop
End Sub

Но этот метод не сработал)

И, если можно, вопрос: может ли VBA получить данные о том, что окно печати в IE открыто? Тогда все стало бы намного проще.

Спасибо!
Изменено: footballplayer - 15.08.2017 00:19:58
 
И Вас компилятор не послал искать отсутствующий end if ?
Можно так отследить загрузку окна.Где elem-это любой элемент нового документа, который гарантировано будет при полной загрузке документа.
Код
    If oIE.LocationURL = LocURL Then
     set elem=IE.document.getElementById("MMM")
     Do While elem is nothing
        set elem=IE.document.getElementById("MMM")
              doevents
              'Сделать паузу  1/10 секунды
     loop
         IE.document.Focus
         Application.Sendkys "{ENTER}"
        Exit Do
    End If
PS:Мне внутренний голос подсказывает, что большую часть телодвижений можно сделать запросами без браузера.
Браузеру оставить роль печати файла.
Изменено: Doober - 15.08.2017 01:26:02
 
Doober, все равно не хочет отправлять SendKeys :-)

Уже не знаю что с этим делать) Прошелся по разным форумам - итог тот же.
Потом на ум пришла мысль получить в макросе окно печати IE и проверив его существование, отправить на него SendKeys. Но нигде так и не нашел как проверяется наличие открытого диалогового окна печати IE.

Проблема в том, что макрос на последнем этапе нажимает кнопку, после нажатия которой в браузере открывается новое окно и автоматически это окно открывается с уже открытым диалоговым окном печати IE и остается только нажать ENTER, чтобы печать началась. Но мне уже который день не удается отследить открытие окна и нажать эту кнопку ENTER при помощи SendKeys.

Новое окно в браузере открывается на весь экран. Если попробовать проверить новое окно по размерам и отправить SendKeys - это реально? То есть, если ширина и высота окна браузера больше, к примеру, 100, то фокус на окне и отправка SendKeys? Я попробовал сам провернуть такое, но не получилось( Может это технически невозможно в VBA?
 
Цитата
Doober написал:
PS:Мне внутренний голос подсказывает, что большую часть телодвижений можно сделать запросами без браузера.
Браузеру оставить роль печати файла.
Это направление не рассматривали?
 
Doober, нет, сказать честно, не рассматривал, т.к. знаний в VBA пока не так много и до такого уровня не дошел)
Но мне что-то подсказывает, что при помощи GET или POST запросов в моем случае не  обойтись, т.к. в ходе заполнения форм приходится пару раз переходить на новую страницу, плюс ко всему, как я понимаю, HTML код сайта подгружается динамически, через :JS.

В принципе, сам макрос работает нормально, проблема осталась лишь в том, чтобы нажать кнопку Enter в нужное время, при появлении нового окна IE )
Страницы: 1
Читают тему
Наверх