Home » excel » Selecting a HTML button in Excel VBA that does not have an id

Selecting a HTML button in Excel VBA that does not have an id

Posted by: admin May 14, 2020 Leave a comment

Questions:

Been working on this issue for a day now. I have a webform that you have 1 set of standard data, and then you enter line items for a purchase requisition; I am trying to enter all data in Excel and use VBA to transfer it to the site. I am getting stuck at how to “update part” (the text on the button that I need to click to add another line item on the webpage). I have also tried the send key method to Shift Tab into the correct location (just normal shifting runs into an error with one of the fields). I am fine with any solution working, this is my first attempt at linking Excel to HTML so it’s been fun.

From what I can find the button does not have an id so I have not been successful in calling it.

Here is my code (with the web url deleted):

Sub Login_2_Website()

Dim oHTML_Element As IHTMLElement
Dim oHTML_Element1 As IHTMLElement
Dim sURL As String
Dim aURL As String
Dim nodeList As Object


On Error GoTo Err_Clear
sURL = URL Can't be Shared
oBrowser.Silent = True
oBrowser.timeout = 60
oBrowser.Navigate sURL
oBrowser.Visible = True

Do
' Wait till the Browser is loaded
Loop Until oBrowser.ReadyState = READYSTATE_COMPLETE

Set HTMLDoc = oBrowser.Document
Set nodeList = HTMLDoc.querySelectorAll("a[onlick*='UpdatePartRow']")

HTMLDoc.all.UserName.Value = ThisWorkbook.Sheets("sheet1").Range("I1")
HTMLDoc.all.Password.Value = ThisWorkbook.Sheets("sheet1").Range("I2")

For Each oHTML_Element In HTMLDoc.getElementsByTagName("input")
If oHTML_Element.Type = "submit" Then oHTML_Element.Click: Exit For


    HTMLDoc.all.reason.Value = ThisWorkbook.Sheets("sheet1").Range("B1") ' selects the reason for the requisition

    HTMLDoc.all.Comments.Value = ThisWorkbook.Sheets("sheet1").Range("B2") ' selects the comments to purchasing

    HTMLDoc.forms("_PurchaseRequisition").getElementsByTagName("select")("RequiredMonth").Value = ThisWorkbook.Sheets("sheet1").Range("B3")
    HTMLDoc.forms("_PurchaseRequisition").FireEvent ("onchange")

    HTMLDoc.forms("_PurchaseRequisition").getElementsByTagName("select")("RequiredDay").Value = ThisWorkbook.Sheets("sheet1").Range("B4")
    HTMLDoc.forms("_PurchaseRequisition").FireEvent ("onchange")

    HTMLDoc.forms("_PurchaseRequisition").getElementsByTagName("select")("RequiredYear").Value = ThisWorkbook.Sheets("sheet1").Range("B5")
    HTMLDoc.forms("_PurchaseRequisition").FireEvent ("onchange")

    HTMLDoc.forms("_PurchaseRequisition").getElementsByTagName("select")("CommodityMain").Value = ThisWorkbook.Sheets("sheet1").Range("B9")
    HTMLDoc.forms("_PurchaseRequisition").FireEvent ("onchange") 'Selects the commodity group

    HTMLDoc.all.Quantity.Value = ThisWorkbook.Sheets("sheet1").Range("B11")
    HTMLDoc.all.Description.Value = ThisWorkbook.Sheets("sheet1").Range("B12")
    HTMLDoc.all.ChargedDepartment.Value = ThisWorkbook.Sheets("sheet1").Range("B13")
    HTMLDoc.all.SubJobNumber.Value = ThisWorkbook.Sheets("sheet1").Range("B14")
    HTMLDoc.all.AccountNumber.Value = ThisWorkbook.Sheets("sheet1").Range("B15")
    HTMLDoc.all.UnitPrice.Value = ThisWorkbook.Sheets("sheet1").Range("B16")
    HTMLDoc.all.CommodityMainSub.Value = ThisWorkbook.Sheets("sheet1").Range("B17")


    Set nodeList = HTMLDoc.querySelectorAll("a[onlick*='UpdatePartRow']")

    nodeList.Item(0).Click
    nodeList.Item(0).FireEvent "onclick"



Next


' oBrowser.Refresh ' Refresh If Needed
Err_Clear:
If Err <> 0 Then
Err.Clear
Resume Next
End If
End Sub

For the login portion I modified code from: http://vbadud.blogspot.com/2009/08/how-to-login-to-website-using-vba.html#ZiqYAtAQMHzl7x1k.99

That works perfectly, so does entering the fields.

The segment of HTML that is associated with this button is:

<a onclick="UpdatePartRow();
chkKeepSubmitPR();

return false;" href=""></a>

<a onclick="var doc = window.document.forms[0];
    UpdatePartRow();
    chkKeepSubmitPR();
if (doc.OrgMatrixYes.value == &quot;Y&quot;) {
    VerifyDeptOrgMatrix();
}


return false;" href=""><img src="/Web/purchreq.nsf/UpdatePart.gif?OpenImageResource" width="72" height="25" border="0"></a>  

I am taking this on because this system is a pain. I could just have multiple macros and have the user hit the button between each line item, but I want to try to offer a full solution. I am a mechanical engineer by trade and my coding experience is limited to what I have picked up on making tools to ease my job. Any help or suggestions would be super helpful. If there is more info needed, please let me know and I can try to help anyway I can. Thank you!

Update: I have tried (See Code) to make the changes that have been suggested. I am still a fairly complete newbie when it comes to coding, so please bear with me and thank you for trying to teach me!

How to&Answers:

You have two a tag elements there with an onclick

You can get both with attribute = value CSS selector using "*" contains operator to search for a substring in the attribute value

a[onclick*='UpdatePartRow']

You can grab both with querySelectorAll method of HTMLDocument object

Dim nodeList As Object
Set nodeList = HTMLDoc.querySelectorAll("a[onclick*='UpdatePartRow']")

The two matches, for your sample, are as follows:

index 0

<a onclick="UpdatePartRow(); chkKeepSubmitPR(); return false;" href="">

index 1

<a onclick="var doc = window.document.forms[0]; UpdatePartRow(); chkKeepSubmitPR(); if (doc.OrgMatrixYes.value == &quot;Y&quot;) { VerifyDeptOrgMatrix(); } return false;" href="">

enter image description here

You can access the nodeList by index e.g.

nodeList.item(0).Click
nodeList.item(0).FireEvent "onclick"