Excel VBA - Error 91 problem when HTML value is nothing - html

Hi I recently discovered excel VBA and am using it to aid my study of German.
I have a list of German words but no meaning/part of speech, example sentences, etc.
I wrote a macro to go to website (https://dictionary.cambridge.org/dictionary/german-english/) and fetch html data.
However, for some words, the example sentences are not provided (Hence the html returning no value and the error 91).
I have referred to other posts concerning this and added If Not HTMLDoc.getElementsByClassName() Is Nothing Then statements, but no luck so far.
Could you please tell me how to write a code such that if there is no html value, the macro moves on and go to the next word? (word is set by integer corresponding to the cell number in the excel sheet)
Dim XMLReq As New MSXML2.XMLHTTP60
Dim HTMLDoc As New MSHTML.HTMLDocument
Dim i As Integer
Dim strURL As String
For i = 2 To 3493
strURL = "https://dictionary.cambridge.org/dictionary/german-english/" & Range("A" & i)
XMLReq.Open "Get", strURL, False
XMLReq.send
If XMLReq.Status <> 200 Then
MsgBox "Error."
Exit Sub
End If
HTMLDoc.body.innerHTML = XMLReq.responseText
Set XMLReq = Nothing
'Part
If IsObject(HTMLDoc.getElementsByClassName("pos dpos")) Then
Range("B" & i) = HTMLDoc.getElementsByClassName("pos dpos")(0).innerText
End If
'Meaning
If IsObject(HTMLDoc.getElementsByClassName("ddef_h")) Then
Range("C" & i) = HTMLDoc.getElementsByClassName("ddef_h")(0).innerText
End If
'ExampleGer
If Not HTMLDoc.getElementsByClassName("eg deg") Is Nothing Then
i = i + 1
Else
Range("D" & i) = HTMLDoc.getElementsByClassName("eg deg")(0).innerText
End If
'ExampleEng
If Not HTMLDoc.getElementsByClassName("trans dtrans hdb") Is Nothing Then
i = i + 1
Else
Range("E" & i) = HTMLDoc.getElementsByClassName("trans dtrans hdb")(0).innerText
End If
Next i
End Sub

Ok, I'm a German and therefore did not need any example words.
A word that delivers all 4 values: Haus (house)
A word that delivers only 2 values: Gummibaum (rubber plant)
Try the following code and please ...
NEVER! NEVER! NEVER! manipulate the counting variable of a for loop in the code block of the loop. Never use this i = i + 1 if i is the counting variable of the for loop. If you do that you run into problems in 99.9%
Sub Dictionary()
Dim XMLReq As New MSXML2.XMLHTTP60
Dim HTMLDoc As New MSHTML.HTMLDocument
Dim i As Integer
Dim strURL As String
'Use object variables for each node you want to read from the DOM tree
'In the code below, these variables are then used to check whether an object exists or not
Dim nodePart As Object
Dim nodeMeaning As Object
Dim nodeExampleGer As Object
Dim nodeExampleEng As Object
For i = 2 To 3493
strURL = "https://dictionary.cambridge.org/dictionary/german-english/" & Range("A" & i)
'strURL = "https://dictionary.cambridge.org/dictionary/german-english/haus"
XMLReq.Open "Get", strURL, False
XMLReq.send
If XMLReq.Status <> 200 Then
MsgBox "Error."
Exit Sub
End If
HTMLDoc.body.innerHTML = XMLReq.responseText
Set XMLReq = Nothing
'Part
Set nodePart = HTMLDoc.getElementsByClassName("pos dpos")(0)
If Not nodePart Is Nothing Then
Range("B" & i) = nodePart.innerText
End If
'Meaning
Set nodeMeaning = HTMLDoc.getElementsByClassName("ddef_h")(0)
If Not nodeMeaning Is Nothing Then
Range("C" & i) = nodeMeaning.innerText
End If
'ExampleGer
Set nodeExampleGer = HTMLDoc.getElementsByClassName("eg deg")(0)
If Not nodeExampleGer Is Nothing Then
Range("D" & i) = nodeExampleGer.innerText
End If
'ExampleEng
Set nodeExampleEng = HTMLDoc.getElementsByClassName("trans dtrans hdb")(0)
If Not nodeExampleEng Is Nothing Then
Range("E" & i) = nodeExampleEng.innerText
End If
Next i
End Sub

Related

Why am I not able to add an HTML Classname to an Element Collection using MSXML2 with VBA

I have tried many proven methods from various posts to get some data from a web page without success. I am able to get a list of linked items on the opening page but once I navigate to any other page, I draw a blank with the code below.
When I run the code, I get no results in Cats.
Sub Main()
Dim XMLReq As New MSXML2.XMLHTTP60
Dim HTMLDoc As New MSHTML.HTMLDocument
Dim Cats As MSHTML.IHTMLElementCollection
Dim Cat As MSHTML.IHTMLElement
Dim NextHref As String
Dim NextURL As String
XMLReq.Open "GET", URL, False
XMLReq.send
If XMLReq.Status <> 200 Then
MsgBox "Problem"
Exit Sub
End If
HTMLDoc.body.innerHTML = XMLReq.responseText
Set XMLReq = Nothing
Set Cats = HTMLDoc.getElementsByClassName("ng-tns-c329-5 product-grid--tile ng-star-inserted")
Debug.Print Cats.Length 'Returns 0
'For Each Cat In Cats
' NextHref = Cat.getAttribute("href")
' NextURL = URL & Mid(NextHref, InStr(NextHref, ":") + 2)
' ListItemsInCats Cat.innerText, NextURL
'Next Cat
End Sub
Expanded Element structure
Collased structure
Thanks for any assistance.
The problem with the website you are trying to scrape from is that:
In XMLHTTP Request method - The product details are dynamic content that is pulled from Fetch/XHR which XMLHTTP does not run, XMLHTTP only gives you the HTML document as it is without any script running.
In Internet Explorer method - The webpage is considered ready before the product details are actually loaded so the usual loop check for Busy and ReadyState is not sufficient.
The code below uses Internet Explorer and to resolve the issue mentioned above, I have put up some checks (Which is not perfect I believe but it works so far in my testing) that will wait until the first product has been loaded before proceeding to pull the product details:
Private Sub GetBakeryProducts()
Const URL As String = "https://www.woolworths.com.au/shop/browse/bakery"
Dim ieObj As InternetExplorer
Set ieObj = New InternetExplorer
ieObj.navigate URL
ieObj.Visible = True
Do While ieObj.Busy Or ieObj.readyState <> READYSTATE_COMPLETE
DoEvents
Loop
Do While ieObj.document.getElementsByClassName("productCarousel-header").Length = 0
DoEvents
Loop
Dim ieDoc As MSHTML.HTMLDocument
Set ieDoc = ieObj.document
Dim productList As Object
Set productList = ieDoc.getElementsByClassName("product-grid--tile")
'==== Test if the website has finish loading the 1st product details
On Error Resume Next
Dim testStatus As String
Do
Err.Clear
testStatus = productList(0).getElementsByClassName("shelfProductTile-descriptionLink")(0).innerText
Loop Until Err.Number = 0
'====
Dim outputArr() As String
ReDim outputArr(1 To productList.Length, 1 To 2) As String
Dim outputIndex As Long
Dim i As Long
For i = 0 To productList.Length - 1
If productList(i).getElementsByClassName("shelfProductTile-descriptionLink").Length <> 0 Then
If Err.Number <> 0 Then
Err.Clear
Exit For
End If
Dim productName As String
Dim productPrice As String
productName = productList(i).getElementsByClassName("shelfProductTile-descriptionLink")(0).innerText
productPrice = Replace(productList(i).getElementsByClassName("price")(0).innerText, vbNewLine, vbNullString)
outputIndex = outputIndex + 1
outputArr(outputIndex, 1) = productName
outputArr(outputIndex, 2) = productPrice
End If
Next i
ReDim Preserve outputArr(1 To outputIndex, 1 To 2) As String
ieObj.Quit
Set ieObj = Nothing
ThisWorkbook.Sheets("Sheet1").Range("A1").Resize(outputIndex, UBound(outputArr, 2)).Value = outputArr
End Sub
Running this will pull the data from the website and paste the output starting from cell A1 in Sheet1, please change the worksheet name and range as you see fits.

Loop through line of code and change integer for getElementsByClassName

Previously posted on the MrExcel forum
www.mrexcel.com/board/threads/change-integer-in-code-line-for-htmldoc-getelementsbyclassname.1146814/
My original line of code was
Set DogRows1 = HTMLDoc.getElementsByClassName("rpb-greyhound rpb-greyhound-1 hover-opacity"
It works perfectly for the integer 1. However, I require to increment this by 1 and change to 2, 3, 4, 5 and 6 for other webpages, as below.
Set DogRows1 = HTMLDoc.getElementsByClassName("rpb-greyhound rpb-greyhound-6 hover-opacity"
I tried declaring some variables and adding a For Next Loop, however it will not loop through. What am I doing wrong? Have I put the For Next Loops in the wrong place?
Dim StartRaceNumber As Integer
Dim LastRaceNumber As Integer
XMLReq.Open "GET", DogPageURL, False
XMLReq.send
If XMLReq.Status <> 200 Then
MsgBox "Problem" & vbNewLine & XMLReq.Status & " - " & XMLReq.statusText
Exit Sub
End If
HTMLDoc.body.innerhtml = XMLReq.responseText
Set XMLReq = Nothing
LastRaceNumber = 6
For StartRaceNumber = 1 To LastRaceNumber
Set DogRows1 = HTMLDoc.getElementsByClassName("rpb-greyhound rpb-greyhound-" & StartRaceNumber & " hover-opacity")
For Each DogRow1 In DogRows1
Set DogNameLink1 = DogRow1.getElementsByTagName("a")(0)
NextHref = DogRow1.getAttribute("href")
NextURL = DogURL & Mid(NextHref, InStr(NextHref, ":") + 28)
Debug.Print DogRow1.innerText, NextURL
Next DogRow1
Next StartRaceNumber
Sure SIM
The scraping order is as follows:
Get Greyhound URL racecards
Greyhound Races
Get Greyhound URL Dog information
List of Greyhounds in the race
Get Greyhound Form details, this is an example for Greyhound#1
Form of Each Greyhound #1
Then loop to the next race and repeat.
As I said, from the code I can scrape only the form for greyhound#1 details for each race. I need to get the other dogs too if you can help?
These are my modules, hopefully they have imported correctly >
Option Explicit
Const DogURL As String = "https://www.timeform.com/greyhound-racing/racecards"
Sub ListDogRace()
Dim XMLReq As New MSXML2.XMLHTTP60
Dim HTMLDoc As New MSHTML.HTMLDocument
Dim TFRaceList As MSHTML.IHTMLElement
Dim TFRaces As MSHTML.IHTMLElementCollection
Dim TFRace As MSHTML.IHTMLElement
Dim NextHref As String
Dim NextURL As String
XMLReq.Open "GET", DogURL, False
XMLReq.send
If XMLReq.Status <> 200 Then
MsgBox "Problem" & vbNewLine & XMLReq.Status & " - " & XMLReq.statusText
Exit Sub
End If
HTMLDoc.body.innerhtml = XMLReq.responseText
Set XMLReq = Nothing
Set TFRaces = HTMLDoc.getElementsByClassName("wfr-race bg-light-gray hover-opacity")
For Each TFRace In TFRaces
NextHref = TFRace.getAttribute("href")
NextURL = DogURL & Mid(NextHref, InStr(NextHref, ":") + 28)
ListDogsOnPage TFRace.innerText, NextURL
Next TFRace
End Sub
Sub ListDogsOnPage(DogName As String, DogPageURL As String)
Dim XMLReq As New MSXML2.XMLHTTP60
Dim HTMLDoc As New MSHTML.HTMLDocument
Dim DogRow1 As MSHTML.IHTMLElement
Dim DogRows1 As MSHTML.IHTMLElementCollection
Dim DogNameLink1 As MSHTML.IHTMLElement
Dim NextHref As String
Dim NextURL As String
Dim StartRaceNumber As Integer
Dim LastRaceNumber As Integer
XMLReq.Open "GET", DogPageURL, False
XMLReq.send
If XMLReq.Status <> 200 Then
MsgBox "Problem" & vbNewLine & XMLReq.Status & " - " & XMLReq.statusText
Exit Sub
End If
HTMLDoc.body.innerhtml = XMLReq.responseText
Set XMLReq = Nothing
LastRaceNumber = 6
For StartRaceNumber = 1 To LastRaceNumber
Set DogRows1 = HTMLDoc.getElementsByClassName("rpb-greyhound rpb-greyhound-" & StartRaceNumber & " hover-opacity"
For Each DogRow1 In DogRows1
Set DogNameLink1 = DogRow1.getElementsByTagName("a")(0)
NextHref = DogRow1.getAttribute("href")
NextURL = DogURL & Mid(NextHref, InStr(NextHref, ":") + 28)
Debug.Print DogRow1.innerText, NextURL
Next DogRow1
Next StartRaceNumber
End Sub
Can I just confirm, it is only the URL on the page of each race for each greyhound I need, so I can scrape the greyhound's form.
As an example:
Nottingham 11.06
#1 BALLYBOUGH GARY
https://www.timeform.com/greyhound-racing/greyhound-form/ballybough-gary/59297
#2 SALACRES BRUISER
https://www.timeform.com/greyhound-racing/greyhound-form/salacres-bruiser/59746
#3 FOLLOW MY LEAD
https://www.timeform.com/greyhound-racing/greyhound-form/follow-my-lead/54898
#4 HONOUR SAMURAI
https://www.timeform.com/greyhound-racing/greyhound-form/honour-samurai/53100
#5 NIDDERDALEFLURRY
https://www.timeform.com/greyhound-racing/greyhound-form/nidderdaleflurry/56446
#6 SPORTY MELODY
https://www.timeform.com/greyhound-racing/greyhound-form/sporty-melody/58746
I already have a Power Query function I have developed to scrape the form data from that url page. I am just struggling to get that full list of 6x greyhound form urls (as above) for each and every race.
If that makes sense?

Grabbing a single piece of data from a website's HTML and assign it to a variable

I'm working on a project where I grab data that I stored in an excel sheet and search a specific website that can be seen in the code below. Once the website completes the search, I want to grab the "worth" from the top right of the page. I'm fairly new to using VBA with HTML, so I'm not sure how to take the element (worth) that I'm looking for from the web page, and assign it to a variable in VBA so I can paste it into my excel sheet.
Right now I'm able to open IE, insert my data into the search bar of the specific website that I'm using, and click search. What I have is seen below. Thank you in advance!
Sub BrowsetoSite()
Dim IE As New SHDocVw.InternetExplorer
Dim website As String
Dim i As Integer
i = 2
'Set ie = New SHDocVw.InternetExplorer
website = "https://cardmavin.com/category/football"
IE.navigate website
IE.Visible = False
Do While IE.readyState <> READYSTATE_COMPLETE
'assign info to variable to enter into the search bar
Loop
Dim idoc As MSHTML.HTMLDocument
Set idoc = IE.document
Dim Brand As String
Dim Year As String
Dim Num As String
Dim Name As String
Dim search As String
Dim value As Variant
Brand = Range("A" & i).value
Year = Range("B" & i).value
Num = Range("D" & i).value
Name = Range("E" & i).value
search = (Year & " " & Brand & " " & Name & " " & Num)
i=i+1
idoc.getElementById("search-field").value = search
idoc.getElementById("to-mavin").Click
While IE.readyState <> READYSTATE_COMPLETE
DoEvents
Loop
Dim value As Variant
value = idoc.getElementsByTagName("h4")(0).innerText
MsgBox value
IE.Quit
End Sub
The issue that I'm having is the value = idoc.getElementsByTagName("h4")(0).innerText. I've tried to get the element a few different ways, but have been unsuccessful so far.
You need Set idoc = IE.document after you've submitted the search, to get a reference to that new page. Otherwise you're still trying to access the previous page.
i=i+1
idoc.getElementById("search-field").value = search
idoc.getElementById("to-mavin").Click
While IE.readyState <> READYSTATE_COMPLETE
DoEvents
Loop
Set idoc = IE.document '<<<<<<<<<<<<<<
Dim value As Variant
value = idoc.getElementById("worthBox") _
.getElementsByTagName("h4")(0).innerText
MsgBox value
Try this approach. Suppose in cell A1 the string 2008 Topps Thomas DeCoud
Sub Test()
Const sURL As String = "https://mavin.io/search?q="
Dim json As Object
Set json = GetJSONFromHTMLHead(sURL & Application.WorksheetFunction.EncodeURL(Range("A1").Value))
Debug.Print json("offers")("priceCurrency")
Debug.Print json("offers")("price")
End Sub
Function GetJSONFromHTMLHead(ByVal sURL As String) As Object
Dim http As MSXML2.XMLHTTP60, html As MSHTML.HTMLDocument, re As Object, json As Object
Set http = New MSXML2.XMLHTTP60
Set html = New MSHTML.HTMLDocument
Set re = CreateObject("VBScript.RegExp")
re.Pattern = "<head>([\s\S]+)<\/head>"
With http
.OPEN "Get", sURL, False
.send
html.body.innerHTML = Replace$(Replace$(re.Execute(.responseText)(0), "<head>", "<body>"), "</head>", "</body>")
End With
Set json = JSONConverter.ParseJson(html.querySelector("script[type='application/ld+json']").innerHTML)
Set GetJSONFromHTMLHead = json
End Function

HTML Element Collection filled from Previous Webpage Rather than Redirected Webpage VBA

The code below navigates to a webpage, fills search boxes with queries, and submits to the results page. However, the final element collection in the script, tdtags, which is defined after the redirect, is pulling data from the original search page, rather than the results page. I currently have the while ie.busy loop and a timed delay in the script, neither of which works. I have also tried waiting until an element only present in the results page becomes available in the html, but this also does not work.
Dim twb As Workbook
Dim ie As Object
Set twb = ThisWorkbook
twb.Activate
Set ie = CreateObject("internetexplorer.application")
'church = Sheets("Control").Range("A2").Value
'minister = Sheets("Control").Range("A4").Value
location = "London" 'Sheets("Control").Range("A6").Value
'denomination = Sheets("Control").Range("A8").Value
With ie
.navigate "http://www.ukchurch.org/index.php"
.Visible = True
Do While .Busy Or .ReadyState <> 4
DoEvents
Loop
End With
Application.Wait (Now + TimeValue("00:00:02"))
Set intags = ie.document.getelementsbytagname("input")
For Each intag In intags
If intag.getattribute("name") = "name" Then
If church <> "" Then
intag.Value = church
End If
ElseIf intag.getattribute("name") = "minister" Then
If minister <> "" Then
intag.Value = minister
End If
ElseIf intag.getattribute("name") = "location" Then
If location <> "" Then
intag.Value = location
End If
Else
End If
Next intag
Set dropopt = ie.document.getelementsbytagname("select")
For Each dropo In dropopt
If dropo.classname = "DenominationDropDown" Then
Set opttags = dropo.getelementsbytagname("option")
For Each opt In opttags
If opt.innertext = denomination Then
opt.Selected = True
End If
Next opt
End If
Next dropo
On Error Resume Next
For Each intag In intags
If intag.getattribute("src") = "images/ukchurch/button-go.jpg" Then
intag.Click
Do While ie.Busy Or ie.ReadyState <> 4
DoEvents
Loop
Application.Wait (Now + TimeValue("00:00:03"))
Exit For
End If
Next intag
Application.Wait (Now + TimeValue("00:00:03"))
Set tdtags = ie.document.getelementsbytagname("td")
For Each td In tdtags
If td.classname = "pText" Then
Debug.Print td.innertext
Debug.Print ie.locationURL
pagecount = Right(td.innertext, InStr(td.innertext, ":"))
End If
Next td
Debug.Print pagecount
End Sub
Any diagnosis would be appreciated.
Automating IE is a pain, so avoid it.
The following function requests the results page directly.
Public Function GetSearchResult(Optional ByVal ResultPage As Integer = 0, Optional ByVal ChurchName As String = "", Optional ByVal Minister As String = "", Optional ByVal ChurchLocation As String = "", Optional ByVal Denomination As String = "") As Object
Dim Request As Object: Set Request = CreateObject("MSXML2.serverXMLHTTP")
Dim Result As Object: Set Result = CreateObject("htmlfile")
Request.Open "POST", "http://www.ukchurch.org/searchresults1.php", False
Request.setRequestHeader "content-type", "application/x-www-form-urlencoded"
Request.send IIf(ResultPage = 0, "", "page=" & ResultPage & "&") & "name=" & ChurchName & "&minister=" & Minister & "&location=" & ChurchLocation & "&denomination=" & Denomination
Result.body.innerHTML = Request.responseText
Set GetSearchResult = Result
End Function
An example which prints the contents of the td with classname pText inside the table containing the search results
Sub Main()
Dim Document As Object
Set Document = GetSearchResult(ChurchLocation:="London")
Dim ResultRows as Object
Dim ResultRow As Object
Set ResultRows = Document.getElementsByTagName("table")(8).getElementsByTagName("td")
For Each ResultRow in ResultRows
If ResultRow.Classname = "pText" Then
Debug.print ResultRow.innerText
End If
Next
End Sub
Update
You need to add a couple of References to your VBA project to make the following code work.
In the VBA Editor, Goto the Tools Menu, Click References and in the dialog that opens add a check next to the following two items: Microsoft XML, v6.0 and Microsoft HTML Object Library (
Public Function GetChurchDetails(ByVal ChurchID As String) As MSHTML.HTMLDocument
Dim Request As New MSXML2.ServerXMLHTTP60
Dim Result As New MSHTML.HTMLDocument
Request.Open "GET", "http://www.ukchurch.org/churchdetails.php?churchid=" & ChurchID, False
Request.send
Result.body.innerHTML = Request.responseText
Set GetChurchDetails = Result
End Function
Sub Main2()
Dim Document As MSHTML.HTMLDocument
Dim Church As MSHTML.HTMLDocument
Set Document = GetSearchResult(ChurchLocation:="London")
Dim ResultRows As MSHTML.IHTMLElementCollection
Dim ResultRow As MSHTML.IHTMLElement
Dim ChurchID As String
'Set ResultRows = Document.getElementsByTagName("table")(8).getElementsByTagName("td")
' all result links on searchresults1.php have a classname of resultslink which makes getting them much easier
Set ResultRows = Document.getElementsByClassName("resultslink")
For Each ResultRow In ResultRows
ChurchID = ResultRow.getAttribute("href")
ChurchID = Mid(ChurchID, InStr(1, ChurchID, "=") + 1)
Set Church = GetChurchDetails(ChurchID)
' code to read data from the page using Church as the Document
' eg: Church.getElemenetsByTagName("td").....
Next
End Sub
You only need to use the "post" mode when your submitting data, for everything else you can use "get"

Webscrape a specific part of a webpage

My webscrape stopped working. The owner changed the html.
I believe it is the Set allElements = doc.getElementsByClassName("el-col el-col-8") line that needs changing.
I am trying to grab text from the webpage that includes the "52-week Range (undefined)" section. I managed to grab text from before and after but not the section I need. An example webpage is https://www.gurufocus.com/stock/gliba/summary and my code should fill my cell with "38.72 - 73.63" after I do some trimming.
I need to do it this way so I can get my head round it and change it in the future when necessary so please just focus on correcting my set line of code (assuming that is the problem!) rather than a whole new more sophisticated method as it will be beyond me. (My other set line of code does what I want it to do.)
Sub get_title_header()
Dim wb As Object
Dim doc As Object
Dim incomeStmtURLs As Variant
Dim sURL As String
Dim lastrow As Long
Dim allRowOfData As Object
Dim i As Integer
Dim allElements As IHTMLElementCollection
Dim anElement As IHTMLElement
Dim aCell As HTMLTableCell
Application.DisplayAlerts = False
Call ToggleEvents(False)
incomeStmtURLs = Range("Sheet1!h1:h2").Value
For i = 1 To UBound(incomeStmtURLs)
Set wb = CreateObject("internetExplorer.Application")
sURL = incomeStmtURLs(i, 1)
wb.navigate sURL
wb.Visible = False
While wb.Busy
Application.Wait Now + #12:00:01 AM#
DoEvents
Wend
Set doc = wb.document
On Error GoTo err_clear
Set allElements = doc.getElementsByClassName("el-col el-col-8")
While allElements.Length = 0
Application.Wait Now + #12:00:01 AM#
DoEvents
Wend
x = allElements(0).innerText
' Debug.Print x
Sheet6.Cells(i + 1, 2).Value = Trim(Replace(Mid(x, InStr(1, x, "52-Week Range (undefined)") + 25, 25), vbLf, ""))
Set allElements = doc.getElementsByClassName("fs-x-large fc-primary fw-bolder")
x = allElements(0).innerText
Sheet6.Cells(i + 1, 4).Value = Trim(Replace(Mid(x, InStr(1, x, "$") + 1, 7), vbLf, ""))
err_clear:
If Err <> 0 Then
Err.Clear
Resume Next
End If
wb.Quit
Next i
Call ToggleEvents(True)
End Sub
Sub ToggleEvents(blnState As Boolean)
Application.DisplayAlerts = blnState
Application.EnableEvents = blnState
If blnState Then Application.CutCopyMode = False
If blnState Then Application.StatusBar = False
End Sub
The page dynamically updates content as you scroll down. You likely need to scroll that part of the page into view then use grab all the elements with classname statictics-item then take the n-2 index e.g. Without the scrolling part:
Set elems = ie.document.getElementsByClassName("statictics-item")
If elems.length > 1 Then Debug.print elems(elems.length-2).innerText
For future readers (I know OP doesn't want this):
I would avoid the whole scrolling pickle, dynamic html and browser and issue an xmlhttp request and regex out the appropriate values from the javscript objects the web page uses for updating. N.B. I would probably add in validation on regex match positions.
Public Sub test()
Dim r As String
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", "https://www.gurufocus.com/stock/gliba/summary", False
.send
r = GetMatches(.responseText, "price52wlow:(.*?),|price52whigh:(.*?),")
If r <> "NA" Then MsgBox r
End With
End Sub
Public Function GetMatches(ByVal inputString As String, ByVal sPattern As String) As String
Dim matches As Object
With CreateObject("vbscript.regexp")
.Global = True
.MultiLine = True
.IgnoreCase = True
.Pattern = sPattern
'If .test(inputString) Then
Set matches = .Execute(inputString)
If matches.Count = 2 Then
GetMatches = matches.Item(0).submatches(0) & "-" & matches.Item(1).submatches(1)
Else
GetMatches = "NA"
End If
End With
End Function
Regex: