VBA + IE Automation - can't get Element ID - vba

I am trying to scrape some information from an internal company website. My code is able to launch a new IE window and navigate successfully to the page but when I try and input data into a box I keep getting errors.
I've switched various things around based off the posts i've read but always get some sort of error.
For the code posted below it's this error on the last line:
Object Variable or With Block Not Set
Here is my code:
Sub PerformancePull()
Dim appIE As Object
Dim sURL As String
Dim StartDate As Variant
Dim MyDoc As HTMLDocument
Set appIE = New InternetExplorerMedium
sURL = "website"
With appIE
.navigate sURL
.Visible = True
End With
Do While appIE.readyState <> READYSTATE_COMPLETE
DoEvents
Loop
Set MyDoc = appIE.document
Set StartDate = MyDoc.getElementById("ct100_assoc_tbEndDate")
StartDate.Value = "3/25/2020"
End Sub
Edit:
Here's a piece of the HTML code that identifies the ID I'm trying to capture:

Try the following
Remove this
Set StartDate = MyDoc.getElementById("ct100_assoc_tbEndDate")
StartDate.Value = "3/25/2020"
And replace it with this
With MyDoc
.getElementById("ct100_assoc_tbEndDate").Value = "3/25/2020"
End With

I tried to test your code on my side and it worked fine without any error. Below is the testing result.
I suggest you try to access the element and assign the value like below to check whether it works or not.
appIE.document.getElementById("ct100_assoc_tbEndDate").Value = "3/25/2020"
Let us know about your testing results if the issue persists then we will try to provide further suggestions.

Related

Cant download a scorecard from pgatour.com

I've searched throughout the site here to improve my simple code, but continue to have an error 424 at the set allRowofdata line, which I gleaned from here. I'm just trying to load a golfers scorecard into my excel spread. I appreciate any help I can get.
Here's my code:
Note: based on advise from below, I've changed my code to the below, but now get a type mismatch error at set allRowOfData.
Sub Trial()
Dim IE As InternetExplorer
Dim allRowOfData
Dim document As Object
Set IE = New InternetExplorer
IE.Visible = False
IE.navigate "https://www.pgatour.com/players/player.32757.patton-kizzire.html/scorecards/r457"
Do Until IE.readyState = 4: DoEvents: Loop
Set allRowOfData = IE.document.getElementById("module-1510443455695-953403-17")
Dim myValue As String: myValue = allRowOfData.Cells().innerHTML
IE.Quit
Set IE = Nothing
Range("A1").Value = myValue
End Sub
I think you've set the page element before it gets a chance to load on the page, therefore 'allRowOfData' remains nothing.
Consider replacing this:
Application.Wait Now + TimeSerial(0, 0, 1)
With:
Do Until IE.ReadyState = 4: DoEvents: Loop
Or alternatively (inefficient but can't see any reason why it wouldn't work):
Do until not(allRowOfData is nothing)
Do events
Set allRowOfData = IE.document.getElementById("#module-1510443455695-953403-17")
Loop
The above assumes your usage of .getElementByID method is correct. Untested, written on mobile.
Edit 1:
See if changing this
Dim allRowOfData
To this
Dim allRowOfData As IHTMLElement
Works.
Before you re-run code, in VBA editor, click Tools > References and add a reference to the Microsoft HTML Object Library (scroll down and tick it).
Type Mismatch would suggest we're assigning something to a variable of the wrong type, so let's get rid of the implicit variant.
I haven't been able to examine the code's HTML source as I'm on mobile. It may be the case though that the specific element that you want is created subsequent to the page's initial loading (in which case you may need to use the inefficient alternative above), or that you need to iterate through a IHTMLElementCollection to get at the information. All depends on the page's structure and loading behaviour.

VBA: Run-time error 424: Object required when trying to web scrape

I'm trying to update various fund sizes using morgninstar.co.uk. The code worked fine until it suddenly stopped and gave an error:
"Run-time error 424: Object required".
The exact line where the error occurs is:
Set allData = IE.document.getElementById("overviewQuickstatsDiv").getElementsByTagName("tbody")(0)
The idea is to ultimately scan the whole "tbody"-tag and look for the line "Fund Size" inside "tr" and "td"-tags. When "Fund Size" is found, the code would return the 3rd "td"-tag (actual fund size).
After this I'd add a loop to loop through a list of funds that I've got.
As the code stopped working completely, I haven't got this far yet. Here I'm just trying to check if the code returns the actual fund size.
Since there are not always 3 "td"-tags inside the "tr"-tags, I'll still have to construct some sort of IF-statement to fix that issue.
But for now I'd just want to know how I could get the code running again? I've spent great deal of time searching for an answer but as it seems that this is a variable type problem the solution depends on the situation.
I'm using Excel 2010 and Internet Explorer 11.
URL in easy form to copy-paste:
http://www.morningstar.co.uk/uk/funds/snapshot/snapshot.aspx?id=F0GBR04BKW
Sub testToScrapeWholeTbodyTag()
'Microsoft Internet Controls
'Microsoft HTML Object Library
'Microsoft Shell Controls and Automation
'======Opens URL======
Dim IE As Object
Set IE = CreateObject("internetexplorer.application")
With IE
.navigate "http://www.morningstar.co.uk/uk/funds/snapshot/snapshot.aspx?id=F0GBR04BKW"
.Visible = False
End With
While IE.Busy
DoEvents
Wend
'======Got from internet, fixed a previous error. However, I'm not 100% sure what this does======
Dim sh
Dim eachIE As Object
Do
Set sh = New Shell32.Shell
For Each eachIE In sh.Windows
If InStr(1, eachIE.LocationURL, "http://www.morningstar.co.uk/uk/funds/snapshot/snapshot.aspx?id=F0GBR04BKW") Then
Set IE = eachIE
IE.Visible = False '"This is here because in some environments, the new process defaults to Visible."
Exit Do
End If
Next eachIE
Loop
Set eachIE = Nothing
Set sh = Nothing
'======Looks for the "Fund Size"======
'Trying to look for "Fund Size" inside "tr"-tag and if found, return the value in the 3rd "tr"-tag
Set allData = IE.document.getElementById("overviewQuickstatsDiv").getElementsByTagName("tbody")(0) 'Run-time error 424: Object required
row1 = allData.getElementsByTagName("tr")(5).Cells(0).innerHTML
row2 = allData.getElementsByTagName("tr")(5).Cells(1).innerHTML
row3 = allData.getElementsByTagName("tr")(5).Cells(2).innerHTML
If Left(row1, 9) = "Fund Size" Then
Worksheets("Sheet3").Range("B3") = Split(row3, ";")(1)
End If
Debug.Print allData.getElementsByTagName("tr")(5).Cells(0).innerHTML '"Fund Size"
Debug.Print allData.getElementsByTagName("tr")(5).Cells(2).innerHTML 'Actual fund size
IE.Quit
Set IE = Nothing
End Sub
EDIT:
Switched method. Now the problem is to get the fund size extracted. So the below code works as it is but I'd need to add a couple of lines to get the fund size out of it. This is my first time using this method so it may well be that I've just not understood some really basic thing. Still, I wasn't able to find a solution to this on my own.
Sub XMLhttpRequestTest()
'Microsoft XML, v 6.0
'Microsoft HTML object library
Dim HTMLDoc As New HTMLDocument
Dim ohttp As New MSXML2.XMLHTTP60
Dim myurl As String
Dim TRelements As Object
Dim TRelement As Object
myurl = "http://www.morningstar.co.uk/uk/funds/snapshot/snapshot.aspx?id=F0GBR04BKW"
ohttp.Open "GET", myurl, False
ohttp.send
HTMLDoc.body.innerHTML = ohttp.responseText
With HTMLDoc.body
Set TRelements = .getElementsByTagName("tr")
For Each TRelement In TRelements
Debug.Print TRelement.innerText
Next
End With
End Sub
You can use a css selector of
#overviewQuickstatsDiv td.line.text
And then select the element at index 4
# means id. . = className.
Option Explicit
Public Sub XMLhttpRequestTest()
'Microsoft XML, v 6.0
'Microsoft HTML object library
Dim HTMLDoc As New HTMLDocument, ohttp As New MSXML2.XMLHTTP60
Const URL As String = "http://www.morningstar.co.uk/uk/funds/snapshot/snapshot.aspx?id=F0GBR04BKW"
Dim TRelements As Object, TRelement As Object
With ohttp
.Open "GET", URL, False
.send
HTMLDoc.body.innerHTML = .responseText
Debug.Print HTMLDoc.querySelectorAll("#overviewQuickstatsDiv td.line.text")(4).innerText
'Your other stuff
End With
End Sub

My excel macro generates errors inconsistently

I am working on a macro to automate some web browser stuff and there is an intermittent runtime error 91 "object variable or with block variable not set". I have been playing around with how I declare and create my browser object but nothing is working.
Sub Morning_Script()
Dim WebBrowser As Object
Set WebBrowser = New InternetExplorerMedium
WebBrowser.Visible = True
WebBrowser.navigate "www.google.com"
While WebBrowser.Busy = True
DoEvents
Wend
WebBrowser.document.getElementById("lst-ib").Value = "test"
'WebBrowser.document.getElementById("verify").Value = Worksheets("Sheet1").Range("B2")
'WebBrowser.document.getElementById("institution").Value = "xxx"
'Worksheets("Sheet1").Range("B1").Clear
'Worksheets("Sheet1").Range("B2").Clear
End Sub
The URL has been changed to a public website and the form entry has been commented out for now.
If you would prefer to avoid fixed timers, try this one:
Dim objElement As Object: Set objElement = Nothing
While objElement Is Nothing
Set objElement = WebBrowser.document.getElementById("lst-ib")
DoEvents
Wend
objElement.Value = "test"
If you would like to refer to verify and institution to, you would have to implement this scheme for them, too and wait until all three variables are non-nothing. You may also want to set a timeout or maximum retry number if there is a really great number of pages to download.

Using VBA to control IE to login to a website

I'm new to this, but I'm practising, and it seemed to me that logging into my Institute's website ought to be the easiest thing in the world. Right? Well, it's driving me crazy.
Specifically, the program fails at
page.Document.getElementById("edit-name").Value = 1234
Run time error 424 "object required"
Also, and I'm not sure if this is related, when I type "page." the VBA editor helpfully provides a list of options, and I select Document. When I type the second "." to get "page.Document." I do not then get a further list of options.
Here's the complete program, and thanks for any help
Public Sub MyLogin()
'This uses early binding
'In menu at top of page - Tools...Reference.... Microsoft Internet Controls and Microsoft HTML Object Library must both be ticked
Dim page As InternetExplorer
Set page = New InternetExplorer
page.Visible = True
Dim MyLink As Object
'Login at Institute website
page.Navigate "http://www.actuaries.org.uk/"
Do While page.Busy Or page.ReadyState <> 4
DoEvents
Loop
For Each MyLink In page.Document.Links
If InStr(MyLink.href, "/user") Then MyLink.Click: Exit For
Next MyLink
Do While page.Busy Or page.ReadyState <> 4
DoEvents
Loop
'Are now at the login page
'Enter username, password and click
page.Document.getElementById("edit-name").Value = 1234
page.Document.getElementById("edit-pass").Value = "01/01/1977"
page.Document.getElementById("edit-submit").Click
End Sub
Specifically, the program fails at page.Document.getElementById("edit-name").Value = 1234
Nothing wrong with that line.
One reason that I can think of is that your For Loop is not executed. To avoid that, directly navigate to the relevant url. This trimmed version works for me.
Sub Sample()
Dim sUrl As String: sUrl = "https://www.actuaries.org.uk/user"
Dim ie As Object
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = True
ie.navigate sUrl
Do While ie.readystate <> 4: DoEvents: Loop
ie.Document.getElementById("edit-name").Value = 1234
End Sub

VBA: not able to pull value within <input> tag using getelementsbyTagname().Value

This is my first post on stackflow :) I've been Googling VBA knowledge and writing some VBA for about a month.
My computer info:
1.window 8.1
2.excel 2013
3.ie 11
My excel reference
Microsoft Object Library: yes
Microsoft Internet Controls: yes
Microsoft Form 2.0 Object library: yes
Microsoft Script Control 1.0: yes
Issue:
I was trying to retrieve data from internet explorer automatically using VBA.
I would like to retrieve the value within an input tag from a id called "u_0_1" which is under a id called "facebook". I am expecting to retrieve the value "AQFFmT0qn1TW" on cell c2. However, it got this msg popped up after I run the VBA "run-time error '91':object variable or with block variable not set.
I have been trying this for a couple of weeks using different methods such as,
1.getelementsbyClassname
2.getelementbyid
3.getelementsbyTagname
But it just doesn't work.
url:
http://coursesweb.net/javascript/getelementsbytagname
Below is my VBA code. Could you guys help me out a little bit please?
Private Sub CommandButton1_Click()
Dim ie As Object
Dim Doc As HTMLDocument
Dim getThis As String
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = 0
ie.navigate "http://coursesweb.net/javascript/getelementsbytagname"
Do
DoEvents
Loop Until ie.readyState = 4
Set Doc = ie.document
getThis = Trim(Doc.getElementById("u_0_1")(0).getElementsByTagName("input")(0).Value)
Range("c2").Value = getThis
End Sub
Thanks for your help. I have no idea that there is difference between JS and VBA in aspect of getelementsby () methods. And using the loop method to find the id which I find it very useful as well.
I still have some issues to retrieve value from a form or input type. I hope that you could help me or give me some suggestions as well.
Expected Result:
retrieve the value "AQFFmT0qn1TW" and copy it on Cell ("c2") automatically.
Actual Result:
nothing return to Cell ("C2")
Below is the HTML elements.
<form rel="async" ajaxify="/plugins/like/connect" method="post" action="/plugins/like/connect" onsubmit="return window.Event && Event.__inlineSubmit && Event.__inlineSubmit(this,event)" id="u_0_1">
<input type="hidden" name="fb_dtsg" value="AQFFmT0qn1TW" autocomplete="off">
Below is the VBA code based on your code.
Private Sub CommandButton1_Click()
Dim ie As Object
Dim Doc As HTMLDocument
Dim Elements As IHTMLElementCollection
Dim Element As IHTMLElement
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = 0
ie.navigate "http://coursesweb.net/javascript/getelementsbytagname"
Do
DoEvents
Loop Until ie.readyState = 4
Set Doc = ie.document
Set Elements = Doc.getElementsByTagName("input")
For Each Element In Elements
If Element.name = "fb_dtsg" Then
Range("c2").Value = Element.innerText
End If
Next Element
Set Elements = Nothing
End Sub
Cheers.
first of all, I can't find in source of website tags you were searching. Anyway, I think you can't chain getElementById.getElementsByTag as in JS. You have to loop through collection of document elements.
Private Sub CommandButton1_Click()
Dim ie As Object
Dim Doc As HTMLDocument
Dim Elements As IHTMLElementCollection
Dim Element As IHTMLElement
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = 0
ie.navigate "http://coursesweb.net/javascript/getelementsbytagname"
Do
DoEvents
Loop Until ie.readyState = 4
Set Doc = ie.document
Set Elements = Doc.getElementsByTagName("ul")
For Each Element In Elements
If Element.ID = "ex4" Then
Sheets(1).Cells(1, 1).Value = Element.innerText
End If
Next Element
Set Elements = Nothing
End Sub
First I'm getting collection of tags "ul", then looping through them for id "ex4". In your case you'd get collection of "input"s then loop for id you want. Finding id which is followed by different id shouldn't be hard, just some if...thens.
If you need further assistant please respond with url in which I can find exactly what you're looking for.
Cheers