【问题标题】:Difficulty Finding Table CheckBoxes难以找到表格复选框
【发布时间】:2014-05-07 14:12:20
【问题描述】:

我正在尝试使用 Excel VBA 在 IE 中执行非常手动的过程。我已经使用 VBA 和 IE 完成了一些简单的任务,例如在字段中输入文本或与按钮交互,但是我很难解决这个问题。

我在 Excel 中有一个字段列表:名字、姓氏、电子邮件地址。电子表格中有两千多行信息。我正在使用的网站有一个包含三千多行信息的列表(相同的信息加上一个复选框),但它一次最多只能加载 100 行。 Excel 中的每一行数据都存在于网络工具中。

我想让我的程序遍历名称并检查网页上的相应行。问题是弄清楚如何识别相应复选框的输入 id。我对 HTML 不是很熟悉,所以我的代码非常简陋......我花了一天的大部分时间写这个:

Sub Test()
Dim str As String
Dim ie As SHDocVw.InternetExplorer
Dim doc As HTMLDocument
Dim tbls As Object
Dim tbl As Object
Dim trow As Object
Dim trs As Object
Dim Cell As Range

Set ie = New SHDocVw.InternetExplorer
ie.navigate "https://test.com"
ie.Visible = True
Set doc = ie.Document
Set tbls = doc.getElementsByTagName("TABLE")
For Each Cell In Range("A2:A2200")
    For Each tbl In tbls
        For Each trow In tbl.Rows
            If InStr(1, trow.Cells(i).innerText, Cell.Offset(0, 1) & ", " & Cell) > 0 Then
                Debug.Print trow.Cells(0).innerText
                Stop
            End If
        Next trow
    Next tbl
Next Cell

End Sub

上面的代码能够识别页面上与工作簿中的单元格匹配的单元格,但我不知道如何找到关联复选框的 id。该网站是私人的,所以我无法提供链接。请参阅下文,了解该网站的相关源代码:

        <div>
        <table cellspacing="0" border="0" id="ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults" style="border-color:Black;border-width:1px;border-style:Solid;width:100%;border-collapse:collapse;">
            <tr>
                <td colspan="6">
                <table id="ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl01_tabPager" border="0" cellpadding="5" width="100%">
                    <tr>
                        <td style="border-style:none;">
                            <a id="ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl01_lbPrev" disabled="disabled">Previous</a>
                            &nbsp;&nbsp;
                            <a id="ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl01_lbNext" disabled="disabled">Next</a>
                        </td>
                        <td style="border-style:none;" align="right">
                            <b>Showing:</b>
                            <span id="ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl01_rblShow"><input id="ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl01_rblShow_0" type="radio" name="ctl00$ctl00$all_content$all_content$content$ucUserSearch$gvSearchResults$ctl01$rblShow" value="10" checked="checked" /><label for="ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl01_rblShow_0">10 People</label><input id="ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl01_rblShow_1" type="radio" name="ctl00$ctl00$all_content$all_content$content$ucUserSearch$gvSearchResults$ctl01$rblShow" value="25" onclick="javascript:setTimeout('__doPostBack(\'ctl00$ctl00$all_content$all_content$content$ucUserSearch$gvSearchResults$ctl01$rblShow$1\',\'\')', 0)" /><label for="ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl01_rblShow_1">25 People</label><input id="ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl01_rblShow_2" type="radio" name="ctl00$ctl00$all_content$all_content$content$ucUserSearch$gvSearchResults$ctl01$rblShow" value="50" onclick="javascript:setTimeout('__doPostBack(\'ctl00$ctl00$all_content$all_content$content$ucUserSearch$gvSearchResults$ctl01$rblShow$2\',\'\')', 0)" /><label for="ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl01_rblShow_2">50 People</label><input id="ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl01_rblShow_3" type="radio" name="ctl00$ctl00$all_content$all_content$content$ucUserSearch$gvSearchResults$ctl01$rblShow" value="100" onclick="javascript:setTimeout('__doPostBack(\'ctl00$ctl00$all_content$all_content$content$ucUserSearch$gvSearchResults$ctl01$rblShow$3\',\'\')', 0)" /><label for="ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl01_rblShow_3">100 People</label></span>
                        </td>
                    </tr>
                    <tr id="ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl01_trSelectOptions">
                        <td colspan="2" style="border-style: none;" align="left">

                                <a href="javascript:SetCheckedAll(true);">Select All on Page</a>
                                &nbsp;&nbsp;
                                <a href="javascript:SetCheckedAll(false);">Clear All on Page</a>
                                &nbsp;&nbsp;

                            <a class="link_w_img" href="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;ctl00$ctl00$all_content$all_content$content$ucUserSearch$gvSearchResults$ctl01$ctl09&quot;, &quot;&quot;, true, &quot;&quot;, &quot;&quot;, false, true))">
                                    <img src="/images/all.gif" />
                                    <span>Select Entire List</span></a>
                                &nbsp;&nbsp;
                                <a class="link_w_img" href="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;ctl00$ctl00$all_content$all_content$content$ucUserSearch$gvSearchResults$ctl01$ctl11&quot;, &quot;&quot;, true, &quot;&quot;, &quot;&quot;, false, true))">
                                    <img src="/images/none.gif" />
                                    <span>Clear Entire List</span></a>
                        </td>
                    </tr>
                </table>    
            </td>
            </tr>

            <tr class="gridheader" align="left">
                <th scope="col">Select</th>
                <th scope="col">Last Name</th>
                <th scope="col">First Name</th>
                <th scope="col">Middle Name</th>
                <th scope="col">E-mail Address</th>
                <th scope="col" style="width:0px;">&nbsp;</th>
            </tr>

            <tr class="griditem" align="center">
                <td>
                    <input id="ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl03_SelectCheckBox" type="checkbox" name="ctl00$ctl00$all_content$all_content$content$ucUserSearch$gvSearchResults$ctl03$SelectCheckBox" />
                </td>
                <td align="left" onmouseover="ShowPopup('ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl03_divTip');" onmouseout="HidePopup();">Demo1</td>
                <td align="left" onmouseover="ShowPopup('ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl03_divTip');" onmouseout="HidePopup();">Test</td>
                <td align="left" onmouseover="ShowPopup('ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl03_divTip');" onmouseout="HidePopup();">&nbsp;</td>
                <td align="left" onmouseover="ShowPopup('ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl03_divTip');" onmouseout="HidePopup();">Demo1@Test.com</td>
                <td style="width:0px;">
                    <div id="ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl03_divTip" class="popup">
                        <div class="popupbg">
                            <table>
                                <tr>
                                    <td style="vertical-align:top;">
                                        <span id="ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl03_lblName" style="font-weight:bold;">Demo1, Test </span>
                                        <br />E-mail:<span id="ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl03_lblEmail">Demo1@Test.com</span><br />
                                            <table cellspacing="0" border="0" id="ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl03_dgDemos" style="border-style:None;border-collapse:collapse;margin-top:-1.25em;">
                                <tr>
                                <td>&nbsp;
                                </td><td>&nbsp;
                                </td>
                        </tr><tr>
                            <td>
                                                            Employee ID: 
                                                        </td><td>
                                                            N/A
                                                        </td>
                        </tr><tr>
                            <td>
                                                            Job Title: 
                                                        </td><td>
                                                            N/A
                                                        </td>
                        </tr><tr>
                            <td>
                                                            Location: 
                                                        </td><td>
                                                            N/A
                                                        </td>
                        </tr>
                    </table>
                                        </td>
                                        <td style="width:50px;vertical-align:top;">
                                            <img src="/images/user_popup.jpg" border="0" width="48" height="48"/>
                                        </td>
                                    </tr>
                                </table>
                            </div>

                </div>
                    </td>

在上面的例子中,姓是Demo1,名字是Test,Email是Demo1@Test.com,复选框的输入id是ctl00_ctl00_all_content_all_content_content_ucUserSearch_gvSearchResults_ctl03_SelectCheckBox

我的问题是,在识别出表格行后,如何识别输入 id?或者,也许那是不可能的,我正在以错误的方式解决这个问题?任何想法将不胜感激。


编辑

这是我尝试过的,它给了我运行时错误 (Object variable or With block variable not set):

trow.Cells(0).getElementsByTagName("input")(0).Click

我也试过这个:

set input = trow.Cells(0).getElementsByTagName("input")(0)
input.Click

最后,这两个都会产生相同的错误:

Debug.Print trow.Cells(0).getElementsByTagName("input")(0).innerText
Debug.Print trow.Cells(0).getElementsByTagName("input")(0)

这是我原始代码中Debug.Print 的输出:

Demo1, Test
E-mail: Demo1@Test.com


Employee ID: N/A
Job Title: N/A
Location: N/A

我唯一关心的部分(在输出中)是前两行,个人的电子邮件和姓名。

【问题讨论】:

  • trow.Cells(0).getElementsByTagName("input")(0) 将为您提供对复选框的引用。如果所有这些记录都在同一个表中,那么一旦识别出匹配的行,您可能应该缓存对正确表的引用,这样您就不必多次扫描页面上的每个表。
  • 当我尝试这样做时,我得到了一个Runtime Error 91。所以也许我的代码没有识别正确的行?另外,我将如何缓存对该行的引用?我以前从来没有这样做过……
  • 如果您可以更新您的问题以显示您在尝试此操作时所做的更改会有所帮助:如果您想保留原始代码,请发布第二个仅包含相关行的块 od 代码.不幸的是,在没有实际访问 URL 的情况下尝试调试此类问题就像试图通过钥匙孔粉刷一个房间......
  • @TimWilliams 请查看我的编辑。我认为.Click 是引发错误的原因。我想我不知道如何使用您的建议标记复选框。我知道在这些问题上很难提供帮助...非常感谢您的帮助!
  • 原始代码中的 debug.print 是否给出了预期的结果?即,您是否获得了复选框的 HTML?

标签: vba internet-explorer excel checkbox


【解决方案1】:

这个测试对我有用。看起来您想要的所有行都具有class="griditem",因此您可以检查该类名称的所有表行。当您找到匹配项和单元格值时,您应该能够找到如图所示的复选框。

Sub Tester()

Dim d As New HTMLDocument, trs, rw

    d.body.innerHTML = _
       "<section><table><tr class='griditem'><td>" & _
       "<input type='checkbox' id='id_1'></td>" & _
       "<td>Foo</td></tr><tr class='griditem'><td>" & _
       "<input type='checkbox' id='id_2'></td>" & _
       "<td>Bar</td></tr></table></section>"

    Set trs = d.getElementsByTagName("tr")
    For Each rw In trs
        If rw.className = "griditem" Then
            'check cell values for match....
            Debug.Print rw.Cells(0).getElementsByTagName("input")(0).ID
        End If
    Next rw

End Sub

【讨论】:

  • 蒂姆,我非常感谢你为此付出的努力!在实现您的代码后,我能够让它工作。一个问题,之前您提到在匹配行之后缓存对行的引用。你能指出我如何做到这一点的正确方向吗?您是在谈论将每个匹配的行存储在一个数组中并检查每个值的数组吗?
  • 这与您以前的方法更相关,并且实际上更多的是关于性能而不是任何东西:如果您要在表中查找许多值,那么扫描所有行一次可能会更快,将单元格值和复选框 id 放入某种数组中。除非当前方法的性能很差,否则增加的复杂性可能不值得。
  • 有道理。我还没有能够进行完整的测试,所以我不确定此时的性能是什么样的。尽管我可以肯定地说,这将是对手动方法的巨大改进。再次感谢您的帮助!
【解决方案2】:

试试这个。

Set ElementCol = ie.Document.getElementsByTagName("input")

For Each btnInput In ElementCol

'your code here 


Next btnInput

【讨论】:

  • 这将遍历输入标签,但我怎么知道该输入标签是否是对应于工作簿中正确行的标签?输入标签中是否有更多信息可以让我以某种方式访问​​和使用来执行此操作?
  • 您可以按类型、名称访问输入标签。像 btnInput.type = "Submit" 然后做点什么。
  • 好的,但是页面上可能有 100 个复选框。我如何知道 btnInput 是否是迭代中当前单元格的正确复选框?也许我没有理解你的意思?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-30
  • 2017-04-06
  • 1970-01-01
  • 2011-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多