Get data from the last filtered row in a webtable with Selenium VBA

228 views Asked by At

I am trying to access https://www.tablefilter.com/0-configuration.html which has a table with filters, then filter according to country specific criteria.

I want the last row that was filtered for this country, which in this case is "Russia" to copy the year into Excel cell B1. This case returns three rows for the years 1998, 1999 and 2000.
In the case of "Slovak Republic" there is one row.
In the case of "Zimbabwe" there are seven rows.

I need to obtain, for any country, the year of the last row of this table or of the only record, understanding that they are dynamic records.

Sub Filtros()

Dim bot As New WebDriver
''Dim Sbutton As Selenium.WebElement
''Dim lista As Selenium.SelectElement
Dim Keys As New Selenium.Keys
        
bot.Start "chrome"
bot.Get "https://www.tablefilter.com/0-configuration.html"

''Application.Wait (Now + TimeValue("00:00:02"))
bot.FindElementById("flt0_demo").SendKeys "Russia"
bot.FindElementById("flt0_demo").SendKeys Keys.Enter

Stop

End Sub
1

There are 1 answers

1
QHarr On BEST ANSWER

You could use a css selector list to filter on the visible rows after table filtering. You would then need to take the last webElement in the matched webElements collection, set in a variable, using .Count.

Dim elems As WebElements, last As WebElement

Set elems = bot.FindElementsByCss("#demo tbody > tr:not([style]) > td:nth-child(3)")

Set last = elems.item(elems.Count)

Debug.Print last.Text

The table filtering adds a style attribute with value display: none; to the rows not to be shown within the table. Excluding rows within the table body that have a style attribute, tbody > tr:not([style]), allows one to match just the visible rows. Then, select for the 3rd column (year), > td:nth-child(3), and take the last.

enter image description here


You may need some form of wait for filtering, based on your initial text entry, to be applied. This could be achieved by using a timed loop (to avoid infinite looping), with one exit condition being a max time to loop being exceeded and the other being:

bot.findElementsByCss("#demo tbody > tr[style]").count > 0

Exit for whichever comes first.

Or, use the inbuilt timeout mechanism and attempt to match on a hidden row (which would mean filtering had occurred for at least one row):

Dim hiddenRow As WebElement

Set hiddenRow = bot.FindElementByCss("#demo tbody > tr[style]", timeout:=<enter timeout>, Raise:=False)

If hiddenRow Is Nothing Then Exit Sub