Filling web form fields but web page unable to detect text - excel

I'm filling a web form using VBA, and I am able to fill text in the inputbox, but the webpage still is unable to detect the text and shows an error:
"Error: Required Field - Please provide an answer"
Set objIE = CreateObject("InternetExplorer.Application")
objIE.Visible = True
URL = "https://npc.collegeboard.org/app/dartmouth/start"
objIE.Navigate URL
objIE.Document.getElementById("student.firstName").Focus
objIE.Document.getElementById("student.firstName").Value = "Tom"
Looks like theres some AngularJS running in the background, and it can't detect text fed in my VBA. Any help would be highly appreciated.

First of all after objIE.Navigate URL you should wait until the website is fully loaded and the IE is ready. This is done with the following:
objIE.Navigate URL 'this needs some time but VBA will continue excecuting the next statement qickly
Const READYSTATE_COMPLETE As Integer = 4
Do While objIE.Busy Or objIE.ReadyState <> READYSTATE_COMPLETE
DoEvents
Loop
'now IE is ready and the page is loaded.
But it might be that some JavaScript is not ready yet and this is not recognized by objIE.Busy Or objIE.ReadyState. So you can do a workaround:
Dim Obj As Object
Do While Obj Is Nothing
On Error Resume Next
Set Obj = objIE.Document.getElementById("student.firstName")
On Error GoTo 0
Loop
'now `student.firstName` is accessible, and probably all the other fields are too.
This will try to access the field student.firstName if it is not there it will error. We suppress the error message using On Error Resume Next and jump back to TryAgain until it was found.
Note that this has one disadvantage: If there is a problem loading this site it will get stuck in this loop. So I recommend to get a timed cancel criterium like if this takes more than a minute cancel it and throw a error message.
Something like the following should work:
Option Explicit
Sub test()
Dim objIE As Object
Set objIE = CreateObject("InternetExplorer.Application")
objIE.Visible = True
Dim URL As String
URL = "https://npc.collegeboard.org/app/dartmouth/start"
objIE.Navigate URL
Const READYSTATE_COMPLETE As Integer = 4
Do While objIE.Busy Or objIE.ReadyState <> READYSTATE_COMPLETE
DoEvents
Loop
Dim Obj As Object
Do While Obj Is Nothing
On Error Resume Next
Set Obj = objIE.Document.getElementById("student.firstName")
On Error GoTo 0
Loop
objIE.Document.getElementById("student.firstName").Focus
objIE.Document.getElementById("student.firstName").Value = "Tom"
End Sub

Related

VBA Internet Explorer - Object variables disappear

I am trying to learn web scraping with VBA and i am running into an issue in the most basic first step.
The problem (I think) is that after IEObject.Navigate is performed, all the variables of IEObject dissapear. So I get the error
"Run-time error '426': The remote server machine does not exist or is
unavailable"
on line 8. Any help is appreciated.
Code:
Sub VBAWeb()
Dim IEObject As InternetExplorer
Set IEObject = New InternetExplorer
IEObject.Visible = True
IEObject.Navigate URL:="https://google.com"
Do While IEObject.Busy = True Or IEObject.ReadyState <> READYSTATE_COMPLETE
Application.Wait Now + TimeValue("00:00:01")
Loop
Debug.Print IEObject.LocationURL
End Sub
I suggest you try to run code below on your side may help to fix the issue.
Sub demo()
Dim URL As String
Dim IE As Object
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
URL = "https://www.microsoft.com"
IE.Navigate URL
Do While IE.ReadyState = 4: DoEvents: Loop
Do Until IE.ReadyState = 4: DoEvents: Loop
Debug.Print IE.LocationURL
Set IE = Nothing
End Sub
You can see that the IE object was created differently. Also, the loop is a little bit different.

Engage with widget on IE by VBA

I haven't really tried working on this before, so I have no idea what I am doing at the moment. I have limited knowledge of html so not sure whether I am doing right. Basically what I aim to do is opening the Internet explorer by macro, changing some elements based id and click submit button on the website to show the data. Then I need keep working on the next step.
As you can see from the code I was trying to engage with the widget on IE by id number from html codes.
Sub Automate_IE_Enter_Data()
'This will load a webpage in IE
Dim i As Long
Dim URL As String
Dim IE As Object
Dim objbutton As Object
'Create InternetExplorer Object
Set IE = CreateObject("InternetExplorer.Application")
'Set IE.Visible = True to make IE visible, or False for IE to run in the background
IE.Visible = True
'Define URL
URL = "http://cfpsg1/plant/Reports/ScrapReport.aspx"
'Navigate to URL
IE.Navigate URL
' Statusbar let's user know website is loading
Application.StatusBar = URL & " is loading. Please wait..."
' Wait while IE loading...
'IE ReadyState = 4 signifies the webpage has loaded (the first loop is set to avoid inadvertantly skipping over the second loop)
Do While IE.ReadyState = 4: DoEvents: Loop
'Webpage Loaded
Application.StatusBar = URL & " Loaded"
IE.Document.getelementbyid("1stGroupBy").Value = "3"
'Find & Fill Out Input Box
IE.Document.getelementbyid("PageContent_uxStartDate").Value = "06/21/2019"
IE.Document.getelementbyid("PageContent_uxEndDate").Value = "06/21/2019"
Set objbutton = IE.Document.getelementbyid("PageContent_btnQuery")
objbutton.Focus
objbutton.Click
Set IE = Nothing
Set objElement = Nothing
Set objCollection = Nothing
End Sub
First thing first the webpage popped up but nothing changed of widgets besides an
error message "method 'Document' of object 'IWebBrowser 2' failed"
show on IE.Document.getelementbyid("1stGroupBy").Value = "3" row.
You are trying to interact with a dropdown so you want syntax such as
IE.Document.querySelector("[value='3']").Selected = True
You could also use
IE.Document.querySelector("#1stGroupBy").SelectedIndex = 2 'change to appropriate index
Error "method 'Document' of object 'IWebBrowser 2' failed" may be due to Integrity level
You can try below mentioned code by changing Integrity level as Medium
Dim IE As InternetExplorer
Set IE = New InternetExplorerMedium
IE.Visible = True
URL = "http://cfpsg1/plant/Reports/ScrapReport.aspx"
IE.Navigate URL
Do While IE.ReadyState <> READYSTATE_COMPLETE
DoEvents
Loop
and try other line of codes to avoid this issue also please refer Here
Please add ref Microsoft Internet Controls and Microsoft HTML Object Library based on your req

getElementById won't work in VBA, error 438

I am relatively new at VBA (I know the basics, but not much else) and I am trying to get some code set up that will fill out online forms for me, but when I run my code I get a 438 error:
object doesnt support this property or method
when it gets to
ie.document.getElementById ("q")
I have added the HTML object library and Microsoft internet controls to my references. I have looked at tons of online forums. I have even copied and pasted an entire script directly into VBA. Nothing will make it use getElementById(). Here is my code:
Sub internetstuff()
Dim ie As Object
Set ie = CreateObject("internetexplorer.application")
ie.Visible = True
ie.navigate ("https://www.google.com/")
Set searchbx = ie.document.getElementById("q")
searchbx.Value = "Howdy!"
End Sub
What should happen is that it should open InternetExplorer, go to Google, and populate the search bar with "Howdy!".
Instead, It only opens google, then I get the error message and it stops running.
Because "q" is not an ID, it's a Name.
You have to use GetElementsByName and select the 1st Element
try this:
Sub internetstuff()
Dim ie As Object
Set ie = CreateObject("internetexplorer.application")
ie.Visible = True
ie.Navigate ("https://www.google.com/")
Do Until ie.ReadyState >= 4
DoEvents
Loop
Set searchbx = ie.document.getElementsByName("q")(0)
searchbx.Value = "Howdy!"
End Sub
I have also added a waiting Event, in case it takes time to load Google.
Result:
A more concise and efficient way is to use querySelector to return first match for the name attribute
Option Explicit
Public Sub internetstuff()
Dim ie As Object
Set ie = CreateObject("InternetExplorer.Application")
With ie
.Visible = True
.Navigate2 "https://www.google.com/"
While .Busy Or .readyState < 4: DoEvents: Wend
.document.querySelector("[name=q]").Value = "Howdy"
Stop '<delete me later
.Quit
End With
End Sub

VBA IE.Document empty error

I've been running a query for a while now getting data from a webpage. After numerous runs it has decided to stop working, and I've traced the issue back to the ie.document object - it never returns anything.
When compiling my project I see that the "Document" element of ie returns an error of "Applicaiton-defined or Object-defined error" - even before I navigate to a webpage. Also some other elements return this error also - namely "Status Text" and "Type"
The link contains a screenshot of my error:
https://www.dropbox.com/s/wcxxep8my10nu8h/vba%20ie%20document.jpg?dl=0
In case that doesn't work here a scaled back version of the code I'm running
Sub getCard()
Dim ie As InternetExplorer
Dim url1 As String
url1 = "google.com"
Set ie = New InternetExplorer
ie.Visible = True
ie.Navigate url1
WaitBrowserQuiet ie
End Sub
Sub WaitBrowserQuiet(objIE As InternetExplorer)
Do While objIE.Busy Or objIE.ReadyState <> READYSTATE_COMPLETE
DoEvents
Loop
End Sub
As soon as I get to the "Set ie = New InternetExplorer" part of the code is when the ie object is created and I see the errors. If I do happen to navigate to webpage, then the ie.document object is empty.
I've searched around and tried a few things to stop this happening - restarted my computer, run "ie.quit" and "Set ie = Nothing", reset my Internet Explorer, etc... Nothing seems to work.
It seems like it may be a deeper issue given I'm getting an error message even before navigating to a webpage. Hope someone knows how to stop the error.
Your URL is URL1, try changing that, or just putting the URL in there.
In your code you have the object "ie" locally defined in the sub getCard and when this sub finishes,so goes the binding. Also changing from private to public internet zones can remove the binding to that object. What I rather do is use a global object appIE and then when it runs into such an error I catch the error (if TypeName(appIE) = "Object" Then FindIE) and find the object again with this sub:
Sub FindIE() 'Needs reference to "Microsoft Shell Controls And Automation" from VBA->Tools->References
Dim sh
Dim eachIE
Dim SearchUntil
SearchUntil = Now() + 20 / 24 / 60 / 60 'Allow to search for 20 seconds otherwise it interrupts search
Do
Set sh = New Shell32.Shell
For Each eachIE In sh.Windows
If InStr(1, eachIE.LocationURL, ServerAddress) Then
Set appIE = eachIE
'IE.Visible = False 'This is here because in some environments, the new process defaults to Visible.
'Exit Do
End If
Next eachIE
If TypeName(appIE) <> "Object" Then
If InStr(1, appIE.LocationURL, ServerAddress) > 0 Or SearchUntil < Now() Then Exit Do
End If
Loop
Set eachIE = Nothing
Set sh = Nothing
End Sub
This code contains parts of other people here from stackoverflow, but I forgot who to credit for some essential parts of the code. Sorry.

VBA error when navigating with Internet Explorer

I am trying to download a table of proprietary investments/positions/pricing from Nationwide. The code seems to do what I want, EXCEPT for producing an "object required" error when I attempt to select a particular account (click)
I thought I had the proper code to tell my macro to wait until IE was ready to go on, but clearly I am missing something.
In the code, the relevant line is highlighted. If I enter a STOP above the error line, I can wait until I "see" the link appear, then "continue" the code and it runs as expected.
Because this goes to my financial accounts, I cannot provide the user name and password to allow someone to replicate the exact problem, but here is the code, and the error message and highlight. Suggestions appreciated.
Option Explicit
'set Reference to Microsoft Internet Controls
Sub DownLoadFunds()
Dim IE As InternetExplorer
Dim sHTML
Const sURL As String = "https://www.nationwide.com/access/web/login.htm"
Const sURL2 As String = "https://isc.nwservicecenter.com/iApp/isc/app/ia/balanceDetail.do?basho.menuNodeId=12245"
Dim wsTemp As Worksheet
Set wsTemp = Worksheets("Scratch")
Set IE = New InternetExplorer
With IE
.Navigate sURL
.Visible = True 'for debugging
Do While .ReadyState <> READYSTATE_COMPLETE
DoEvents
Loop
Do While .Busy = True
DoEvents
Loop
'Login: User Name and Password "remembered" by IE
.Document.all("submitButton").Click
Do While .ReadyState <> READYSTATE_COMPLETE
DoEvents
Loop
Do While .Busy = True
DoEvents
Loop
'Select this account to show
.Document.all("RothIRA_#########").Click '<--Error at this line
Do While .ReadyState <> READYSTATE_COMPLETE
DoEvents
Loop
Do While .Busy = True
DoEvents
Loop
.Navigate sURL2
Do While .ReadyState <> READYSTATE_COMPLETE
DoEvents
Loop
Do While .Busy = True
DoEvents
Loop
Set sHTML = .Document.GetElementByID("fundByFundOnly")
With wsTemp
.Cells.Clear
.Range("a2") = sHTML.innertext
End With
.Quit
End With
Set IE = Nothing
End Sub
This is the error message:
This shows the highlighted line:
EDIT:
At Tim Williams suggestion, I added a loop to test for the presence of the desired element. This seems to work:
...
On Error Resume Next
Do
Err.Clear
DoEvents
Application.Wait (Time + TimeSerial(0, 0, 1))
.Document.getelementbyid("RothIRA_#########").Click
Loop Until Err.Number = 0
On Error GoTo 0
....
IE.Document.all("#RothIRA_....") is returning Nothing (null in more refined languages), so calling the Click method is causing the error.
Your code is the same as doing this:
Dim rothElement As Whatever
rothElement = IE.Document.all("#RothIRA_....")
rothElement.Click
...when you should do this:
Dim rothElement As Whatever
rothElement = IE.Document.all("#RothIRA_....")
If rothElement <> Nothing Then
rothElement.Click
End If
I suggest using the modern document.GetElementById method instead of the deprecated (if not obsolete) document.All API.
It's possible/likely that the page is using script to dynamically load some content or generate some layout after your "wait" loop has finished. That loop only waits until all linked content/resources have been loaded - it does not wait for scripts on the loaded page to finish, etc.
One approach is to loop your code waiting for the desired element to be rendered:
Const MAX_WAIT_SEC as Long = 5 'limit on how long to wait...
Dim t
t = Timer
Do While .Document.all("RothIRA_#########") Is Nothing
DoEvents
'or you can Sleep here
If Timer - t > MAX_WAIT_SEC Then Exit Do
Loop
'carry on...

Resources