Страницы: 1
RSS
Ошибка -2147352319 при использовании parentWindow.execScript
 
Добрый вечер, уважаемые участники форума!

Прошу помочь в решении вопроса.
Написал небольшой макрос, который работает с веб-формой. Чтобы поля становились сразу валидными, заполняю их по таким способом:
Код
oie.document.parentWindow.execScript "angular.element('[data-ng-model=""text""]').scope().text = 'какой-либо текст';"
oie.document.parentWindow.execScript "angular.element('[data-ng-model=""text""]').scope().$apply();" '
Заполнение полей таким образом работает, в общем, нормально, но периодически возникает ошибка такого вида "Run-time error: -2147352319 (80020101) ".
Таких ошибок (с таким номером) ранее не встречал и на просторах интернета понятного объяснения так же не нашел, хотя, возможно, плохо искал.
Насколько я понял, эта ошибка означает, что код не дождался появления в HTML коде свойств, которые ему необходимо заполнить и ушел в ошибку. Или я не прав?
Пытался сделать цикл с проверкой существования кода  oie.document.parentWindow.execScript "angular.element('[data-ng-model=""text""]') применого так:
Код
IsObject( oie.document.parentWindow.execScript "angular.element('[data-ng-model=""text""]'))

но VBA такого не понимает и выдает ошибку...

Подскажите, пожалуйста, можно ли как-либо решить данную ошибку проверкой в коде нужного свойства или как-либо по-другому?

Спасибо!
 
footballplayer, on error resume next + пауза + цикл
 
Jungl, спасибо за ответ.
Если возможно, хотелось бы обойтись без паузы, т.к. скорость работы - основная необходимость макроса)
Скажите, пожалуйста, я правильно понимаю , что указанная ошибка возникает в связи с тем, что макрос опережает  загрузку элементов HTML сайта и в связи с этим не найдя поле для заполнения уходит в ошибку?  
 
Цитата
footballplayer написал: хотелось бы обойтись без паузы
Вы неверно поняли слово 'пауза'. Это не минуты и даже не секунды. DoEvents будет достаточно
Согласие есть продукт при полном непротивлении сторон
 
Sanja,  спасибо за ответ.

Если Вам несложно, могли бы вы на основе куска кода, приложенного вначале темы, показать как правильно составить конструкцию, о которой Вы говорите. Честно сказать не силен в построении таких конструкций.  
 
footballplayer, попробуйте
Код
On Error Resume Next
Do While True
oie.document.parentWindow.execScript "angular.element('[data-ng-model=""text""]').scope().text = 'какой-либо текст';"
If Err.Number = 0 Then
    On Error GoTo 0
    Exit Do
End If
DoEvents
Loop
 
Jungl,  спасибо за ответ.
Если Вам несложно, объясните, пожалуйста для понимания процесса два момента.

1. Правильно ли я понимаю, что данная конструкция означает, что выход из цикла будет выполнен, если в течение этого цикла не было ошибок
Код
On Error GoTo 0
ExitDo

А как себя поведет данный код, если возникнет ошибка с номером, указанная в начале темы? Макрос остановится и выдаст окно ошибки?

2. Правильно ли я понимаю, что процесс заполнения в поля формы, код которого указан ниже, возвращает True?
Код
oie.document.parentWindow.execScript "angular.element('[data-ng-model=""text""]').scope().text = 'какой-либо текст';"
 
footballplayer, может проверять готовность браузера как описано тут (кстати, про футбол :))?
https://stackoverflow.com/questions/17480369/vba-hanging-on-ie-busy-and-readystate-check
 
Казанский, спасибо за ответ.

Готовность браузера  данном случае работает не совсем корректно, т.к. изменения на сайте происходят динамически и, как я понимаю, в данном случае через ReadyStatec= 4 готовность HTML кода отследить корректно не получается.
 
footballplayer,
1.  Не совсем, там прописано условие, если Err.Number = 0, т.е. ошибок нет, то сбрасываем в операторе On Error существующую запись об ошибке и выходим из цикла.
По моей логике, у вас ошибка вылетает, когда вы пытаетесь присвоить значение объекту, а он еще не прогрузился.
После выхода из цикла у вас должна быть следующая строка кода с Apply, как подтверждение ввода. Вы бы проверили, я ни в чем не уверен, все зависит от веб страницы.
2.  Ничего оно там не возвращает, разве что свойства объекта.
3.  Ссылки будут или дальше сами? :)
Изменено: Jungl - 01.01.2018 19:05:10
 
Jungl, спасибо за ответ.
К сожалению, показать сам сайт в качестве примера сейчас не смогу, т.к. там специфическая форма входа.
Понимаю, что без примера говорить о чем-то очень сложно)

Код приведенный вами, понял, разобрал. :
Код
On Error Resume Next
Do While True
oie.document.parentWindow.execScript "angular.element('[data-ng-model=""text""]').scope().text = 'какой-либо текст';"
If Err.Number = 0 Then
    On Error GoTo 0
    Exit Do
End If
DoEvents
Loop

Это как раз именно то, что мне нужно. Но возникла проблема.
Для проверки делал так: запускал кусок макроса для заполнения одного отдельного поля в то время, когда сайт открыт в том месте, где этого поля нет. Потом перехожу на страницу, где есть заполняемое поле. Поле корректно заполняется, но выход из цикла не происходит и в цикле повторяется ошибка (как я увидел в debug.print), ошибка даже после заполнения формы не исчезает и цикл бесконечно выполняется.

Попробовал доработать код так, чтобы происходил выход из цикла, когда в заполняемом поле появляется текст с длиной более нескольких символов:
Код
On Error Resume Next
Do While True
oie.document.parentWindow.execScript "angular.element('[data-ng-model=""text""]').scope().text = 'какой-либо текст';"


For Each aa In oie.document.getElementsByTagName("input")
If aa.getAttribute("data-ng-model") = "text" Then
If Len(aa.Value) > 0 Then

Exit Do
End If
End If
Next aa

If Err.Number = 0 Then

On Error GoTo 0
Exit Do

End If
DoEvents
Loop

Скажите, пожалуйста, такой способ выхода из цикла корректен? Фактически это срабатывает, но волнует момент - не снижает ли такая конструкция работу макроса на среднем ПК?
Возможно, можно как-то по-другому выйти из цикла:
Код
On Error Resume NextDo While True
oie.document.parentWindow.execScript "angular.element('[data-ng-model=""text""]').scope().text = 'какой-либо текст';"
If Err.Number = 0 Then
    On Error GoTo 0
    Exit Do
End If
DoEvents
Loop

Если это возможно, то данный вариант был бы идеально подходящим для меня.
Изменено: footballplayer - 01.01.2018 19:05:44
 
Код
On Error Resume Next
Do
  Err.Clear
  oie.document.parentWindow.execScript "angular.element('[data-ng-model=""text""]').scope().text = 'какой-либо текст';"
  DoEvents
Loop While Err.Number
On Error GoTo 0
Изменено: AAF - 27.12.2017 05:41:50
 
AAF, спасибо за ответ!
Указанный Вами код помог в решении вопроса. Заполнение полей происходит без ошибок. Спасибо!

Jungl,  чуть доработал указанный Вами код с добавлением Err.Clear, код так же работает отлично, заполнение происходит без ошибок.
Код
On Error Resume Next
Do While True
Err.clear
oie.document.parentWindow.execScript "angular.element('[data-ng-model=""text""]').scope().text = 'какой-либо текст';"
If Err.Number = 0 Then
    On Error GoTo 0
    Exit Do
End If
DoEvents
Loop


Большое спасибо всем за помощь!
 
footballplayer, Err.Clear значительно быстрее, чем Err.Number = 0, хотя в Вашем случае это значения не играет, но я так... для общего представления
 
AAF, подскажите, пожалуйста, почему данная пауза не срабатывает в следующем случае:
Код
On Error Resume Next
Do While True
Err.Clear

For Each text_item In oie.document.getElementsByClassName("textbox")
MsgBox text_item.innerText
Next text_item

If Err.Number = 0 Then
    On Error GoTo 0
    Exit Do
End If
DoEvents
Loop

Делаю так: запускаю данный код, когда браузер находится на сайте, где класса "textbox" в HTML коде нет. Соответственно, код запускается и повторяется в цикле, т.к. нужного имени класса в HTML коде нет.
После этого перехожу в браузере на сайт, где имя класса "textbox" и, как я понимаю, при загрузке HTML кода, где есть данное имя класса тега, код должен при очередном прохождении цикла увидеть, что есть нужный класс и вывести его текст через  MsgBox text_item.innerText.
Однако, этого не происходит. Даже после полной загрузке сайта код продолжает выполняться в цикле бесконечно, не замечая, что нужное имя класса уже существует.
Возможно, я что-то делаю не так?
Изменено: footballplayer - 31.12.2017 23:12:30
 
Код
If Err.Number = 0 Then
    On Error GoTo 0
    Exit Do
End If

Засунте в For Each
Страницы: 1
Наверх