问题
Recently, I posted the question vbscript capture text in the HTML select option tag. This helped me tremendously on an Internet Explorer platform. However, I have a new project with a bit more complex of a web site. The web site has multiple nested tables that are formatted to hold form elements. My team and I have figured out how to get and set data within most of the elements except the drop down box (select tag). We are able to get the text from the drop down, but we can't change the value. Instead, all the options are wiped clear and the whole drop down is blank.
Here's a revised version of the code for the web site as there is much more code involved, but only the pertinent code is shown:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>...</head>
<body>
<form id="form1" action="AssignOFS.aspx" method="post">
<div class="aspNetHidden">...</div>
<div class="aspNetHidden">...</div>
<table width="100%" align="center" cellspacing="0">
<tbody>
<tr>
<td>
<table width="100%" align="center" cellspacing="0">...</table>
</td>
</tr>
<tr>
<td>
<table width="100%" align="center" cellspacing="0">
<tbody>
<tr>...</tr>
<tr>...</tr>
<tr class="tr_data">...</tr>
<tr>
<td align="center">
<div id="pnlBtn1">...</div>
<div id="pnlView">
<table width="100%" align="center" cellspacing="0">
<tbody>
<tr>...</tr>
<tr>...</tr>
<tr class="tr_data">
<td align="center">...</td>
<td valign="top">...</td>
<td valign="top">...</td>
<td valign="top">...</td>
<td nowrap="" valign="top">...</td>
<td align="left">...</td>
<td align="center">...</td>
<td align="center">
<select name="user" class="txt_input1" id="user" onchange="javascript:addUser(227);">
<option value="">--Select User--</option>
<option value="0123">Amy Jones (000456321)</option>
<option value="0432">Brian Wyatt (000745632)</option>
<option value="0345">Carl Lister (000874563)</option>
<option value="0654">Daniel Michaels (000987456)</option>
<option value="0567">Elizabeth Sweeny (001456321)</option>
<option value="0876">Fran Tarris (001745632)</option>
<option value="0789">Gail McMurphy (001874563)</option>
<option value="1098">Hannah Barisce (001987456)</option>
</select>
</td>
</tr>
</tbody>
</table
</div>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</form>
</body>
</html>
To be able to get the text from the drop down, we used the class name txt_input1 after locating the node within the table that holds the drop down. This code will give us the entire list within the drop down:
objIE.Document.getElementsByTagName("table")(0).getElementsByTagName("td").Item(64).GetElementsByClassName("txt_input1")(0).innerText
I've tried changing the value of the select drop down from "--Select User--" to one of the names in the list with the following code:
objIE.Document.getElementsByTagName("table")(0).getElementsByTagName("td").Item(64).GetElementsByClassName("txt_input1")(0).innerText = "Carl Lister"
This resulted in the blank drop down. If I changed the ending to .Value, it only removes "--Select User--" from being shown. It still doesn't change the value to "Carl Lister". Is there something we're missing when it comes to selecting an option in a select drop down within nested tables?
回答1:
For a select element, the best way to change the displayed value is to "select" one of the option elements that's part of the menu. To do that, you could change your code like this:
objIE.Document.getElementsByTagName("table")(0).getElementsByTagName("td").Item(64).GetElementsByClassName("txt_input1")(0).childNodes(x).selected = true
The code above would select the child node (the option element) at index x and programmatically select it, so that value would be displayed in the select element. The index for the options starts at 0, so for x = 0 that would select the first option (in this case, Amy Jones).
You could also simplify the above code to just read:
objIE.Document.getElementsByClassName("txt_input1")(0).childNodes(x).selected = true
Or you could even do it by id since you have an ID assigned to the menu:
objIE.Document.getElementById("user").childNodes(x).selected = true
If you wanted to select an employee name from the drop down list, you could loop through the existing options and find the correct one like this (code adapted from the VBA code in this question):
Dim el As IXMLDOMNode
Dim childNode As IXMLDOMNode
el = objIE.Document.getElementById("user")
For Each childNode in el.ChildNodes
If InStr(childNode.innerText, emplName) Then
childNode.selected = true
Exit For
End If
Next childNode
In this example, emplName is whichever employee you want to select.
(My VBA is a little rusty, so I apologize if any of the syntax is off.)
回答2:
Thanks, @freginold, for all your help. My team and I came up with a solution that expands upon our already developed solutions.
tdNode = 64
i = 0
For Each objOption In objIE.Document.GetElementsByTagName("table")(0).GetElementsByTagName("td")(tdNode).GetElementsByClassName("txt_input1")(0).Options
Q(i) = objOption.Text & "-" & objOption.Value
QNm = QNm & "|" & Q(i)
i = i + 1
If objOption.Selected Then
strWQ = objOption.Text
End If
If i > 53 Then
MsgBox "stuck"
SetEverythingToNothing
End If
Next
QNm = QNm & "|=" & strWQ
a = 1
MyArray = Split(QNm, "|")
For a = LBound(MyArray) To UBound(MyArray)
If InStr(MyArray(a), UserName) Then
strWQ = MyArray(a)
End If
Next
SelQ = Mid(strWQ, InStr(strWQ, "-") + 1, Len(strWQ) - InStr(strWQ, "-"))
For Each objOption In objIE.Document.GetElementsByTagName("table")(0).GetElementsByTagName("td")(tdNode).GetElementsByClassName("txt_input1")(0).Options
If objOption.Value = SelQ Then
objOption.Selected = True
objIE.Document.GetElementsByTagName("table")(0).GetElementsByTagName("td")(tdNode).GetElementsByClassName("txt_input1")(0).OnChange
Else
objOption.Selected = False
End If
Next
来源:https://stackoverflow.com/questions/45963540/excel-vba-change-option-in-the-html-select-tag