带有 VBA 输入事件的 Internet Explorer 自动化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10191506/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Internet Explorer Automation with VBA input events
提问by Dkellygb
am trying to use automation in from Microsoft Access 2003 to control Internet Explorer 9 to complete a form using database data.
我正在尝试使用 Microsoft Access 2003 中的自动化来控制 Internet Explorer 9 以使用数据库数据完成表单。
The input fires an event in the browser which validates the data and makes the save button visible. If I use sendkeys the event is triggered; however, I have found sendkeys to be very unreliable. If I change the value of the element and then use .fireevent ("onchange"), nothing happens – not even an error.
输入在浏览器中触发一个事件,该事件验证数据并使保存按钮可见。如果我使用 sendkeys,则触发事件;但是,我发现 sendkeys 非常不可靠。如果我更改元素的值,然后使用 .fireevent ("onchange"),则不会发生任何事情 - 甚至不会出现错误。
My question is, how do I fire the event. Or, how can I find out what javascript is running. Is there a debug type of addin for IE which will tell me what event is fired? If so, can I just run the script myself?
我的问题是,如何触发事件。或者,我如何找出正在运行的 javascript。是否有调试类型的 IE 插件会告诉我触发了什么事件?如果是这样,我可以自己运行脚本吗?
My code is below.
我的代码如下。
Set IE = CreateObject("internetexplorer.application")
IE.Visible = True
IE.Navigate "https://extranet.website.com/Planning/Edition/Periodic?language=en"
Do While IE.ReadyState <> 4 Or IE.Busy = True
DoEvents
Loop
'log in
If IE.Document.Title = "website- access" Then
IE.Document.getElementById("login_uid").Value = "username"
IE.Document.getElementById("login_pwd").Value = "password"
IE.Document.all("ButSubmit").Click
Do While IE.ReadyState <> 4 Or IE.Busy = True
DoEvents
Loop
End If
Do While Not RstAvailability.EOF
StartDate = RstAvailability!AvailDate
IE.Document.getElementById("periodStart").Value = Format(StartDate, "dd mmm yy")
IE.Document.getElementById("periodEnd").Value = Format(StartDate, "dd mmm yy")
Set LinkCollection = IE.Document.GetElementsByTagName("A")
For Each link In LinkCollection
If link.innertext = "Add" Then
link.Click
Exit For
End If
Next
Do While IE.ReadyState <> 4 Or IE.Busy = True
DoEvents
Loop
Set objRows = IE.Document.GetElementsByTagName("tr")
If RstAvailability!RoomType = "DTW" Then
n = 0
While n < objRows.Length
If Trim(objRows(n).Cells(0).innertext) = "Single Room" Then
For i = 1 To 7
'objRows(n).FireEvent ("onchange")
'objRows(n).Cells(i).GetElementsByTagName("input")(0).Focus
'SendKeys Format(RstAvailability!roomcount - RstAvailability!RoomsSold, "0") & "{TAB}"
objRows(n).Cells(i).GetElementsByTagName("input")(0).Value = Format(RstAvailability!roomcount - RstAvailability!RoomsSold, "0")
objRows(n).Cells(i).GetElementsByTagName("input")(0).fireevent ("onchange")
Do While IE.ReadyState <> 4 Or IE.Busy = True
DoEvents
Loop
Next i
End If
n = n + 1
Wend
End If
Set objButtons = IE.Document.getelementsbyname("savePlanning")
objButtons(0).Click
Do While IE.ReadyState <> 4 Or IE.Busy = True
DoEvents
Loop
newtime = Now + TimeValue("0:00:10")
Do While True
If Now > newtime Then Exit Do
Loop
RstAvailability.MoveNext
Loop
The html of the input fields are:
输入字段的html是:
<tr class="first" roomId="30494" articleId="0" type="Availability" readonly="False">
<div>
<span class="roomName">
Single Room
</span>
</div>
<span class="data">
<input id="Availabilities" name="Availabilities" type="text" value="" />
</span>
<span class="data">
<input id="Availabilities" name="Availabilities" type="text" value="" />
</span>
Thanks!
谢谢!
回答by Dkellygb
After sweating over this for a few days, the answer was actually very simple but nearly impossible to find in any documentation on MSDN or anywhere else on the web.
经过几天的努力,答案实际上非常简单,但几乎不可能在 MSDN 上的任何文档或网络上的任何其他地方找到。
Before you change the value of the input field, you net to set the focus on that field. After you change the value, you need to set the focus to another field. Apparently, the events fire on the loss of focus. Therefore, the code should look like this:
在更改输入字段的值之前,您需要将焦点设置在该字段上。更改值后,您需要将焦点设置到另一个字段。显然,这些事件是在失去焦点时引发的。因此,代码应如下所示:
n = 0
While n < objRows.Length
If Trim(objRows(n).Cells(0).innertext) = "Family Room" Then
For i = 1 To 7
objRows(n).Cells(i).GetElementsByTagName("input")(0).Focus
objRows(n).Cells(i).GetElementsByTagName("input")(0).Value = Format(RstAvailability!roomcount - RstAvailability!RoomsSold, "0")
Next i
objRows(n).Cells(1).GetElementsByTagName("input")(0).Focus
End If
n = n + 1
Wend
The way I found this was by looking at some MSDN documentation about accessibility for IE9. It was advising on setting the focus for disabled users. I just thought I would give this a try and it worked. I hope this helps someone else.
我发现这一点的方法是查看一些有关 IE9 可访问性的 MSDN 文档。它建议为残疾用户设置焦点。我只是想我会尝试一下,它奏效了。我希望这对其他人有帮助。
Dave
戴夫
回答by Angel
If you want (in IE9) to put the following line right before line "Next i". it should also work even if you do not loose the focus?
如果您想(在 IE9 中)将以下行放在“Next i”行之前。即使您没有失去焦点,它也应该起作用吗?
objRows(n).Cells(i).GetElementsByTagName("input")(0).Click
objRows(n).Cells(i).GetElementsByTagName("input")(0).Click