I am writing a Keyword using Robot Framework with FOR Loop just to iterate all the values present in the 1ST dropdown and get selected one by one. Loop is working but not able to iterate for selecting the indexes.
WebSite:
https://blazedemo.com/ (Choose your departure city:)
Test Case is:
1st will select the zero index with value "Paris", then will select the First index with value "Philadelphia" so on till the 6th indexes.
XPATH:
${Xpath_Departure_DropDown}= "xpath://*[starts-with(#class,'container')]//select[#name='fromPort']"
${Xpath_Departure_DropDown_Options}= "xpath://select[#name='fromPort']/option"
Robot Framework Keyword:
KW_14: Choose your departure city Drop Down:
#{All_Items_In_Drop_Down}= Get List Items ${Xpath_Departure_DropDown} values=True
${All_Items_In_Drop_Down_Label}= Get Selected List Label ${Xpath_Departure_DropDown}
${All_Items_In_Drop_Down_Value}= Get Selected List Value ${Xpath_Departure_DropDown}
List Selection Should Be ${Xpath_Departure_DropDown} ${All_Items_In_Drop_Down_Value}
${Length_Of_Lists_Items}= get length ${All_Items_In_Drop_Down}
FOR ${Index} IN RANGE ${Length_Of_Lists_Items}
LOG ${Index} html=true
Click Element ${Xpath_Departure_DropDown}
sleep 2 seconds
run keyword and continue on failure Select From List By Index ${Xpath_Departure_DropDown_Options}[${Index}]
sleep 2 seconds
${All_Items_In_Drop_Down_Label}= Get Selected List Label ${Xpath_Departure_DropDown}
${All_Items_In_Drop_Down_Value}= Get Selected List Value ${Xpath_Departure_DropDown}
List Selection Should Be ${Xpath_Departure_DropDown} ${All_Items_In_Drop_Down_Value}
END
I believe your usage of "Select From List By Index" is incorrect. Please check docs:
https://robotframework.org/SeleniumLibrary/SeleniumLibrary.html#Select%20From%20List%20By%20Index
It accepts locator and index. While you are passing
${Xpath_Departure_DropDown_Options}[${Index}]
which doesn't make sense at all since Xpath_Departure_DropDown_Options is locator itself. Try
Select From List By Index ${Xpath_Departure_DropDown_Options} ${Index}
Related
I am trying to separate a single number (or multiple) from a list of randomly generated list without any repeating values. This random list can be, for example, a range of 7 values from 1-45, then take one or more of those values from the list and use the same range but cannot be the same as the values inside the main list.
import random
rndList = []
rndList = random.sample(range(1,45), 7)
rndList.sort()
print("Some numbers...", rndList[0:6])
print("Separate number...", rndList[6])
This will output a random and sorted list, e.g. [5,12,28,35,39,41] and the last separate value from the list, e.g. [43]. The problem is that the last number will always be greater than the previous whereas I need it to be between 1-45 but never use repeated values from the list.
Is it possible to select the separate value randomly from the list instead of creating another list? Appreciate the help!
The easiest thing would simply be to make your selection and remove it from the list before you sort the list.
rndList = random.sample(range(1,45), 7)
separate = rndList.pop()
rndList.sort()
print("Some numbers...", rndList)
print("Separate number...", separate)
I am trying to achieve this result: assign a category to a document based on its title, or part of its title.
Title
Category
correspondence
Correspondence
Note Transmission Correspondence
Correspondence
Advisors Evaluation Report
Report
Country Notes
Correspondence
Annual Portfolio Report
Report
Appointment Letter
Correspondence
The categories are arranged into a table (docCategories) where each row starts with a unique category name, and is followed by a set of labels that match entirely or partially with the document title.
Category
Label
Label2
Label3
Label4
Correspondence
Letter
Memo
Note
Correspondence
Report
Dashboard
Report
The formula will take the document title and check if it matches any of the labels (with wild cards), so to return the unique category in the first position in the same row of the matched label.
Appointment Letter -> matches label:letter -> cat:Correspondence
I have made it working with this formula to be copied in the Category column:
=INDEX(docCategories;MIN(IF(docCategories=A2;ROW(docCategories)))-1;MIN(IF(docCategories=A2;1)))
And only if the title is exact matching of the entire label (e.g. Correspondence -> matches label:correspondence -> cat:Correspondence).
I am looking to have it working for matching on part of the title (e.g. Appointment Letter -> matches label:letter -> cat:Correspondence).
I have tried and failed to change the docCategories=<title> into something that can match the substring of the title, even applying the SPLITEXT(<title>) it still fails to give me the expected result.
Who can think of a creative solution for this?
The following solution works for any number of categories and for any number of labels on any category. It also identifies if no labels were found and also if more than one label was found from a different category. Since the question doesn't specify any specific excel version tag I assume Microsoft Office 365 function can be used.
On cell I2 put the following formula:
=LET(rng, A2:E3, texts, G2:G9, lkupValues, B2:E3, categories, INDEX(rng,,1),
BYROW(texts, LAMBDA(text,LET(
reduceResult, REDUCE("",categories, LAMBDA(acc,c, LET(
lkup, XLOOKUP(c,categories, lkupValues), searchLabels, FILTER(lkup, lkup<>0),
IF(SUM(N(ISNUMBER(SEARCH(searchLabels,text))))=0, acc,
IF(acc="", c, "MORE THAN ONE CATEGORY FOUND"))
))), IF(reduceResult<>"", reduceResult, "CATEGORY NOT FOUND")
)))
)
and here is the corresponding output:
The last two rows Title column were added to test the Non-Happy paths.
Explanation
We use LET function to define the names to be used and to avoid repeating the same calculation. If in your excel version you have DROP function available, then the name: lkupValues can be defined as follow: DROP(rng,,1).
The main idea is to iterate over texts values via BYROW and for each text we invoke SEARCH function for all categories. When the first input argument of SEARCH is an array, it returns an array of the same shape indicating the start of the index position of the labels found in text or #VALUE! if no labels were found.
Note: SEARCH is not case sensitive, if that is not the case, then replace it with FIND.
We use REDUCE function to iterate over all categories to find a match. For each category (c) we find the corresponding labels via XLOOKUP. Since not all categories have the same number of labels, for example Report has fewer labels than the Correspondence category. We need to adjust it to remove empty labels. The name searchLabels filters the result to only non-empty labels.
For checking if labels were not found we use the following condition:
SUM(N(ISNUMBER(SEARCH(searchLabels,text))))=0
ISNUMBER converts the SEARCH result to TRUE/FALSE values. N function converts the result to equivalent 0,1 values.
If the condition is TRUE, it returns the accumulator (acc initialized to an empty string). If the condition is FALSE, some labels were found, then it returns the category (c) if acc is empty, i.e. no previous categories were found. If acc is not empty any previous category was found, so it returns MORE THAN ONE CATEGORY FOUND.
Finally, if the result of REDUCE (reduceResult) is an empty string, it means the accumulator was not updated after initialization, so no labels were found for any category and it is indicated with the output: CATEGORY NOT FOUND.
Consider a list of strings in columnm A. Each member takes the form a_delimiter_b. The list also has quasi-duplicate members b_delimiter_a.
How can I select all the relevent entries without the "duplicates?" This is how can I query for entries in the columnn, and for each a_delimiter_b exclude b_delimiter_a?
Attempt:
I am trying to tag the duplicates in another column.
=IF(<condition>,"Keep","Delete")
I need a good condition that I cannot think up. If I use VLOOKUP both the "orginal" and the "duplicate" are taggef. For example if the element is A1="a_delim_b"
<condition> = ISERROR(VLOOKUP(b_delim_a, <list_range>, FALSE))
I can get "b_delim_a" by
CONCAT(TRIM(MID(SUBSTITUTE(A1,"_delim_",REPT(" ",LEN(A1))),(2-1)*LEN(A1)+1,LEN(A1))) & "_delim_" & TRIM(MID(SUBSTITUTE(A1,"_delim_",REPT(" ",LEN(A1))),(1-1)*LEN(A1)+1,LEN(A1))))
This does not work because if "b_delim_a" exists, all entries in the list are tagged for deletion.
How can I tag to keep only exacly one instance and tag to delete the other occurances?
Try the following in B1 and drag down:
=IF(COUNTIF(A$1:A1,MID(A1,FIND("; ",A1)+2,LEN(A1))&"; "&LEFT(A1,FIND("; ",A1)-1)),"Delete","Keep")
My problem
I have a list of values (List 1) that have the following pattern...
1234-COD-125
I have another list (List 2), which follow the pattern...
12345(1234-COD-100 - 1234-COD-150)
I need to search List 2 and return True if the value in List 1 is within range. So for example..
List 1 Result List 2
1234-COD-125 TRUE 12345(1234-COD-100 - 1234-COD-150)
1234-COD-126 TRUE 12345(4567-BAH-100 - 4567-BAH-150)
1234-COD-155 FALSE
4567-BAH-125 TRUE
4567-BAH-126 TRUE
4567-BAH-155 FALSE
Background
The first part (1234-COD) is the vendor ID and code. The last part (125) is the order ID. Different vendors can have the same order ID, so my lookup needs to account for the vendor.
What I've done so far
I have written a series of formulas which extract parts of the string. For instance, for
12345(1234-COD-100 - 1234-COD-150)
I have extracted the following in individual cells
100
150
COD
1234-COD-100
1234-COD-150
I know I can create a series to manually populate each order ID within range, then perform a lookup but I have hundreds of values in List 2 so this isn't an option.
Another option is to take the value in List 2 (12345(1234-COD-100 - 1234-COD-150) and check if every number in the range 100-150 is found in List 1.
I would like to be able to use a formula (or even VBA) to achieve this, but haven't been able to get any further. Any help would be greatly appreciated!
Parsing text is always problematic. The following will return what you want:
=SUMPRODUCT((A2>=TRIM(LEFT(MID($C$2:$C$3,FIND("(",$C$2:$C$3)+1,LEN($C$2:$C$3)),FIND(" - ",MID($C$2:$C$3,FIND("(",$C$2:$C$3)+1,LEN($C$2:$C$3)))-1)))*(A2<=SUBSTITUTE(TRIM(MID($C$2:$C$3,FIND(" - ",$C$2:$C$3)+3,LEN($C$2:$C$3))),")","")))>0
But it depends exclusively on the pattern you are showing. Specifically that the range is always in () and the two ranges are separated by -
I am trying to write an Excel VBA script to navigate to a website and select from a drop-down list using the text in the list item, NOT the value of the index. By examining the HTML code, I can see that the values in the drop-down list appear to be integers with no recognizable pattern and do not appear to correlate to the text shown for the entry in the drop-down list.
<option value="246">new2</option>
<option value="245">new</option>
<option value="196">test</option>
I can successfully use the following command:
ieDoc.getElementById("viewMaintainFixedCombustible_fixedCombustible_fireZoneId").Value = 246
To select the item "new2" from the drop-down list, by sending the value 246. Or, I could send 245 to select "new". However, the elements in the list are always changing, so selecting by value (246, 245, etc.) is impractical. Thus, I am searching for a way to select an entry from the drop-down list (e.g. "new2") by sending the text name of the entry (e.g. "new2") in VBA.
Does anyone have a method for how to do this?
Try below sample code to set dropdown list by text.
Set drp =ieDoc.getElementById("<id of your dropdown>")
For x = 0 To drp.Options.Length - 1
If drp.Options(x).Text = "new2" Then
drp.selectedIndex = x
Exit For
End If
Next