I am new to VBA and it would be great if you can help me on resolving this issue.
I am trying to click on a Text on an IE SharePoint webpage. I am am able to navigate to IE browser, but I am getting a VBA error for clicking the text "Americas" highlighted in Yellow in attached Screenshot. I need help with the IE.Document part of the code at the end of VBA code below. I assume GetElementbyID and GetElementByTagName are correct from HTML code below.
Error - Method Document of Object "IEwebBrowser"Failed
VBA Code:
Private Sub UploadFile()
Dim i As Long
Dim IE As Object
Dim Doc As Object
Dim objElement As Object
Dim objCollection As Object
Dim buttonCollection As Object
Dim AllSpanElements
Dim Span
' Create InternetExplorer Object
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
' Send the form data To URL As POST binary request
IE.navigate "URL"
' Wait while IE loading...
While IE.Busy
DoEvents
Wend
' I AM GETTING ERROR HERE
Set AllSpanElements = IE.Document.getElementById("ext-gen1271").getElementsByTagName("div")
AllSpanElements.Click
Set IE = Nothing
Set objElement = Nothing
End Sub
HTML CODE
<table class="x-grid-table x-grid-table-resizer" border="0" cellspacing="0" cellpadding="0" style="width:10000px;"><tbody>
<tr class="x-grid-row x-grid-row-selected x-grid-row-focused" id="ext-gen1271">
<td class="x-grid-cell-treecolumn x-grid-cell x-grid-cell-treecolumn-1030 x-grid-cell-first">
<div class="x-grid-cell-inner " style="text-align: left; ;"><img src="data:image/gif;base64,R0lGODlhAQABAID/AMDA" class="x-tree-elbow-plus x-tree-expander">
<img src="data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAA" class="x-tree-icon x-tree-icon-parent ">
Americas</div>
</td>
</tr>
</tbody>
</table>
Give this a shot, I cleaned up the code slightly and I'm trying a slightly different approach. Basically I'm iterating over each element on the page, then clicking it when the InnerText has "Americas" contained with in it.
It may not be the InnerText Property you want to check, it might be the Value or Title so you will need to check that.
Here's the code:
Private Sub UploadFile()
Dim IE As Object: Set IE = CreateObject("InternetExplorer.Application")
Dim Elements As Object
Dim Element As Object
With IE
.Visible = True
' Send the form data To URL As POST binary request
.navigate "URL"
' Wait while IE loading...
While .Busy Or .readystate <> 4
Application.Wait (Now() + TimeValue("00:00:01"))
DoEvents
Wend
End With
' I AM GETTING ERROR HERE
Set Elements = IE.Document.getElementsByTagName("*") ' * is all elements
For Each Element In Elements
If InStr(1, Element.innerText, "Americas") > 0 Then ' If the element has the word Americas...click it
Element.Focus
Element.Click
Element.FireEvent ("OnClick")
End If
Next
'Clean up
Set IE = Nothing
End Sub
Related
I want to catch the anchor element in website via vba.
I tried both as an MSHTML.IHTMLAnchorElement and MSHMTL.IHTMLBUttonELement but either way gives an error on Set line. Can anyone describe what's wrong with code below?
Sub goToWhtSpp()
Dim ie As New SHDocVw.InternetExplorer
ie.Visible = True
ie.navigate "https://cooperatordirectory.com/"
Do While ie.readyState <> READYSTATE_COMPLETE Or ie.Busy
Loop
Dim doc As MSHTML.HTMLDocument
Set doc = ie.document
Application.Wait 3000
URL = "https://cooperatordirectory.com/search_results?location_value=Florida&adm_lvl_1_sn=FL&stateSearchLN=Florida&country_sn=US&location_type=administrative_area_level_1&stateSearch=FL&swlat=24.396308&nelat=31.000968&swlng=-87.634896&nelng=-79.974306&lat=27.6648274&lng=-81.5157535&faddress=Florida%2C+USA&place_id=ChIJvypWkWV2wYgR0E7HW9MTLvc"
ie.navigate URL
Dim aelement As MSHTML.IHTMLAnchorElement
Set aelement = doc.getElementsByClassName("btn btn-primary btn-block") ' err line
Dim btn As MSHTML.IHTMLButtonElement
Set btn = doc.getElementsByClassName("btn btn-primary btn-block") ' err line
Debug.Print btn.Value
End Sub
<a class="btn btn-primary btn-block" href="/pro/20220324090906/connect">Send Message</a>
You want a page load wait after each .navigate. In this case you only need the one .navigate and wait.
getElementsByClassName() returns a collection not a single node. So both your type declaration, subsequent SET attempt to this type, and later attempt to view the .value attribute will fail. .value is a property of a single node.
If you want the first "button" href then index into a correctly typed variable and call .item(0), or, more efficiently, use the querySelector() method of ie.document and pass in a single class of the multi-valued class (the one which still correctly identifies the target element).
Dim anchors As IHTMLElementCollection
Set anchors = .document.getElementsByClassName("btn-primary")
Dim anchor As IHTMLAnchorElement
Set anchor = .document.getElementsByClassName("btn-primary").Item(0)
Option Explicit
Public Sub PrintMessageUrl()
Const URL As String = "https://cooperatordirectory.com/search_results?location_value=Florida&adm_lvl_1_sn=FL&stateSearchLN=Florida&country_sn=US&location_type=administrative_area_level_1&stateSearch=FL&swlat=24.396308&nelat=31.000968&swlng=-87.634896&nelng=-79.974306&lat=27.6648274&lng=-81.5157535&faddress=Florida%2C+USA&place_id=ChIJvypWkWV2wYgR0E7HW9MTLvc"
Dim ie As SHDocVw.InternetExplorer
Set ie = New SHDocVw.InternetExplorer
With ie
.Visible = True
.navigate URL
Do While .readyState <> READYSTATE_COMPLETE Or .Busy: DoEvents: Loop
Debug.Print .document.querySelector(".btn-primary").href
.Quit
End With
End Sub
I'm trying to use the Excel VBA to fill a web form and then scrape some data.
I am stuck on how to put in the value that I want to search for.
In the source code, there is no id or name that I can use.
I tried with a class name but it is not working.
" Source code:
<input type="text" style="height: 28px; width: 170px; padding-left: 5px;" ng-model="model.FieldValue" placeholder="Enter a Value" ng-show="model.searchOptions.length && model.searchOptions != 'SQE Quote Id'" class="ng-pristine ng-valid ng-touched">
Sub Macro1()
Dim i As Long
Dim URL As String
Dim IE As Object
Dim objElement As Object
Dim objCollection As Object
Dim html As HTMLDocument
Set IE = New InternetExplorerMedium
'Set IE.Visible = True to make IE visible, or False for IE to run in the background
IE.Visible = True
'Define URL
URL = "xxxx"
'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 inadvertently skipping over the second loop)
Do While IE.ReadyState = 4: DoEvents: Loop 'Do While
Do Until IE.ReadyState = 4: DoEvents: Loop 'Do Until
'
Set html = IE.Document
IE.Document.getElementById("searchOptions").Click (2)
IE.Document.getElementById("searchOptions").Value = "Access Qref"
IE.Document.getelemenetbyclassname("ng-pristine ng-valid ng-touched").Value = "00000"
'
End Sub
Try to put '.' between class names like below is working on my side.
IE.Document.querySelector("input.ng-pristine.ng-valid.ng-touched").Value = "00000"
Modified example:
Sub Macro1()
Dim i As Long
Dim URL As String
Dim IE As Object
Dim objElement As Object
Dim objCollection As Object
Dim html As HTMLDocument
Set IE = New InternetExplorerMedium
'Set IE.Visible = True to make IE visible, or False for IE to run in the background
IE.Visible = True
'Define URL
URL = "D:\Backup20190913\tests\353.html"
'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 inadvertently skipping over the second loop)
Do While IE.ReadyState = 4: DoEvents: Loop 'Do While
Do Until IE.ReadyState = 4: DoEvents: Loop 'Do Until
Set html = IE.Document
IE.Document.querySelector("input.ng-pristine.ng-valid.ng-touched").Value = "00000"
End Sub
Output:
The error is as it says. The method you are trying does not exist for that node. You are fine using a multi-valued class (more than one class name for the element; denoted by several strings separated by spaces within the class attribute of the element) inside of the correct method getElementsByClassName, rather than getelemenetbyclassname then you need to index into the returned collection in order to exercise the .click method.
IE.Document.getElementsByClassName("ng-pristine ng-valid ng-touched")(0).Value = "00000" '0 for first node
However, as in other answer, if using querySelector/querySelectorAll to match by css class selector then a multi-valued class must have the spaces between replaced with ".". Better still, try to select as few of those class names inside the multi-value as possible and the most selective which still match on the required node(s)
And please, I write this a lot on SO, use a proper page load wait:
While IE.busy Or IE.readystate <> 4: DoEvents: Wend
Can someone help please, i can't seem to get the below to work
Sub Automate_IE_Load_Page()
'This will load a webpage in IE
Dim i As Long
Dim URL As String
Dim IE As InternetExplorer
Dim objElement As Object
Dim objCollection As Object
'Create InternetExplorer Object
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
URL = "https://Whatever" 'Not putting the URL up here
IE.Navigate URL
Do Until IE.ReadyState = 4: DoEvents: Loop
IE.Document.getElementbyid("menuoptionCell_Excel2007+").Click '(Fails here)
'Set Button = IE.Document.getElementbyid("menuoptionCell_Excel2007+")
'Button.Click
End Sub
i have also tried
IE.Document.getElementsbyClass("contextMenuOptionTextCell")(0).Click
It is saying i need an object. I have tried different methods but none seem to work. I will say i am using the word "Button" loosely as its not actually a button, but not sure what it is called. Below are the identities used on the web page, and i'm not totally sure which i need to press, but neither seem to work
<td class="contextMenuOptionTextCell">
<span class="contextMenuOptionText">Excel 2007+</span></td>
<td id="menuoptionCell_Excel2007+" style="vertical-align: top; width: 16px;"></td>
thank you
Mike
I am trying to use excel to scrap some information from a website.
This is what shows on source:
<tr class="even">
<td align="right">1</td>
<td>Acrobatic Maneuver</td>
<td>Instant</td>
<td>2W</td>
<td>Common</td>
<td>Winona Nelson</td>
<td><img src="http://magiccards.info/images/en.gif" alt="English" width="16" height="11" class="flag2"> Kaladesh</td>
</tr>
So I want to get everything that has even, and extract the data between the <td></td>
However, all I've found until now is this code
Sub getcards()
Dim IE As Object
Dim i As Long
Dim objCollection As Object
' Create InternetExplorer Object
Set IE = CreateObject("InternetExplorer.Application")
' You can uncoment Next line To see form results
IE.Visible = False
' URL to get data from
IE.Navigate "http://magiccards.info/query?q=%2B%2Be%3Akld/en&v=list&s=issue"
' Statusbar
Application.StatusBar = "Loading, Please wait..."
' Wait while IE loading...
Do While IE.Busy
DoEvents
Application.Wait DateAdd("s", 1, Now)
Loop
On Error GoTo abort
Application.StatusBar = "Searching for value. Please wait..."
Dim dd As String
Set objCollection = IE.document.getElementsByClassName("even")
For i = 0 To objCollection.Length
dd = IE.document.getElementsByClassName("even")(i).innerText
MsgBox dd
Next i
abort:
' Show IE
IE.Visible = True
IE.Quit
' Clean up
Set IE = Nothing
Application.StatusBar = ""
End Sub
It works in such a way that it extracts the data, but the output is 1Acrobatic ManeuverInstant2WCommonWinona Nelson Kaladesh all together.
How can I do so it understands each <td> as a separate field, so I can extract it easily?
When you're looping through i within objCollection you're actually looping through all elements with the ClassName of "even" as opposed to the elements inside the specific element you want.
Try this:
For i = 0 To objCollection.Length - 1
For c = 0 to IE.document.getElementsByClassName("even")(i).getElementsByTagName("td").Length - 1
dd = IE.document.getElementsByClassName("even")(i).getElementsByTagName("td")(c).innerText
MsgBox dd
Next c
Next i
I'm working with VBA to fill a form in a URL and submiting to get results.
When I submit the form with correct values and submit via VBA, I get results in another URL but on the same window.
The problem is that I don't know how to change html reference to start scrapping data with this new url.
Here is my code:
'to refer to the running copy of Internet Explorer
Dim IE As InternetExplorer
'to refer to the HTML document returned
Dim html As HTMLDocument
'open Internet Explorer in memory, and go to website
Set IE = New InternetExplorer
IE.Visible = False
IE.navigate "http://url..."
'Wait until IE is done loading page
Do While IE.READYSTATE <> READYSTATE_COMPLETE
Application.StatusBar = "Connecting with http://url..."
DoEvents
Loop
'show text of HTML document returned
Set html = IE.document
'close down IE and reset status bar
Set IE = Nothing
Application.StatusBar = ""
Set txtArea = html.getElementsByTagName("textarea")(0)
txtArea.Value = txtArea_data
Set formSubmit = html.getElementsByName("submit")(1)
formSubmit.Click
'-------------Get results
'Dim html_results As HTMLDocument
IE.navigate "http://new_url" 'Im not sure if I must do it this way...
'Wait until IE is done loading page
Do While IE.READYSTATE <> READYSTATE_COMPLETE
Application.StatusBar = "Connecting with http://new_url..."
DoEvents
Loop
Set html = IE.document
Dim trResults As IHTMLElementCollection
Set trResults = html.getElementsByClassName("tr")
MsgBox (trResults.Length) 'At this point, trResults always have 0 results...
Have you any idea to help me?
Thanks!
This is a new approach, and still don't work.
I've used IE.Visible = True, so I could check that I get many <tr> results on the results page.
Dim rowNumber As Long
Dim txtArea_data As String
Dim txtArea As Object
Dim formSubmit As Object
Dim IE As InternetExplorer
Dim html As HTMLDocument
Set IE = New InternetExplorer
IE.Visible = True
IE.navigate "http://url..."
Do While IE.READYSTATE <> READYSTATE_COMPLETE
Application.StatusBar = "Connecting with http://url..."
DoEvents
Loop
Set html = IE.document
rowNumber = 4
For rowNumber = 4 To 120 'Rows.Count
txtArea_data = txtArea_data & Cells(rowNumber, 1).Value & Chr(10)
Next rowNumber
Set txtArea = html.getElementsByTagName("textarea")(0)
txtArea.Value = txtArea_data
Set formSubmit = html.getElementsByName("submit")(1)
formSubmit.Click
'Wait until results
Do While IE.Busy: DoEvents: Loop
'-------------Get results
'At this point, the page URL with results has changed, but on the same tab. In the other code, I've used IE.navigate "http://new_url..." But a "Invalid file" message appears.
'-------------
'I suppose html var could be recharged with these new results data, but nothing happen...
Set html = IE.document
Dim trResults As IHTMLElementCollection
Set trResults = html.getElementsByClassName("tr")
MsgBox (trResults.Length) 'At this point, MsgBox returns O...
Set html = Nothing
Results page looks like:
<body>
<table id="tabla-a">
<thead>
<tr>
<th>...</th>
<th>...</th>
<th>...</th>
</tr>
</thead>
<tbody>
<tr>
<td>...</td>
<td>...</td>
<td>...</td>
</tr>
<tr>
<td>...</td>
<td>...</td>
<td>...</td>
</tr>
<tr>
<td>...</td>
<td>...</td>
<td>...</td>
</tr>
</tbody>
</table>
</body>
Is there anything I could tell you to make to help you finding the problem?
Thanks!
EDIT
Oh my God! I've been using Set trResults = html.getElementsByClassName("tr") instead of Set trResults = html.getElementsByTagName("tr") !!!
Thanks for your time!
What should I do now? Edit the original question with the final solution or close the entire question?
I don't use Stackoverflow too much to ask questions...
Thanks!