I am currently having trouble trying to insert text into the website "www.skyvector.com". I've been trying to paste some text in the "Route" field, which appears in a grey box at the top left (usually after clicking 'Flight Plan').
This is the code that I have so far, which has worked for other websites, but strangely not for SkyVector:
Sub test1()
Dim IE As Object
Dim doc As HTMLDocument
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.navigate "http://www.skyvector.com/"
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
Set doc = IE.document
doc.getElementsById("sv_planEditField").Value = "test"
End Sub
Unfortunately, an error appears whenever this line is set to run:
doc.getElementsById("sv_planEditField").Value = "test"
The error is "Run-time error '438': Object doesn't support this property or method".
Been wracking my head for a solution to this, and I couldn't find any solution here as well, specifically for websites that work like SkyVector. I am not exactly sure what the difference is between that and any other website. Thank you very much for your time!
CodePudding user response:
The element sv_planEditField
is not a normal text box. Open it in your browser and inspect it with the developer tools (Press F12). Do this both before and after filling it. You will notice that this is quite different from a standard input. Either recreate the html structure of the filled control or recreate the form submission. Have a look at createElement and appendChild for more information.
CodePudding user response:
First of all, the method name is not getElementsById()
. The name is getElementById()
without the s
for plural. The reason is, an ID should be only used once in a html document, it's unique.
But if you use the right name you will receive the error that there is no object. The reason here is, there is no element with an ID named sv_planEditField
.
So what can you do? You can use another method called getElementsByClassName()
because the html line in question is
<input autocomplete="false" spellcheck="false" class="sv_search" autocorrect="off">
The method getElementsByClassName()
buids a node collection. Therefore it uses the s
for plural. There can be as many elements with the same class name as the developer want. You can get a specific element by it's index like you use it with an array. The clss name sv_search
is only once used in the document. A node collections first index is allways 0
. So you must use the following line of vba code, instead of yours:
doc.getElementsByClassName("sv_search")(0).Value = "test"
Edit
After reading your question again and understand it ;-) and based on the answer of Sam here is the way you can solve your problem. What you need is a new text node and (I think) to trigger the right event to make the input work for the page. Try it with original data.
Sub test1()
Dim IE As Object
Dim textToEnter As Object
Dim nodeToAppendText As Object
Dim nodeText As Object
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.navigate "http://www.skyvector.com/"
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
'Open overlay to enter data
IE.document.getElementsByClassName("sv_topbarlink")(0).Click
'Click textfield to hide helptext and place curser
IE.document.getElementsByClassName("svfpl_helpmessage")(0).Click
'Create a text node which belongs to the document
Set textToEnter = IE.document.createTextNode("Test")
'Get the node you want to append the new text node
Set nodeToAppendText = IE.document.getElementById("sv_planEditField")
'Append the new text node
Set nodeText = nodeToAppendText.appendChild(textToEnter)
'Not sure if it is necessary to trigger an event
'But there are two events in question:
' First one is input
' Second one is keypress
'You must try how it works
Call TriggerEvent(IE.document, nodeToAppendText, "input")
End Sub
If needed use this method to trigger any event:
Private Sub TriggerEvent(htmlDocument As Object, htmlElementWithEvent As Object, eventType As String)
Dim theEvent As Object
htmlElementWithEvent.Focus
Set theEvent = htmlDocument.createEvent("HTMLEvents")
theEvent.initEvent eventType, True, False
htmlElementWithEvent.dispatchEvent theEvent
End Sub