I am having an issue with one part of my automation job, and that is selecting ALL the options in a combobox, on a webpage, using VBA and IE.
This code selects ONE item in the combo box
Set frm = HTMLDoc.getElementsByName("UFG.USER_TYPES")(0)
frm.Value = "AUT"
However, when I try to select multiple items, it just selects the last one, not all of them.
Here is the code from the web page
<p id="DispFormCollapsible.Rc10"class="formrow" >
<span id="DispFormCollapsible.Rc10.C1" class="querytextleft">
<label for="UFG.USER_TYPES" id="LabelForContro123"class = "simpletext" >
Accessible Types:<span class="redstar">*</span></label></span>
<span id="DispFormCollapsible.Rc10.C2" class="querytextright">
<span class="labelColumn_combo">
<span class="labelColumn_combi_brdr">
<select name= "UFG.USER_TYPES" multiple= "true" class = "dropdownexpandalbe"
id="UFG.USER_TYPES" title = "Accessible Financial Transaction Types">
<option value="AUT" title="ACTIVE USER TYPE1" >TYPE1</option>
<option value="SET" title="Selective User Type" >TYPE2</option>
<option value="TST" title="Test User Type" >TEST3</option>
</select></span></span>
<input type ="hidden" name= "UFG.USER_TYPES" value="NULL" >
</span></p>
Here is my VBA line to select an item
Set frm = HTMLDoc.getElementsByName("UFG.USER_TYPES")(0)
frm.Value = "AUT"
What I need it to do, is select all the "option values" in the combobox. I think it needs to be an array maybe, or some other way. I've tried searching, but I'm getting nowhere. Any help appreciated. Thx
Tried the following, but get an error 91 Block not set. I've also tried using the Values "AUT" in the children, and when doing that I don't get an error, but it doesn not select anything.
With HTMLDoc.getElementsByName("Select")(0)
.Children(1).Selected = True
.Children(2).Selected = True
.Children(3).Selected = True
End With
Also tried the following, this doesn't give an error, but only selects the first option in the list.
With HTMLDoc.getElementsByName("UFG.USER_TYPES")(0)
.Children(AUT).Selected = True
.Children(SET).Selected = True
.Children(TST).Selected = True
End With
This is strange, when I use this code, it selects the first two in the list, but not the third.
With HTMLDoc.getElementsByName("UFG.USER_TYPES")(0)
.Children(all).Selected = True
End With
With HTMLDoc.getElementsByName("UFG.USER_TYPES")(0)
.Children(0).Selected = True
.Children(1).Selected = True
.Children(2).Selected = True
End With
The above code fixed it... whoopie!
Related
I am using VBA in excel to submit a MS form. It could fill the values to text inputs but after submit, this question is still blank. Any thoughts?
Dim emailDomain As Variant
Dim URL As String
Set IE = GetObject("new:{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}")
IE.Visible = True
URL = "https://forms.office.com/Pages/ResponsePage.aspx?id=Aq5v9jZdW0m_4Him_5-ObrQJR7r8UGdPhwKFE494ioxUOEg4M1Q5STRGSzk5Q1VPMTJPRUNLMk5IMi4u"
IE.navigate (URL)
While IE.Busy
DoEvents
Wend
IE.document.getElementsByClassName("office-form-question-textbox office-form-textfield-input form-control office-form-theme-focus-border border-no-radius")(0).Value = "currentUserEmailAddress"
delay 5
IE.document.getElementsByClassName("button-content")(0).Click
IE.Quit
Set IE = Nothing
End Sub
Before submit, the value has been filled correctly
This <div class="button-content">Absenden</div> is not a button but the actual button starts with <button so this is what you need to look for and click on.
<button class="office-form-theme-primary-background office-form-theme-button office-form-bottom-button button-control light-background-button __submit-button__" title="Absenden" role="button">
<div class="button-content">Absenden</div>
</button>
In order to click the send button you can use something like
IE.document.getElementsByClassName("office-form-theme-primary-background office-form-theme-button office-form-bottom-button button-control light-background-button __submit-button__")(0).Click
after you have set the value of the textbox with
IE.document.getElementsByClassName("office-form-question-textbox office-form-textfield-input form-control office-form-theme-focus-border border-no-radius")(0).Value = "currentUserEmailAddress"
I met this kind of issue before. You can also refer to this thread.
The root cause of the issue is .Value can't set the value effectively. In this situation, you can simulate user input using SendKeys to set value to the input box.
Sample code:
IE.document.getElementsByClassName("office-form-question-textbox office-form-textfield-input form-control office-form-theme-focus-border border-no-radius")(0).Focus
SendKeys ("currentUserEmailAddress")
I've checked already multiple similar questions and answers, but unfortunately didn't found any solution for my particular case.
Issue description
I'm trying to fill out and submit the form on this site. The form was build as follow:
<form id="hikuZR" action="/historische-kurse/BMW" method="post">
...
<div class="hidden"><input type="submit" value="senden"></div>
<span class="button bgBlue btn-xs-block pull-sm-right" onclick="submitForm($(this));">Historische Kurse anzeigen</span>
</div>
<input type="hidden" name="pkBHTs" value="1550956687">
</form>
This is how I'm performing it:
Filling out the form
start_day_1 = self.driver.find_element_by_xpath("//select[#name='inTag1']/option[#value=22]")
start_day_1.click()
start_day_2 = self.driver.find_element_by_xpath("//select[#name='inTag2']/option[#value=22]")
start_day_2.click()
start_month_1 = self.driver.find_element_by_xpath("//select[#name='inMonat1']/option[#value=08]")
start_month_1.click()
start_month_2 = self.driver.find_element_by_xpath("//select[#name='inMonat2']/option[#value=08]")
start_month_2.click()
start_year_1 = self.driver.find_element_by_xpath("//select[#name='inJahr1']/option[#value=2018]")
start_year_1.click()
start_year_2 = self.driver.find_element_by_xpath("//select[#name='inJahr2']/option[#value=2018]")
start_year_2.click()
try:
market = self.driver.find_element_by_xpath("//select[#name='strBoerse']/option[#value='%s']" % 'XETRA')
market.click()
sleep(randint(7, 10))
except NoSuchElementException:
print("Element by xpath does not exist!")
This part works fine, and I'm able to put all values to the form:
Clicking on the Button:
I'm trying to locate the button by XPATH as well:
hist_button = self.driver.find_element_by_xpath("//span[contains(.,'Historische Kurse anzeigen')]")
and to click on this button, which seems to be found:
hist_button.click()
It doesn't work for me. I've tried also performing the button by executing the script as proposed in some answers on SO:
self.driver.execute_script("arguments[0].click();", hist_button)
Also this solution doesn't work in my case. The page has been refreshed, but didn't show me the result for the historical dates:
This is what I see after manual clicking on the button:
Could you please help me to find out, what I'm doing wrong? Thank you.
Update 25.02.2018
As suggested in the comment, I'm selecting the values from DropDown lists with the Select class as follow:
start_day_1 = Select(self.driver.find_element_by_xpath("//select[#name='inTag1']"))
start_day_1.select_by_value("22")
start_day_2 = Select(self.driver.find_element_by_xpath("//select[#name='inTag2']"))
start_day_2.select_by_value("22")
start_month_1 = Select(self.driver.find_element_by_xpath("//select[#name='inMonat1']"))
start_month_1.select_by_value("8")
start_month_2 = Select(self.driver.find_element_by_xpath("//select[#name='inMonat2']"))
start_month_2.select_by_value("8")
start_year_1 = Select(self.driver.find_element_by_xpath("//select[#name='inJahr1']"))
start_year_1.select_by_value("2018")
start_year_2 = Select(self.driver.find_element_by_xpath("//select[#name='inJahr2']"))
start_year_2.select_by_value("2018")
market = Select(self.driver.find_element_by_xpath("//select[#name='strBoerse']"))
market.select_by_value('XETRA')
And I'm seeing the selected values in the form (with the "first" version posted in the description, I saw the values in the form as well). After that I'm clicking the button again without any effects. The page was refreshed, but I don't see the results:
hist_button = self.driver.find_element_by_xpath("//span[contains(.,'Historische Kurse anzeigen')]")
hist_button.click()
html_historical = self.driver.page_source
or
hist_button = self.driver.find_element_by_xpath("//span[contains(.,'Historische Kurse anzeigen')]")
self.driver.execute_script("arguments[0].click();", hist_button)
html_historical = self.driver.page_source
When I click on the button manually, the result for selected data will show correctly. It looks like the performing of the button is not working.
I am trying to loop through the options or items of a drop down menu, but I don't know the number of items as it will be changeable every time.
Here's the html part of the sList3
<select name="ctl00$ContentPlaceHolder1$Dschool" onchange="javascript:setTimeout('__doPostBack(\'ctl00$ContentPlaceHolder1$Dschool\',\'\')', 0)" id="ContentPlaceHolder1_Dschool" style="font-size:12pt;font-weight:bold;width:500px;">
<option selected="selected" value="0"> Select From Menu </option>
<option value="311223">first option</option>
<option value="311625">some option</option>
</select>
Here's my code that I have started
For i = 1 To 4
Set sList1 = .FindElementById("ContentPlaceHolder1_Dedara").AsSelect
sList1.SelectByIndex i
.Wait 2000
Set sList2 = .FindElementById("ContentPlaceHolder1_Drel").AsSelect
sList2.SelectByIndex 1
.Wait 2000
Set sList3 = .FindElementById("ContentPlaceHolder1_Dschool").AsSelect
'How can I loop through the options (unknown in length)
Next i
I would like to loop each option and debug.print the value of the option.
SOLUTION
With the help of JeffC this is the final solution
For j = 1 To sList3.Options.Count
Debug.Print sList3.Options(j).Text
Next j
I think you can use for each loop
WebElement selectElement = driver.findElement(By.xpath("//select[#id='ContentPlaceHolder1_Dschool']"));
Select select = new Select(selectElement);
List<WebElement> options = select.getOptions();
for (WebElement we : options)
{
System.out.println("Element="+we.getText());
}
You can use CSS selector to get collection of the options under the parent id
Dim elements As Object, element As Object
Set elements = driver.FindElementsByCss("#ContentPlaceHolder1_Dschool option")
Then loop
For Each element In elements:
Debug.Print element.text
Next
CSS:
If the id is dynamic switch css to
[id^=ContentPlaceHolder1] option
I had a procedure that scraped information from a website in IE9 however after updating to IE11 the procedure breaks when trying to enter a piece of data into
an input box on the webpage. The code recognizes the field and it is listed as on object when I debug but when I try to enter a value into the box using CUSIP.value it does not enter anything on the webpage. I think it has something to do with the source being updated after the browser was updated. I could have sworn that the identifier for "txtCusipNo" in the HTML was listed as an ID instead of a Name. Any help is appreciated. Thanks.
HTML from website
<td class="tbl1">
<INPUT TYPE="TEXT" NAME="txtCusipNo" VALUE="" CLASS="input" SIZE="11" MAXLENGTH="9">
<img src="/RDPANN/pbs/images/lookup.gif" border="0" alt="Open Security Finder" align="absmiddle"> <IMG NAME="txtCusipIMG"SRC="/RDPANN/pbs/images/req.gif" ALIGN="ABSMIDDLE">
</td>
VBA code
Private Sub EnterCUSIP()
Retry:
Set CUSIP = Doc.getElementById("txtCusipNo")
Err.Clear
valA = ActiveSheet.Cells(row, 1)
On Error Resume Next
CUSIP.Value = ActiveSheet.Cells(row, 1) 'insert CUSIP
If Err.Number = 91 Then GoTo Retry
Set CurrentWindow = IE.document.parentWindow
Call CurrentWindow.execScript("javascript:processForm(document.forms.frmSearchEntry)") 'Search (hit enter)
If Err.Number = -2147352319 Then Exit Sub
On Error GoTo 0
Do While (IE.Busy Or IE.READYSTATE <> READYSTATE.READYSTATE_COMPLETE):DoEvents: Loop
End Sub
If you suspect that the HTML source has been changed and may make unannounced changes in the future, I would recommend switching to the ie.Document.All.Item property.
Doc.all.Item("txtCusipNo").Value = 123
The .Item identifier can be either an ID or a Name, there is no distinction between the two. However, I would be concerned that the identifying factor (e.g. txtCusipNo) may not be unique on that page. Yes, it is supposed to be but a growing number of HTML developers are using code like divs(0).getElementById("txtCusipNo") and divs(1).getElementById("txtCusipNo").
I am writing an Excel macro to fill out a form on a website. I have written the code that populate the text boxes easily enough, and found code to chose radio boxes, but I am having problems with choosing info from dropdown menus.
Example 'Gender':
The combo box has three options:
Select / Male / Female
I've tried a few variations on this:
doc.getElementsByName("xs_r_gender").Item(0).Value="Male"
...but with no luck.
This is the web source code:
<td> <select name="xs_r_gender" id="xs_r_gender">
<option value="" selected>Select</option>
<option value="male">Male</option>
<option value="female">Female</option> </select></td>
Thanks.
doc.getElementById("xs_r_gender").selectedindex=1
seems to do the trick. (Where 1 represents male)
Though it means I will need to do alot of lookups to determine what the value is for the items in my dropdown. (Easy enough for Sex, where there are only two options, but I have some comboboxes with up to 50 options). If anyone knows of a faster solution, that'd be great. In the meantime, Ill start doing up some tables!!!
thanks.
Try below code assuming doc = ie.document
doc.getElementById("xs_r_gender").value = "Male"
Use this in your code to call the function below.
xOffset = SetSelect(IE.Document.all.Item("shipToStateValue"), "Texas")
doc.getElementById("shipToStateValue").selectedindex = xOffset
Then use this for your function
Function SetSelect(xComboName, xComboValue) As Integer
'Finds an option in a combobox and selects it.
Dim x As Integer
For x = 0 To xComboName.options.Length - 1
If xComboName.options(x).Text = xComboValue Then
xComboName.selectedindex = x
Exit For
End If
Next x
SetSelect = x
End Function
Thanks Stack, works for me! My solution to operate an IE HTML combobox drop down turned out to be two parts.
Part 1 was to click the pull down, here's code:
Dim eUOM1 As MSHTML.HTMLHtmlElement
Set eUOM1 = ie.document.getElementsByTagName("input")(27).NextSibling
eUOM1.Focus
eUOM1.Click
Part 2 was to choose and click the value, like this (*actual element name changed):
Dim eUOM2 As MSHTML.HTMLHtmlElement
Set eUOM2 = ie.document.getElementsByName("[*PutNameHere]")(0)
eUOM2.Value = "EA"
eUOM2.Click
Here are references:refs
You can try the querySelector method of document to apply a CSS selector of option tag with attribute value = 'male':
doc.querySelector("option[value='male']").Click
or
doc.querySelector("option[value='male']").Selected = True
Function SetSelect(s, val) As Boolean
'Selects an item (val) from a combobox (s)
'Usage:
'If Not SetSelect(IE.Document.all.Item("tspan"), "Custom") Then
'something went wrong
'Else
'continue...
'End If
Dim x As Integer
Dim r As Boolean
r = False
For x = 0 To s.Options.Length - 1
If s.Options(x).Text = val Then
s.selectedIndex = x
r = True
Exit For
End If
Next x
SetSelect = r
End Function
Try this code :
doc.getElementById("xs_r_gender").value = "Male"
doc.getElementById("xs_r_gender").FireEvent("onchange")
You can do something like this:
doc.getElementsByName("xs_r_gender").Item(1).Selected=True
or
doc.getElementById("xs_r_gender").selectedindex = 1
Where 1 is the male option (in both cases).
If the dropbox needs to fire some event in order to aknowledge your choice, it is likely that it will be the "onchange" event. You can fire it like so:
doc.getElementById("xs_r_gender").FireEvent("onchange")
If you ever want to be able to select an option based on the option's text you can use the function given by Lansman (here) .
Based on the same answer, if you want to call the option by it's value property (instead of the text, you can just change the line If xComboName.Options(x).Text = xComboValue Then to If xComboName.Options(x).value = xComboValue Then).
This should cover all bases.
Copy from Here till last line:
Sub Filldata()
Set objShell = CreateObject("Shell.Application")
IE_count = objShell.Windows.Count
For X = 0 To (IE_count - 1)
On Error Resume Next ' sometimes more web pages are counted than are open
my_url = objShell.Windows(X).document.Location
my_title = objShell.Windows(X).document.Title
If my_title Like "***Write your page name***" Then
Set IE = objShell.Windows(X)
Exit For
Else
End If
Next
With IE.document.forms("***write your form name***")
' Assuming you r picking values from MS Excel Sheet1 cell A2
i=sheet1.range("A2").value
.all("xs_r_gender").Item(i).Selected = True
End with
End sub