getelementbytagname isn't recognized - vba

I'm attempting to have Excel open a web site, populate some fields, submit, and download the resulting data in a file.
My code never gets very far, however, because it looks like Excel doesn't recognize "getelementsbytagname" as an existing operation. I assume this is the issue because it does not correct the case to GetElementsByTagName like it does for everything else.
My References in the editor include Microsoft Internet Controls and Microsoft HTML Object Library. Is there another one that I need to activate?
The code is just a modified version of something found online.
Private Sub IE_automation()
'Retrieve data from Enterprise Reporting with IE
Dim i As Long
Dim IE As Object
Dim objElement As Object
Dim objCollection As Object
'Create Internet Explorer Object
Set IE = CreateObject("InternetExplorer.Application")
'Comment out while troubleshooting
'IE.Visible = False
'Send the form data to URL as POST binary request
IE.Navigate "http://corpprddatawhs1/Reports/Pages/Report.aspx?ItemPath=%2fInventory%2fInventory+By+Branch"
'Set statusbar
Application.StatusBar = "Webhost data is loading. Please wait..."
'Wait while IE loading
Do While IE.busy
Application.Wait DateAdd("s", 1, Now)
Loop
'Find 2 input tags:
' 1. Text field
' <input type="text" class="null" name="ct132$ct104$1ct105$txtValue" size="30" value="" />
'
' 2. Button
' <input type="submit" value="View Report" />
Application.StatusBar = "Searching form submission. Please wait..."
Set objCollection = IE.document.getelementsbytagname("input")

My References in the editor include Microsoft Internet Controls and Microsoft HTML Object Library.
Then you have no need to do this:
Dim IE As Object
Dim objElement As Object
Dim objCollection As Object
Set IE = CreateObject("InternetExplorer.Application")
Declaring everything As Object is a technique called late-binding. In that paradigm you create a new instance of an object by passing a ProgID to the CreateObject function.
Late-bound code is, by definition, resolved at run-time: the compiler is happy with the Object interface, and the onus is on you to use the correct members.
With late-bound code you can't get IntelliSense or auto-complete, because the compiler has no idea what you're up to: all it's seeing is Object.
When you actually reference a type library, you can use early binding, which means the types and member calls are resolved at compile-time instead of run-time. But for this to work, you need to use the types you're referencing. Otherwise you're late-binding against a type library that's referenced... and late-bound code doesn't require a reference (just that some version of the type library is registered on the machine that's running the code).
Dim browser As InternetExplorer
Set browser = New InternetExplorer
browser.Navigate url
'...
Dim dom As HTMLDocument
Set dom = browser.Document
Dim inputElements As HTMLElementCollection
Set inputElements = dom.getElementsByTagName("input")
And now you're coding against an HTML DOM just like you would against any Excel worksheet, with IntelliSense and parameter info and all the goodies.
This is suspicious:
Do While IE.busy
Application.Wait DateAdd("s", 1, Now)
Loop
That wait-loop isn't even looking at the browser's ReadyState. Try this instead:
Do Until IE.ReadyState = 4 And IE.Busy = False
DoEvents
Loop
See this post for an allegedly fail-safe way to go about it.
Your code otherwise looks fine though, so my money is on the wait-loop.

Even though VBA is case-insensitive, all the methods/properties under document are case-sensitive.
A safe way to call them with late-binding is to use CallByName:
Set items = CallByName(IE.document, "getElementsByTagName", VbMethod, "input")

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 with Excel and IE: Can't get the source right source code?

I'm currently trying to automate my IE at work with VBA and Excel, because we have some repetitive tasks to complete in an SAP System which is called within the Internet Explorer.
So far I am able to start IE and navigate to the starting page of our System.
I looked on the source code from the Sap System to search for an id from a div (lets say its 'SampleID'). But if I try to click it via VBA I only get returned 'nothing'. So I tried to print out the source code via VBA Debug.Print to look at the problem. And here's the thing:
The source code that gets printed is completely different from the Website's Source Code. In the printed code for example is a iframe that I can't find in the website source code. So that's the reason I can't find my div and any other objects, because they are not in the code that VBA is searching through.
Can anyone tell me what's going wrong? Why are the source codes completely different?
Sub stgGo(){
Dim i As Long
Dim IE As InternetExplorerMedium
Dim objElement As Object
Dim objCollection As Object
Set IE = New InternetExplorer
IE.Visible = True
IE.Navigate ("URL")
'waiting 10 seconds to be really sure javascript is ready
Application.Wait (Now + TimeValue("0:00:10"))
'printing out the false source code
Debug.Print strHTML = myIE.Document.body.innerHTML
Set objCollection = IE.document.getElementsByTagName("div")
i = 0
While i < objCollection.Length
If objCollection(i).ID = "SampleID" Then
objCollection(i).Click
End If
i = i + 1
Wend
End Sub

vba can not find opening IE 11 Browser.

I have a vba code which can upload the data from an excel sheet to a website. However, the code works fine in Win7 System and IE browser 8,but it does not work on a win8 IE browser 11.
Here are part of the code:
Dim objIE As SHDocVw.InternetExplorer
Dim htmlDoc As MSHTML.HTMLDocument
Dim htmlFrame As MSHTML.HTMLFrameElement
Dim frame As HTMLIFrame
Dim htmlElement As HTMLDTElement
Dim myDoc As Object
Set curSheet = ActiveWorkbook.ActiveSheet
Set oShApp = CreateObject("Shell.Application")
For Each oWin In oShApp.Windows
If oWin.Name = "Windows Internet Explorer" Then
Set IE = oWin
Exit For
End If
Next
If IE Is Nothing Then
MsgBox ("Please sign into Avocado, then re-run this macro")
Set IE = New InternetExplorerMedium
IE.Visible = True
IE.navigate "https://www.google.com"
Exit Sub
End If
Sheets("Prepare").Select
fPathName = Cells(5, 5)
Call MakeFolders(fPathName)
Call MakeFolders2(fPathName)
Call MakeFolders3(fPathName)
'fFileName = fPathName & "\*.xls"
fFileName = Dir(fPathName & "\*.xls")
The code runs in a loop when enters the statement : "If IE Is Nothing Then"
Even when the google site is opened, the program still keeps prompting out the msgBox, and reopen the website again and again, and it never executes to the last part "Sheets("Prepare").Select". I am very confused because it works perfect in the IE 8 browsers. I am wondering if there is any difference between IE11 and IE8 in terms of vba IE function.
Please take a look up it and give me some ideas on this, your help is greatly appreciated. Thank you very much.
I ran into the identical problem and found, that the window name of the shell.application has changed in IE 11. Earlier versions had the name "Windows Internet Explorer", but IE 11 uses only "Internet Explorer"
If you change your if condition accordingly, it will work again ...
I think you are using an old version of internet explorer. Use the code I provided bellow and see if it works. Please make sure you have the following references added to your project:
Microsoft HTML Object Library
Microsoft Internet Controls.
If you are not sure how to add the references to your code check out this link.External References
Sub Test()
Dim objIE As InternetExplorer
Dim htmlDoc As HTMLDocument
Dim htmlFrame As HTMLFrameElement
Dim frame As HTMLIFrame
Dim htmlElement As HTMLDTElement
Dim myDoc As Object
Dim curSheet As Worksheet
' Set the variables
Set curSheet = ActiveWorkbook.ActiveSheet
Set objIE = New InternetExplorer
' Make the browser visible and navigate
With objIE
.Visible = True
.navigate "https://www.google.com"
End With
WaitForInternetToLoad objIE
Sheets("Prepare").Select
fPathName = Cells(5, 5).Value
Call MakeFolders(fPathName)
Call MakeFolders2(fPathName)
Call MakeFolders3(fPathName)
'fFileName = fPathName & "\*.xls"
fFileName = Dir(fPathName & "\*.xls")
End Sub
Sub WaitForInternetToLoad(ByRef ie As InternetExplorer)
Do
dovents
Loop While Not ie.readyState = READYSTATE_COMPLETE
End Sub
Extra Information.
Hi I see you are having some trouble with this and I want to extend my help.
Let's start by the fact that you are using two external libraries in your code; and you should have references set to them for the code to work properly. See my picture I have highlighted the libraries yellow.
What are the differences:
Microsoft Internet Controls
Is the one that takes care of the internet object. It creates an internet explorer application and it navigates to certain links. Once it finishes navigating to the url then " internet object" has a "document". This object cannot do anything else.
Microsoft HTML Object Library
This library takes care of the Html document. And as you probably guessed you will assign the "document" from the previous object (internet explorer) to a HTML document variable and then you can do further manipulation.

excel VBA - function to parse data

I am trying to parse a webpage but am having difficulty in getting the information coming through.
I have a simple button which navigate to a website in a worksheet
Private Sub Sellit_Click()
Dim IE As Object
Dim HTMLDoc As HTMLDocument
Dim oHTML_Element As IHTMLElement
Set IE = CreateObject("Internetexplorer.Application")
IE.Visible = True
apiShowWindow IE.hwnd, SW_MAXIMIZE
IE.navigate "https://www.yahoo.com/"
Do
Loop Until IE.ReadyState = READYSTATE_COMPLETE
DoEvents
Scrape
End Sub
While the function Scrape in a module
Function Scrape()
Dim IE As Object
Dim HTMLDoc As HTMLDocument
Dim oHTML_Element As IHTMLElement
MsgBox IE.document.Title
End Function
I kinda think i know the problem here is the IE doesn't go from the worksheet to the module and vise versa but am not quite sure how to fix it.
your help will be much apperciated
You'd have to declare the IE object variable publicly, then refer to it using it's fully qualified name. To do so:
At the top of the Worksheet code module type Public IE as Object
Remove variable declarations to IE within the SellIt Click event and the Scrape function. Since this is declared publicly, it shouldn't be declared privately within the code.
In the standard module, also remove the IE declaration. (Same reason as step 2)
Change MsgBox IE.document.Title to include the sheet's codename. For example, if the sheet codename is Sheet1 it should read MsgBox Sheet1.IE.document.Title
Let me know if that helps.

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