如果同一行中的单元格值等于Excel工作簿中的值,则如何单击HTML表格中的href

时间:2018-01-31 03:07:22

标签: html excel vba excel-vba html-table

我尝试根据Excel模板中的值自动化网络表单的填充。我已成功访问该网站,并使用下面的VBA代码点击几下。接下来,我需要处理一个HTML表。我需要点击包含内部文字的href"调和"如果HTML表格的同一行中的单元格等于键入我的Excel工作簿的值。 HTML表包含很多行,我已经截断了下面的HTML代码,只包括2行用于说明(项目符号2和3)。使用row" bullet 2"例如,如果我的工作簿中的单元格等于" 2205021"我需要单击该行中的href。 (" 2205021"是HTML表格和Excel工作簿中唯一可识别的单元格值。)

请注意,我不想引用href的任何唯一可识别属性,例如" id"因为我一般都需要编写代码来应用于我的所有Excel模板,只依赖于上面提到的唯一可识别的单元格值(除非有这样做的方法仍能达到我想要的结果) )。

非常感谢任何帮助,

捐赠

到目前为止我的VBA代码:

Sub ieBusy(ie As Object)
    Do While ie.Busy Or ie.ReadyState < 4
    DoEvents
Loop
End Sub

Sub FillInternetForm()
Dim ie As Object
Set ie = CreateObject("InternetExplorer.Application")

ie.Navigate "https://Website I'm Navigating To"
ie.Visible = True

ieBusy ie

Set AllHyperLinks = ie.Document.getElementsByTagName("A")
For Each Hyper_link In AllHyperLinks
    If Hyper_link.innerText = "Reconciliations" Then
        Hyper_link.Click
        Exit For
    End If
Next

ieBusy ie

Dim mySelection As String, mySelObj As Object
Set mySelObj = ie.Document.getElementById("ctl00_MainContent_ucDashboardPreparer_ucDashboardSettings_ctl00_ddlRoles")

mySelection = ThisWorkbook.Sheets("1").Range("b2").Value    
Select Case mySelection
Case "Preparer", "Reviewer", "Approver"
Case Else
    MsgBox "Invalid Selection!"
    ie.Quit
    Exit Sub
End Select

mySelObj.Value = mySelection

ieBusy ie

Set mySelObj = ie.Document.getElementById("ctl00_MainContent_ucDashboardPreparer_ucDashboardSettings_ctl00_ddlEffectiveDate")

mySelection = ThisWorkbook.Sheets("1").Range("c8").Value    
Select Case mySelection
Case "12/31/2017" 'I'll ref a cell in my workbook here once code is built out
Case Else
    MsgBox "Invalid Selection!"
    ie.Quit
    Exit Sub
End Select

相关HTML代码:

1."<table class=""rgMasterTable"" 
id=""ctl00_MainContent_assignedAccountsGrid_ctl00"" style=""border-width: 
0px; width: 100%; table-layout: auto; empty-cells: show;"" border=""0"" 
cellspacing=""1"" cellpadding=""2"">"

  <tbody>
2. <tr class="rgRow" id="ctl00_MainContent_assignedAccountsGrid_ctl00__0" style="white-space: nowrap;" onclick="javascript:needToConfirm = false;">
    <td style="display: none;">29937</td><td style="display: none;">0</td><td style="display: none;">3199</td><td style="display: none;">&nbsp;</td><td style="display: none;">False</td><td style="display: none;">False</td><td>
                            <img title="Not Started" id="ctl00_MainContent_assignedAccountsGrid_ctl00_ctl04_StatusIcon" style="border-width: 0px;" alt="Not Started" src="../images/document_plain_new.gif">
                        </td><td>
                            <a tabindex="33" id="ctl00_MainContent_assignedAccountsGrid_ctl00_ctl04_lnkReconcile" onclick="javascript:return CheckInterval();" href="javascript:__doPostBack('ctl00$MainContent$assignedAccountsGrid$ctl00$ctl04$lnkReconcile','')">Reconcile</a>
                        </td><td>US</td><td>CORP</td><td>DOM</td><td>2205021</td><td>XX</td><td>XX</td><td>XX</td><td>0L</td><td>Group Insurance Withholding</td><td align="center">12/31/2017</td><td align="center" class="Delinquent">1/28/2018</td><td align="right">10,920.72</td><td align="right">0.00</td><td>

                        </td><td align="right">&nbsp;</td><td align="right">10,920.72</td><td>Grant Bangerter</td><td>Ryan Smith</td><td>
                            <span id="ctl00_MainContent_assignedAccountsGrid_ctl00_ctl04_lblResponsibilty">Primary</span>
                        </td><td style="display: none;">False</td>
3. </tr><tr class="rgAltRow" id="ctl00_MainContent_assignedAccountsGrid_ctl00__1" style="white-space: nowrap;" onclick="javascript:needToConfirm = false;">
    <td style="display: none;">28148</td><td style="display: none;">0</td><td style="display: none;">3199</td><td style="display: none;">&nbsp;</td><td style="display: none;">False</td><td style="display: none;">False</td><td>
                            <img title="Not Started" id="ctl00_MainContent_assignedAccountsGrid_ctl00_ctl06_StatusIcon" style="border-width: 0px;" alt="Not Started" src="../images/document_plain_new.gif">
                        </td><td>
                            <a tabindex="33" id="ctl00_MainContent_assignedAccountsGrid_ctl00_ctl06_lnkReconcile" onclick="javascript:return CheckInterval();" href="javascript:__doPostBack('ctl00$MainContent$assignedAccountsGrid$ctl00$ctl06$lnkReconcile','')">Reconcile</a>
                        </td><td>US</td><td>CORP</td><td>DOM</td><td>GRP.2203015</td><td>XX</td><td>XX</td><td>XX</td><td>0L</td><td>Accrued Dental Insurance Expense</td><td align="center">12/31/2017</td><td align="center" class="Delinquent">1/28/2018</td><td align="right">-12,751,041.02</td><td align="right">0.00</td><td>

                        </td><td align="right">&nbsp;</td><td align="right">-12,751,041.02</td><td>Grant Bangerter</td><td>Ryan Smith</td><td>
                            <span id="ctl00_MainContent_assignedAccountsGrid_ctl00_ctl06_lblResponsibilty">Primary</span>
                        </td><td style="display: none;">False</td>

如果需要,我可以从webform提供更多HTML代码。

3 个答案:

答案 0 :(得分:3)

您帖子中的HTML没有任何单元格等于2205021。虽然有一个等于GRP.2203015

要查找并点击“GRP.2203015”行中的Reconcile链接:

Dim elmID As Object, elmLink As Object

' get the cell in column 12 with text "GRP.2203015" '
Set elmID = FindElement(ie.document, "table tr td:nth-child(12)", text:="GRP.2203015")

' get the link in the parent row with text "Reconcile"
Set elmLink = FindElement(elmID.parentElement, "td a", text:="Reconcile")

' click the link '
elmLink.Click

对于FindElement函数:

Public Function FindElement(context As Object, selector As String, Optional text) As Object

    For Each FindElement In context.querySelectorAll(selector)
        If IsMissing(text) Or FindElement.innerText Like text Then Exit Function
    Next

    Err.Raise 9, , "Element not found for selector:" & selector & " text:" & text
End Function

请注意,您还可以搜索text="*2203015"以忽略前缀。

答案 1 :(得分:1)

这可能需要几次尝试,因为在我面前没有消息来源的情况下确保答案的有效性有点困难。

你能做的就是先抓住桌子。在以下示例中,您的表格将设置为变量t

接下来,您可以查看表格中的所有标记(tr - 表格行)以查找您的值(yourVal),并将其设置为变量r当你点击时。

Sub FillInternetForm()

    Dim ie As Object


    ' ... add'l code ...


    'Grab the table itself
    Dim t As Object, htmlTbls As Object
    Set htmlTbls = ie.document.getElementsByTagName("table")
    For Each t In htmlTbls
        If t.className = "rgMasterTable" Then Exit For
    Next t

    'Grab the cell containing your value
    Dim yourVal As Long, tCell As Object, tCells As Object
    yourVal = 2205021
    Dim r As Object, rColl As Object    'rColl is collection of rows in your table
    Set rColl = t.getElementsByTagName("tr")    ' tr = table row
    For Each r In rColl

        'TRY IT AS A STRING
        If r.outerHTML Like "*" & CStr(yourVal) & "*" Then
            MsgBox "FOUND IT (STRING)! TRYING TO CLICK NOW"  ' for debugging purposes
            r.Click
            Exit For
        End If

        'TRY IT AS A LONG
        Set tCells = r.getElementsByTagName("td")
        For Each tCell In tCells
            If tCell.innerText = yourVal Or _
                    tCell.innerText Like "*" & CStr(yourVal) & "*" Then
                MsgBox "FOUND IT (ALTERNATE). ATTEMPTING TO CLICK NOW"
                r.Click
                tCell.Click
                Exit For
            End If
        Next tCell

    Next a

End Sub

答案 2 :(得分:1)

我不完全确定我理解你的问题,但也许这样的事情会让你朝着正确的方向前进。

For each l in ie.document.getElementsByTagName("a") 
    If l.ClassName = "click_button" Then
        l.Click
    Exit For
Next

OR

Dim ieDoc As Object
Dim ieAnchors As Object
Dim Anchor As Object

Set ieDoc = ieApp.Document
Set ieAnchors = ieDoc.Anchors

For Each Anchor In ieAnchors
If Anchor.innerHTML = "Button" Then
Anchor.Click
Exit For
End If
Next Anchor

OR

for each ele in ie.document.getelementsbytagname("a")
   if instr(ele.innerhtml, "yes.gif") > 0 then ele.click: exit for
next

最后,下面的链接有一些好的想法,可以帮助你。

http://automatetheweb.net/vba-getelementsbytagname-method/