使用 Excel VBA 在 Kendo UI 小部件中选择/操作项目 [英] Selecting/actioning items in Kendo UI widgets using Excel VBA

查看:16
本文介绍了使用 Excel VBA 在 Kendo UI 小部件中选择/操作项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

卡住 - 需要帮助!

我正在尝试在我们公司内部网站的 IE 网页中自动执行操作项.我可以填写任何类型的文本对象、点击提交按钮等,但有几个项目要么在网格/表格中(Kendo网格)下拉列表.我似乎无法弄清楚如何从这些网格/表格或下拉列表中进行选择.

I'm trying to automate actioning items in an IE web page on our internal company site. I'm able to fill out any kind of text object, click on a submit button etc., but several items are either in a grid/table (Kendo Grid) or a dropdown list. I just can't seem to figure out how to select from these grids/tables or dropdowns.

我已经尝试了所有我能想到的方法,但无济于事.我使用过 getElementById()getElementsByTagName()getElementsByName(),甚至一些网页抓取技术.

I've tried everything I can think of, to no avail. I've used getElementById(), getElementsByTagName(), getElementsByName(), and even some web scraping techniques.

不幸的是,由于网页位于内部网站上,其他人无法对其进行测试.

Unfortunately, as the web page is on an internal site, no one else will be able to test against it.

这是我代码的主要部分

 'After opening the web page, inserting a number, selecting the "search"
 ' (all from the VBA script), I have to use a "mousemove", "mousedown" and     
 ' "mouseup" to select the item, whick is what the "myClick" subroutine does

     myClick '<<< THIS IS WHAT I WANT TO GET RID OF >>>

   'I left the following segment in to show that I'm able to do several other functions        
    myDocs = ie.Document.getElementById("DispatchComments").Value

    If myInfo = True Then
        ie.Document.getElementById("DispatchComments").Value = "__" & myCell5 & "__" & myDocs
    Else: End If

   'IF ESTIMATED TIME IS LESS THAN 0, ENTER 120 - Enter estimated time    
  If ie.Document.getElementById("TotalEstimatedTime").Value < 10 Then
    ie.Document.getElementById("TotalEstimatedTime").Value = 120

   Else: End If

  End With

End Sub

`

这是输入租约号并点击搜索按钮后的屏幕截图.我设法选择该行的唯一方法是以编程方式在显示的三个白色背景区域之一中单击鼠标.我的代码使用 mousemove 和坐标来选择行,向下滚动到一个坦克下拉菜单,然后点击打开,这样我就可以手动选择一个坦克编号.

This is a screen shot after entering the lease number and clicking the search button. The only way I've managed to select the row is to programmatically click the mouse in one of the three white-background areas shown. My code uses mousemove and coordinates to select the row, scroll down to a tank dropdown and click it open so I can manually choose a tank number.

这部分代码是我卡住的地方

This portion of the code is where I'm stuck

Set myChoice1 = ie.Document.getElementById("drgdLease").getElementsByTagName("tr")(1)
        With myChoice1
         .getElementsByTagName("td")(0).Focus '<<---Works all the way to here
         .FireEvent ("onmouseover")           '<<---No errors from this point on
         .FireEvent ("onmousedown")                'but doesn't do anything
         .FireEvent ("onmouseup")
         .FireEvent ("onclick")                '<<---some other things tried
         .FireEvent ("ondblclick")
         .FireEvent ("onselect")
         td.innerText = value
         td.innerHTML = value
        End With

'<tr role="row" data-uid="db62d811-4337-477c-a0fd-0e9e036670bb">
'  <td role="gridcell">998262</td> '<<---This is the info/row I need to select
'  <td role="gridcell">HENDERSON (SMACKOVER) STORAGE</td>
'  <td role="gridcell">ORYAN OIL &amp; GAS</td>

检查我尝试选择的区域的元素显示此 HTML

Inspecting the element for the area I'm trying to select shows this HTML

 name="Result">
 <div class="k-widget k-grid" id="drgdLease" style="-ms-touch-action: double-tap-zoom pinch-zoom;" data-role="grid">
    <table class="k-selectable" role="grid" style="-ms-touch-action: double-tap-zoom pinch-zoom;" data-role="selectable">
       <colgroup>
          <col>
          <col>
          <col>
       </colgroup>
       <thead class="k-grid-header" role="rowgroup">
          <tr role="row">
             <th class="k-header k-with-icon" scope="col" data-title="Lease Number" data-index="0" data-field="LeaseCode" data-role="columnsorter">
                <a tabindex="-1" class="k-header-column-menu" href="#">
                   <span class="k-icon k-i-arrowhead-s"></span>
                </a>
                <a class="k-link" href="/LeaseProfiles/GetLeasesSearch?Length=9&amp;drgdLease-sort=LeaseCode-asc">Lease Number</a>
             </th>
             <th class="k-header k-with-icon" scope="col" data-title="Lease Name" data-index="1" data-field="LeaseName" data-role="columnsorter">
                <a tabindex="-1" class="k-header-column-menu" href="#">
                   <span class="k-icon k-i-arrowhead-s"></span>
                </a>
                <a class="k-link" href="/LeaseProfiles/GetLeasesSearch?Length=9&amp;drgdLease-sort=LeaseName-asc">Lease Name</a>
              </th>
             <th class="k-header k-with-icon" scope="col" data-title="Lease Operator" data-index="2" data-field="LeaseOperator.OperatorName" data-role="columnsorter">
                <a tabindex="-1" class="k-header-column-menu" href="#">
                   <span class="k-icon k-i-arrowhead-s"></span>
                </a>
                <a class="k-link" href="/LeaseProfiles/GetLeasesSearch?Length=9&amp;drgdLease-sort=LeaseOperator.OperatorName-asc">Lease Operator</a>
             </th>
          </tr>
       </thead>

<!--
 This is what the code looks like before selecting the item. 
 ie: before clicking  anywhere on the row.
-->

       <tbody role="rowgroup">
          <tr role="row" data-uid="db62d811-4337-477c-a0fd-0e9e036670bb">
             <td role="gridcell">998262</td>                         
             <td role="gridcell">HENDERSON (SMACKOVER) STORAGE</td>
             <td role="gridcell">ORYAN OIL &amp; GAS</td>
          </tr>
       </tbody>
    </table>

<!--
 This is what the code changes to after clicking the row. 
 Note the class and arial are added on the `tr role` line, which may be binding  the data.
-->

 <tr role="row" data-uid="db62d811-4337-477c-a0fd-0e9e036670bb" class = "k-state- selected" arial = "true">
   <td role="gridcell">998262</td> 
   <td role="gridcell">HENDERSON (SMACKOVER) STORAGE</td>
   <td role="gridcell">ORYAN OIL &amp; GAS</td>

推荐答案

这是如何选择kendoGrid的第一行:

This is how to select the first row of the kendoGrid:

ie.Document.parentWindow.execScript "$('#drgdLease').data('kendoGrid').select('tr:eq(0)');"


下面是一个演示,展示了在官方 Kendo UI 上工作的等效代码网格小部件演示页面.

注意可能的竞争条件的变通方法.虽然这种特殊的竞争条件可能也适用于您的情况,但还有另一个竞争条件,您需要注意.

Note the work-around for the possible race condition. While it may be that this particular race condition also applies in your case, there is another race condition that you need to be aware of.

有可能在开始搜索租用号之后, kendoGrid 完成更新之前,您的代码可能会尝试选择第一行.这将导致选择默认显示数据/以前搜索数据的第一行,然后更新网格,导致选择消失.

It's possible that, after having initiated the search for the lease number, and before the kendoGrid has finished updating, your code might attempt to select the first row. This would result in the first row of the default displayed data/previous search data being selected, and then the grid being updated, causing the selection to disappear.

在这种情况下,下面代码中采用的变通办法将不起作用,因为它总是(错误地)检测到选定的行.需要不同的解决方法.(我可以想到一些 - 最合适的可能取决于您的具体用例.)

The work-around employed in the code below will not work in this case, as it will always (incorrectly) detect a selected row. A different workaround is needed. (I can think of a few - the most suitable probably depending on your exact use case.)

'============================================================================================
' Module     : <in any standard module>
' Version    : 0.1
' Part       : 1 of 1
' References : Microsoft Internet Controls   [SHDocVw]
' Source     : https://stackoverflow.com/a/46483783/1961728
'============================================================================================
  ' Required if late binding SHDocVw
  Private Enum tagREADYSTATE
    READYSTATE_UNINITIALIZED = 0
    READYSTATE_LOADING
    READYSTATE_LOADED
    READYSTATE_INTERACTIVE
    READYSTATE_COMPLETE
  End Enum

Public Sub AutomateKendoUI()

  ' Create and use a new instance of IE
  With New SHDocVw.InternetExplorer '##Late Binding: CreateObject("InternetExplorer.Application")
    .Visible = True ' False is default

    .Navigate "http://demos.telerik.com/kendo-ui/grid/index"
    Do Until .Busy = False And .ReadyState = SHDocVw.tagREADYSTATE.READYSTATE_COMPLETE: DoEvents: Loop '##Late Binding: = tagREADYSTATE.READYSTATE_COMPLETE  ##No Enums: = 4

    ' Get and use the main DOM
    With .Document
      ' Race Condition Work-Around
      '   Kendo UI may not have finished loading the Grid data before we invoke its select method.
      '   Therefore, we continue to invoke the method until a selected row is detected.
      Do
        .parentWindow.execScript "$('#grid').data('kendoGrid').select('tr:eq(0)');"
        On Error Resume Next
          Dim elm_tr As MSHTML.HTMLTableRow: Set elm_tr = .querySelector("#grid tr.k-state-selected")
        On Error GoTo 0
      Loop While elm_tr Is Nothing

    End With
  End With
End Sub

<小时>


来源:

来自 官方 Kendo UI API 文档 用于 select 方法1:



Sources:

From the official Kendo UI API documentation for the select method1:

示例 - 选择第一行和第二行
...

Example - select the first and second table rows
...

var grid = $("#grid").data("kendoGrid");
grid.select("tr:eq(1), tr:eq(2)");

请注意,这实际上是错误的.第一行在索引 0 处,不是索引 1. select 方法的字符串参数被视为 jQuery 选择器,来自 官方 jQuery API 文档,用于 :eq() 选择器2:

Note that this is actually wrong. The first row is at index 0, not index 1. A string parameter for the select method is treated as a jQuery selector, and from the official jQuery API documentation for the :eq() selector2:

eq 选择器

描述: *选择匹配集合中索引 n 处的元素.*

Description: *Select the element at index n within the matched set.*

jQuery(":eq(index)")

index: 基于零的要匹配元素的索引.

index: Zero-based index of the element to match.


有趣的是,官方剑道用户界面tbody 对象的 API 文档虽然正确3:


Interestingly, the official Kendo UI API documentation for the tbody object gets it right though3:

示例 - 获取表格的第一行
...

Example - get the first table row
...

var grid = $("#grid").data("kendoGrid");
var row = grid.tbody.find("tr:eq(0)");

<小时>


1 http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#methods-select
2 https://api.jquery.com/eq-selector/
3 http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#fields-tbody

这篇关于使用 Excel VBA 在 Kendo UI 小部件中选择/操作项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆