2

I've written some code in vba using IE to reach a certain webpage. To get that webpage it is necessary to initiate a click on a link in the opening page and when the click is successfully performed then the page i am after shows up. However, I can't find any way to click on that very link.

Elements for the link within:

<div id="grid" data-role="grid" class="k-grid k-widget" style="opacity: 1;"><div class="k-grid-header" style="padding-right: 17px;"><div class="k-grid-header-wrap k-auto-scrollable"><table role="grid"><colgroup><col style="width:100px"><col style="width:210px"><col><col><col style="width:120px"></colgroup><thead role="rowgroup"><tr role="row"><th role="columnheader" data-field="PropertyQuickRefID" rowspan="1" data-title="PROPERTY ID" data-index="0" id="68a98aa1-147e-47f5-8eb6-1bb59bc5f37e" class="k-header" data-role="columnsorter"><a class="k-link" href="#">PROPERTY ID</a></th><th role="columnheader" data-field="PropertyNumber" rowspan="1" data-title="ACCOUNT" data-index="1" id="d4f307be-0d97-41cd-8e04-869fd5a041f4" class="k-header" data-role="columnsorter"><a class="k-link" href="#">ACCOUNT</a></th><th role="columnheader" data-field="PartyQuickRefID" rowspan="1" data-title="OWNER ID" data-index="2" id="1a4c6015-4851-4c78-9a67-1e3f2f384b00" style="display:none" class="k-header" data-role="columnsorter"><a class="k-link" href="#">OWNER ID</a></th><th role="columnheader" data-field="OwnerName" rowspan="1" data-title="OWNER NAME" data-index="3" id="206614df-19d6-4ae4-a27a-496bdda92fb3" class="k-header" data-role="columnsorter"><a class="k-link" href="#">OWNER NAME</a></th><th role="columnheader" data-field="SitusAddress" rowspan="1" data-title="SITUS ADDRESS" data-index="4" id="5cba12e3-5dde-4d67-b664-2832adf92c29" class="k-header" data-role="columnsorter"><a class="k-link" href="#">SITUS ADDRESS</a></th><th role="columnheader" data-field="LegalDescription" rowspan="1" data-title="LEGAL DESCRIPTION" data-index="5" id="3199fe1c-1ee1-4f87-87ff-5effca8a9cfe" style="display:none" class="k-header" data-role="columnsorter"><a class="k-link" href="#">LEGAL DESCRIPTION</a></th><th role="columnheader" data-field="NeighborhoodCode" rowspan="1" data-title="NEIGHBORHOOD CODE" data-index="6" id="c4b711f3-e793-45f3-b086-c95f9215a66f" style="display:none" class="k-header" data-role="columnsorter"><a class="k-link" href="#">NEIGHBORHOOD CODE</a></th><th role="columnheader" data-field="Abstract" rowspan="1" data-title="ABSTRACT" data-index="7" id="135291e9-f5e8-4d3e-9c91-50c90bf6f339" style="display:none" class="k-header" data-role="columnsorter"><a class="k-link" href="#">ABSTRACT</a></th><th role="columnheader" data-field="Subdivision" rowspan="1" data-title="SUBDIVISION" data-index="8" id="3951acbf-89f5-4f55-902c-0c55e78d124f" style="display:none" class="k-header" data-role="columnsorter"><a class="k-link" href="#">SUBDIVISION</a></th><th role="columnheader" data-field="PropertyType" rowspan="1" data-title="PROPERTY TYPE" data-index="9" id="d71ff4cd-d5fb-4b9c-9f7f-17f4ce0a2154" style="display:none" class="k-header" data-role="columnsorter"><a class="k-link" href="#">PROPERTY TYPE</a></th><th role="columnheader" data-field="PropertyValue" rowspan="1" data-title="2017 VALUE" data-index="10" id="feb614c1-9ee4-4653-bd92-d5b411bf255e" class="k-header">2017 VALUE</th></tr></thead></table></div></div><div class="k-grid-content k-auto-scrollable"><table role="grid" data-role="selectable" class="k-selectable" style="touch-action: none;"><colgroup><col style="width:100px"><col style="width:210px"><col><col><col style="width:120px"></colgroup><tbody role="rowgroup"><tr data-uid="f6c50847-b17b-4f32-9377-5386deabce48" role="row" class="rowHover"><td role="gridcell">R016698</td><td role="gridcell">R-13-0410-0620-50000</td><td style="display:none" role="gridcell">O0485204</td><td role="gridcell">GOOCH, PHILIP L</td><td role="gridcell">319 LIZZIE ST, TAYLOR, TX  76574</td><td style="display:none" role="gridcell">DOAK ADDITION, BLOCK 62, LOT 5</td><td style="display:none" role="gridcell">T541</td><td style="display:none" role="gridcell"> </td><td style="display:none" role="gridcell">S3564 - Doak Addition</td><td style="display:none" role="gridcell">Real</td><td role="gridcell"><div style="text-align:right;width:100%">$46,785</div></td></tr></tbody></table></div><div class="k-pager-wrap k-grid-pager k-widget k-floatwrap" data-role="pager"><a href="#" title="Go to the first page" class="k-link k-pager-nav k-pager-first k-state-disabled" data-page="1" tabindex="-1"><span class="k-icon k-i-seek-w">Go to the first page</span></a><a href="#" title="Go to the previous page" class="k-link k-pager-nav  k-state-disabled" data-page="1" tabindex="-1"><span class="k-icon k-i-arrow-w">Go to the previous page</span></a><span class="k-pager-input k-label">Page<input class="k-textbox">of 1</span><a href="#" title="Go to the next page" class="k-link k-pager-nav  k-state-disabled" data-page="1" tabindex="-1"><span class="k-icon k-i-arrow-e">Go to the next page</span></a><a href="#" title="Go to the last page" class="k-link k-pager-nav k-pager-last k-state-disabled" data-page="1" tabindex="-1"><span class="k-icon k-i-seek-e">Go to the last page</span></a><span class="k-pager-sizes k-label"><span title="" class="k-widget k-dropdown k-header" unselectable="on" role="listbox" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-owns="" aria-disabled="false" aria-readonly="false" aria-busy="false" aria-activedescendant="8334826b-15aa-41ed-976d-52d896a5ac8a" style=""><span unselectable="on" class="k-dropdown-wrap k-state-default"><span unselectable="on" class="k-input">20</span><span unselectable="on" class="k-select"><span unselectable="on" class="k-icon k-i-arrow-s">select</span></span></span><select data-role="dropdownlist" style="display: none;"><option value="10">10</option><option value="15">15</option><option value="20">20</option><option value="50">50</option><option value="100">100</option></select></span>items per page</span><a href="#" class="k-pager-refresh k-link" title="Refresh"><span class="k-icon k-i-refresh">Refresh</span></a><span class="k-pager-info k-label">1 - 1 of 1 items</span></div></div>

Script I'm trying with:

Sub Get_Page()
    Dim IE As New InternetExplorer, html As HTMLDocument

    With IE
        .Visible = True
        .navigate "link"
        Do Until .readyState = READYSTATE_COMPLETE: Loop
        Set html = .Document
    End With

   html.getElementsByClassName("k-selectable")(1).Click
   Application.Wait (Now + TimeValue("0:00:05"))

End Sub

This is The link which will be placed in my script.

This is the image of that link which is marked with a pencil:

enter image description here

When I do the same using selenium along with css selector then it works:

Sub Trigger_Click()
  Dim driver As New ChromeDriver, html As New HTMLDocument

  With driver
    .Get "replace_with_above_link"
    .Wait 1000
  End With

  driver.FindElementByCss(".k-selectable tr[role='row']").Click
  driver.Wait 1000

  driver.Quit
End Sub

So I tried with .querySelector() in my above script replacing html.getElementsByClassName("k-selectable")(0).Click with html.querySelector(".k-selectable tr[role='row']").Click but it did not work either. As selenium can do the trick I'm still sanguine, IE can do the same.

With sir alecxe's suggestion It seems I'm very close to the solution. I've been able to select the first portion of the grid with the method I'm pasting below along with a picture to show how the grid looks like when i executed my script. The selected portion of the grid gets different look than the other portions. All i need to do now is a click.

Here is the portion of kendoGrid method:

html.parentWindow.execScript "$('#grid').data('kendoGrid').select('.k-selectable tr td:eq(0)');"

This is the picture of the selected portion of the grid:

enter image description here

This is the refined script which can do the job:

Sub Get_Page()
    Dim IE As New InternetExplorer, html As HTMLDocument

    With IE
        .Visible = True
        .navigate "replace_with_above_link"
        Do Until .readyState = READYSTATE_COMPLETE: Loop
        Set html = .Document
    End With

   Application.Wait (Now + TimeValue("0:00:05"))
   html.parentWindow.execScript "$('#grid').data('kendoGrid').select('.k-selectable tr[role=row]');"
   html.queryselector(".k-selectable tr[role=row]").Click
   Application.Wait (Now + TimeValue("0:00:05"))
End Sub

Acknowledgement: Pasted above the working solution by taking permission from the owner of this solution @sir alecxe.

SIM
  • 21,997
  • 5
  • 37
  • 109
  • 1
    at first, try debug.print html.getElementsByClassName("k-selectable")(0).innerText and see if you are in right place. – MarcinSzaleniec Oct 25 '17 at 08:33
  • try using the ID – mojo3340 Oct 25 '17 at 09:01
  • According to the text visible on the link which I want to click can be found using `html.getElementsByClassName("k-selectable")(1).innerText` so I tried using `html.getElementsByClassName("k-selectable")(1).Click` but it doesn't bring any result either. – SIM Oct 25 '17 at 09:09
  • does your code only need to work for the one link, or dynamically with various records? – ashleedawg Dec 25 '17 at 00:37
  • Clicking on the aforementioned link will suffice @ashleedawg. – SIM Dec 25 '17 at 03:53
  • In that case, I don't why don't you just [load the target directly](http://search.wcad.org/Property-Detail?PropertyQuickRefID=R016698) (instead of loading Search Results and then clicking it)? – ashleedawg Dec 25 '17 at 04:12
  • Only because I wish to know how click works here. Btw, the data I'm not after cause I've already scraped that. – SIM Dec 25 '17 at 04:26
  • 1
    Oh okay, I'm won't spend time on it then, but the short explanation of why it won't work is because it's not a button, nor a hyperlink that needs to be clicked, rather is responding to a javascript event. – ashleedawg Dec 25 '17 at 04:47

1 Answers1

1

When you are using k-selectable class to locate an element, what you get is the table element, but you need to get the clickable row - tr element.

Now, the problem is, you cannot trigger the "click" of the row element node directly. See what happens when you do it in the browser console:

> document.querySelector(".k-selectable tr[role=row]").click()
Property-Search-Result?searchtext=319 lizzie taylor:672 Uncaught TypeError: Cannot read property 'PropertyQuickRefID' of null
    at HTMLTableRowElement.<anonymous> (Property-Search-Result?searchtext=319 lizzie taylor:672)
    at HTMLDivElement.dispatch (VM45 jquery.js?cdv=282:3074)
    at HTMLDivElement.elemData.handle (VM45 jquery.js?cdv=282:2750)
    at <anonymous>:1:54

This is because it is a specific "kendo UI" grid and the row selection event needs to happen before the click itself.

Programmatically, we can "select" a kendo UI grid row using this suggestion:

var grid = $("#grid").data("kendoGrid"); 

var rows = grid.dataSource.data(); 
var lastRowUid = rows[0].uid;

var row = grid.table.find("[data-uid=" + lastRowUid + "]");    
grid.select(row);

And then click:

document.querySelector(".k-selectable tr[role=row]").click();

Works for me in the Chrome console but I have no way to test it in VBA at the moment.

From what I understand, you can always use execScript to execute javascript with the above-provided logic, example:

alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • Thanks again sir for your response. Basically, it neither works nor throws any error and finally quits the browser gracefully. – SIM Dec 26 '17 at 17:39
  • @Topto thanks for the information! I've updated the answer with some more research. It works for me in the chrome console, but I can imagine you need to tweak the kendo grid selection code to work in VBA.. – alecxe Dec 26 '17 at 17:54