HTML object library / pull - html

I have the following code in an HTML web page, and I am trying to use the html object library via vba engine to pull the value from within this tag:
<input name="txtAdd_Line1" disabled="disabled" size="30" maxLength="50" value="123 N 1ST ST"/>
I figure I have to use .getelementsbytagname or .getelementsbyname, but I am not sure how to grab the value. Does anyone have any ideas?

Here's an example with comments, subtitute in your actual address:
Sub Example()
'Declare needed variables
Dim ie, elements
Dim x As Long
'Create IE Applction
Set ie = CreateObject("InternetExplorer.Application")
'Navigate to the website
ie.navigate "C:\test.html" 'Substitute your actual address
'Wait for website to finish loading
Do While ie.ReadyState <> 4
Loop
'Find the elements
Set elements = ie.document.getelementsbyName("txtAdd_Line1")
'Display the value of each returned element
For x = 0 To elements.Length - 1
MsgBox elements(x).Value
Next
'Quit IE
ie.Quit
End Sub
Based on your comment most likely just looking at the document wasn't retrieving the actual layer of the tree you wanted, try this:
Set HTMLDoc = ie.document.frames("MainFrame").document
With HTMLDoc
'This returns an (object) which contains an array of all matching elements
a = .getElementsByName("txtAdd_Line1")
end with
For x = 0 to a.length
msgbox a(x).value
next

You can use a CSS selector of input[name='txtAdd_Line1'] . This says element with input tag having attribute name with value 'txtAdd_Line1'.
CSS selector:
You apply a CSS selector using the .querySelector method of document e.g.
Msgbox ie.document.querySelector("input[name='txtAdd_Line1']").innerText

Related

Excel VBA macro to get HTML SPAN ID value

I appreciate there are similar questions, but as a novice I find it hard to full adapt examples.
Problem Statement
I want the create a macro in Excel to pull the "last updated" value found on the website https://www.centralbank.ae/en/fx-rates. Specifically this is found within their HTML code (value example also below):
<span class="dir-ltr">11 Feb 2021 6:00PM</span>
What I wanted to Repurpose
The code here (https://www.encodedna.com/excel/extract-contents-from-html-element-of-a-webpage-in-excel-using-vba.htm) seemed to be a very clean way of launching IE in the background and then clearing down all elements thereafter. It iterates through hyperlinks which I don't need to do.
My code doesn't seem to work:
Option Explicit
Const sSiteName = "https://www.centralbank.ae/en/fx-rates"
Private Sub GetHTMLContents()
' Create Internet Explorer object.
Dim IE As Object
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = False ' Keep this hidden.
IE.navigate sSiteName
' Wait till IE is fully loaded.
While IE.readyState <> 4
DoEvents
Wend
Dim oHDoc As HTMLDocument ' Create document object.
Set oHDoc = IE.document
Dim oHEle As HTMLSpanElement ' Create HTML element (<span>) object.
Set oHEle = oHDoc.getElementById("dir-ltr").innerText ' Get the element ref using its ID. [A]
' Clean up.
IE.Quit
Set IE = Nothing
Set oHEle = Nothing
Set oHDoc = Nothing
End Sub
Once it works printing to innerText, I thought you can replace line commented by [A] with something like this but again not 100% sure how to replace:
Cells(iCnt + 1, 1) = .getElementsByTagName("h1").Item(iCnt).getElementsByTagName("a").Item(0).innerHTML
The goal is to print this SPAN CLASS ID value into a cell in an Excel worksheet (say "Sheet1").
The span tag has no ID. dir-ltr is the class. You can get all elements with a specific class with getElementsByClassName(). With the get methods with the plural Elements you create a node collection which is based by index 0. The class dir-ltr is the one and only class with this name in the document.
You can refer to it via index 0 which will be written behind the name of the node collection (like an array) or behind the method call. If you do it after the method call the node collection will be destroyed imidiatly but you get the indexed element of the list.
If you want to read the innertext you can do it directly behind the index but than you have a string, no object. I used that in the following code:
Private Sub GetHTMLContents()
Const sSiteName = "https://www.centralbank.ae/en/fx-rates"
Dim IE As Object
'Create Internet Explorer object.
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = False ' Keep this hidden.
IE.navigate sSiteName
' Wait till IE is fully loaded.
While IE.readyState <> 4: DoEvents: Wend
'New sheet with name "New sheet" at the end
ThisWorkbook.Sheets.Add after:=Sheets(Worksheets.Count)
ThisWorkbook.ActiveSheet.Name = "New sheet"
' Get the element ref using its ID. [A]
ThisWorkbook.Sheets("New sheet").Cells(1, 1) = IE.document.getElementsByClassName("dir-ltr")(0).innerText
' Clean up.
IE.Quit
Set IE = Nothing
End Sub

Prompted with Object doesn't support his property or method

I am trying to update the 1 of the field on the right section after selecting 1 of the button on left section but was prompted with the run-time error 438 code.
I have tried changing the element and attribution of the last row of my code but nothing seems to work.
Below is part of my VBA script:
Sub BrowseToWebTest1()
Dim ie As Object
Dim the_button_elements As Object
Dim button_element As Object
Dim radioButton As Object
Dim radioButtons As Object
Dim doc As HTMLDocument
Set ie = New InternetExplorerMedium
ie.navigate "company system web"
ie.Visible = True
While ie.Busy
DoEvents
Wend
Set doc = ie.document
Set the_button_elements = doc.getElementsByTagName("button")
For Each button_element In the_button_elements
If button_element.getAttribute("onclick") = "CreateAcqCase();" Then
button_element.Click
Exit For
End If
Next button_element
Call doc.getElementByName(“TransactionID”).setAttribute(“value”, “test”)
Below is the DOM Explorer code:
<input name="$PAcqCaseCreation$pTransactionID" class="leftJustifyStyle" id="TransactionID" style="width: 175px;" type="text" maxlength="15" value="" data-ctl='["TextInput"]' minchars="15" validationtype="minchars" data-changed="false">
Hopefully someone call help so that i can update fields accordingly. By the way I am using IE11 and Window 10
1) You have a mistake here:
doc.getElementByName(“TransactionID”).setAttribute(“value”, “test”)
The method is getElementsByName , notice the s indicating plural - a collection is returned. As it is a collection, you will need to supply an appropriate index to target the element of interest.
2) Also, you have introduced smart “ where you want ".
3) Neither call keyword, nor parantheses are needed.
4) The name attribute is:
name="$PAcqCaseCreation$pTransactionID"
Whereas the id attribute is:
id="TransactionID"
id is likely unique and a better selector (and is singular, so no s or index):
doc.getElementId("TransactionID").setAttribute "value", "test"
Otherwise,
doc.getElementsByName("$PAcqCaseCreation$pTransactionID")(0).setAttribute "value", "test"
This would be assuming first element in collection is the correct; otherwise, change the index.
5) You can replace all this (and remove the associated declarations):
Set the_button_elements = doc.getElementsByTagName("button")
For Each button_element In the_button_elements
If button_element.getAttribute("onclick") = "CreateAcqCase();" Then
button_element.Click
Exit For
End If
Next button_element
With one line:
doc.querySelector("[onclick='CreateAcqCase();']").Click

Using VBA to extract data from website, but getting run time error '91'

Quite new to VBA, having a problem with this error code.
run time error '91' object variable or With block variable not set
I'm trying to extract data from a website and past to a excel document. My Excel doc is Book2 and my module is called Module1. I'll paste the code below.
Sub WebNavigate()
Dim CreatingObject As Object
Dim WebNavigate As Object
Set objIE = CreatingObject("InternetExplorer.Application")
WebSite = "website link"
With objIE
.Visable = True
.navigate WebSite
Do While .Busy Or .readyState <> 4
DoEvents
Loop
Set elements = .document.getElementByClass("timark")
Sheet1.Cells(i, 8) = element.innerText
End With
End Sub
In the absence of HTML/URL to go with:
1) You are spelling of Visible is incorrect
2) The following:
Set elements = .document.getElementByClass("timark")
Is missing an s as it returns a collection and should be ClassName:
Set elements = .document.getElementsByClassName("timark")
3) You may need a pause or loop to ensure elements is available on the page.
4) This
Sheet1.Cells(i, 8) = element.innerText
You don't yet have element declared and assigned (you also don't have elements declared) . You may use in a For Loop.
e.g.
Dim element As Object, elements As Object
Set elements = .document.getElementsByClassName("timark")
For each element in elements
5) Creating should be Create (also as noted) and you need to declare objIE
Dim objIE As Object
Set objIE = CreateObject("InternetExplorer.Application")
6) i is not declared anywhere and must be greater than 1 when it is as there is no cell with row 0 in the sheet. Also, i would indicate a Loop of which there is no sign and when in a loop should be incremented to avoid overwriting the same cell.
7) Dim WebNavigate As Object is unassigned and not needed at present in the code.
8) To avoid many of the above use Option Explicit at the top of your code (As already mentioned).

VBA - getElementById works for simple website but not another?

So I'm currently stuck at getting a VBA script to retrieve the value of an input box from this Sudoku website. However, I was able to get the value from a paragraph element with the id of "contact" from my own simpler website, using the same code (after switching the url and id names, of course).
Any attempts to research further brings up articles/blogs that discuss what I've done correctly so far, so I suspect I am not researching it properly.
Here is my code:
Sub GetTable()
Dim ieApp As InternetExplorer
Dim ieDoc As Object
Dim sudokuCell As Object
Dim url, id, content As String
Dim i As Integer
Set ieApp = New InternetExplorer
ieApp.Visible = True
url = "http://www.websudoku.com/"
ieApp.navigate url
Do While ieApp.Busy: DoEvents: Loop
Do Until ieApp.READYSTATE = READYSTATE_COMPLETE: DoEvents: Loop
Set ieDoc = ieApp.document
If ieDoc Is Nothing Then
MsgBox ("Nothing")
'Else
' MsgBox ("Something")
End If
For i = 0 To 8
Set sudokuCell = ieDoc.getElementById("f00")
content = sudokuCell.innerText
MsgBox (content)
Next i
ieApp.Quit
Set ieApp = Nothing
End Sub
And here is an example of the html for a cell which is blank:
<td class="g0" id="c00"><input class="d0" size="2" autocomplete="off"
name="8iz6n11" maxlength="1" onblur="j8(this)" id="f00"></td>
And here is one for cell that is prefilled with a number:
<td class="f0" id="c10"><input class="s0" size="2" autocomplete="off"
name="s8iz6n21" readonly="" value="7" id="f10"></td>
I have tried both the "c00" an "f00" without success. Also, while I believe the problem at hand is I am not retrieving the element, I am concerned that the .innerText property won't retrieve the values.
First: The website is using FRAME, so you are not accessing the frame document in the VBA code actually. You need to navigate to the actual URL given below - change your url variable as the following (which is the frame's src property):
url = "http://view.websudoku.com/?"
Second: Those are INPUT elements you are trying to get values, you should be better using Value property instead innerText
content = sudokuCell.Value
Third and last: I have no idea what your code is supposed to do inside the loop as it will keep reading f00 element value as is. However I believe you'll loop through the input elements and just hit the wall here about the FRAME issue I explained above, so I assume loop is your part and have no trouble about it.

Get value from web document input element with VBA

I am having difficult to retrieve value 300 from the input named points.
Here's my HTML and VBA code.
HTML:
<td id="myPower_val_9" style="visibility: visible;">
<input type="text" disabled="disabled" value="300" name="points"></input>
</td>
VBA:
Dim ie As Object
Dim myPoints As String
Set ie = CreateObject("InternetExplorer.Application")
With ie
.Visible = 0
.navigate "www.example.com"
While .Busy Or .readyState <> 4
DoEvents
Wend
End With
Dim Doc As HTMLDocument
Set Doc = ie.document
myPoints = Trim(Doc.getElementsByTagName("td")(0).getElementById("myPoints").innerText)
Range("A1").Value = myPoints
HTML Code
I'd try working out the code that manipulates the Document Object Model (DOM) in javascript in a web browser so you can make use of better web based debugging tools.
There are several issues here that a console or debugger could help out with:
You want to get the element ID myPoints but in HTML it's just called points
You want to get the element by ID, but you've only set the name property -
As long as name is unique to the element, you don't need to search for a td first
As you can see from <input></input>, input elements do not have innerText (the text inside the ><). Instead they have a value attribute
The element exposes it's attributes and other data through the properties on the object itself. So you can check the input's value by just looking at .value
Here's a javascript example of what you're trying to do:
var value = document.getElementsByName("points")[0].value;
console.log(value);
<input type="text" disabled="disabled" value="300" name="points" />
Open the console (F12), and you should see 300
VBA
To convert it to VBA code for Excel, just make sure you uses parentheses () for VB arrays instead of square brackets [] for JS arrays:
myPoints = Trim(Doc.getElementsByName("points")(0).Value)
That should work just fine.
References
Since I'm not sure at what point you're failing in VB, also make sure you have all the proper web references in place in your VBA script.
Go to Tools > References > and add "Microsoft HTML Object Library" and "Microsoft Internet Controls":
Demo
I created a demo in plunker so there would be a live site to go against instead of example.com.
Paste the following code into excel and everything should work fine:
Public Sub GetValueFromBrowser()
Dim ie As Object
Dim url As String
Dim myPoints As String
url = "http://run.plnkr.co/plunks/6UTb9kHRZ363Ivhh2BPE/"
Set ie = CreateObject("InternetExplorer.Application")
With ie
.Visible = 0
.navigate url
While .Busy Or .readyState <> 4
DoEvents
Wend
End With
Dim Doc As HTMLDocument
Set Doc = ie.document
myPoints = Trim(Doc.getElementsByName("points")(0).Value)
Range("A1").Value = myPoints
End Sub
Output:
CSS selector:
Use a CSS selector to get the element of input[name='points']
You don't show enough HTML to know if this is the only on the page. The above says elements with input tag having attribute name whose value is 'points'
CSS query:
VBA:
You apply the CSS selector with .querySelector method of document for a single element; .querySelectorAll for a nodeList of all matching elements i.e. if there is more than one on the page and you get the one of interest by index.
Debug.Print ie.document.querySelector("input[name='points']").getAttribute("value")
You need to use .getAttribute("name of attribute") to get an attributes value. In your case .getAttribute("value") will return 300.
Dim ie As Object
Dim myPoints As String
Set ie = CreateObject("InternetExplorer.Application")
With ie
.Visible = 1
.navigate "website URL"
While .Busy Or .readyState <> 4
DoEvents
Wend
End With
Dim Doc As HTMLDocument
Set Doc = ie.document
myPoints = Trim(Doc.getElementsByTagName("td")(0).getElementsByTagName("input")(0).getAttribute("value"))
Range("A1").Value = myPoints
Just on a side note. I don't know much about HTML and maybe someone can elaborate on this more. But if you want to test that HTML code you need to add in the < table> < tr> tags.
Something like this:
<table>
<tr>
<td id="myPower_val_9" style="visibility: visible;">
<input type="text" disabled="disabled" value="300" name="points"></input>
</td>
</tr>
</table>