Question
Shuurgan
CN
Last activity: 21 Oct 2024 20:02 EDT
I'm having some problems with my design, but I'm not sure what the problem is, please advise
As shown in the figure, I want to put an element of a web page and all the elements like it into a list control. This element is a text column and is not clickable. With this design I have it always gives the error “unable to find contextid for key”, I would like to know what is wrong? It's worth mentioning that clicking on the columns containing the text belongs to the upper level of the page, i.e., clicking on a key brings up a layer of a popup-like page, and the text columns are on each line of this popup. I'm targeting the overall html of the popup, and the html of each row, and I want to get the text columns for each row and place them in a List component. I am asking for help.
BAO
-
Reply
-
Share this page Facebook Twitter LinkedIn Email Copying... Copied!
Accepted Solution
Updated: 21 Oct 2024 20:02 EDT
Pegasystems Inc.
US
Here are screenshots of the relevant portions of my automation for you to try to recreate.
Pegasystems Inc.
US
- Do you have UseKeys enabled for "ctlSiteName..." (the one with the GetClones method shown in your screenshot) or its parent? GetClones should be called on whatever control has UseKeys enabled. If this is a row, generally the row itself has UseKeys enabled and the controls beneath it would not. In this example, there'd be only one site name for each row, so rows would have UseKeys enabled and not the Site Name control.
- I would use a LookupTable to add things to a list in an automation. It is designed to be easy to use in an automation whereas the ArrayList is a .Net object. The lookup table is pretty easy to use. You add one to your global container (it must be global in scope) and then configure whatever columns you want. One of the columns will need to be a unique value (the key field). If you only have one column and it is not unique, you can add a column and set it to auto-increment to key each row for you.
- You may need to have a brief pause after waiting for the table itself to be created before you start iterating the rows. Matching for cloned objects does not happen before the parent control is matched. This is because there is an unknown number of clones available to match, so there really is no way to indicate that everything has been matched. If speed is important, you can use a loop and check the number of clones in a loop and stop once that number has stopped changing, but that is a little more advanced and a pause of about 500 milliseconds is probably OK and a good place to start.
Shuurgan
CN
@ThomasSasnett Thank you for your answer. There's something I don't quite understand about how 2 and 3 are implemented though, can you demonstrate it with a simple automation?
BAO
Shuurgan
CN
As shown in the picture, I actually want to get the sitename of the external folder and then get the sitename of each line from the page, and then choose to click the “Monthly Report” (the link wrapped in a red square in the picture) in the corresponding sitename line by recognizing the sitename in the external folder. I have now set this button to recognize all buttons of the same type in that column, and what I want to know is, can I be using that button in the loop again? Or is there any way to make it click on the “Monthly Report” of the corresponding row when it recognizes sitename1, click on the “Monthly Report” of the corresponding row when it recognizes sitename2, and so on. Can you please tell me? Thank you.
BAO
Pegasystems Inc.
US
@BAOX17175074 The way you would do this is use the GetClones method of the row. Pass this to a ListLoop. On each iteration of the list, the context for the current clone will be preserved, so any of the items inside of the row will have the appropriate key. You can then read the text of whatever field you need to determine if you are on the correct row and the click whatever control you need right afterwards before breaking your loop.
Remember that UseKeys should be enabled for the row of data, since it is the element that is repeating. Beneath it are elements present for every row. Each row will be given a unique key to be able to refer to it specifically. Make sure that whatever match rule(s) you apply to the row apply to every row you wish to match. You should see all of the rows you wish to match shown in the Targets window. You will also want to ensure when you interrogate items beneath the row, that their Match rules also apply to their counterparts on other rows. You can check them by selecting a different row from the targets window and making that new row the prototype (right-click the target row and select "Make prototype"). This will re-draw Object Explorer now attached to the new row and allow you to see if its children match.
Shuurgan
CN
@ThomasSasnett As you can see in the picture, this is the corresponding Monthly Report button I mentioned above, I can now get it to match all the Monthly Reports in a column, but in another automation loop I can only click on the first Monthly Report, and I can't correctly go through the loop index and click on the corresponding Monthly Report. Do I need to add this button to the above mentioned automation process to work with the getClone method of ctlSiteNameItem to save it to an arrayList? BAO
Pegasystems Inc.
US
@BAOX17175074 Look at my prior response. I believe you may just be confused on what you are looking at.
@BAOX17175074 Look at my prior response. I believe you may just be confused on what you are looking at.
- Interrogate a row and ensure that its match rules apply to every row since UseKeys will be enabled for this control.
- Interrogate the elements you need within the row. Ensure that their match rules would apply to Row 2, 3, 4, etc.
- In your automation, use the GetClones method of the row to iterate over the matched list of Rows.
- Any of the children's properties, methods, or events you refer to within the loop, should have the correct key associated with them because the ListLoop is keeping track of which row you are "on".
- Once you have identified that you are on the correct row by checking the "SiteName" field, you can then click the button for the report and break your loop.
- If you need to return to the page again and continue iteration to click more than one row in the table, it will get more complicated as the table itself will be recreated whenever you return to it. You cannot simply iterate all items in the ListLoop, since those refer to specific instances of each element and that list changes whenever the list is recreated). If this is your use case, I would suggest building yourself a really simple iteration to try to understand it. A similar table can be found at training.openspan.com. I could put together an example with that site if that would be helpful. I would need to know what build of 19.1 are you using though.
Shuurgan
CN
@ThomasSasnett I understood your literal meaning and I also made this button or html matchable to all elements with the same attribute by changing the match role. In the automation flow shown in the picture I put the sitename from the Input file in another automation into a dataTable as well, to make it easier to recognize the same element in both dataTables and follow up. But my current design always fails to click the monthly report book button correctly, so I'm wondering what would be the best way to change this part. My version is Proprietary information hidden If possible, could you please make a simple diagram? Thanks for your help.
BAO
Pegasystems Inc.
US
@BAOX17175074 I will attach a sample in a reply to the original post (I can't attach it here). You may use the Robot Inspector to run the IterateSeasonings automation to see it work. It updates a LookupTable, so you can view that in Robot Inspector before and after the run.
I would break down your automation into smaller pieces so you can identify where your issue is. Start by iterating through your list and making sure each row and its children are matched as expected. Then, once you know your iteration through the list works, add a step to click on the row. Is it clicking the right link? If so, now you can add the logic to ensure the second row is clicked, etc.
Pegasystems Inc.
US
Here is a sample solution. You may use the Robot Inspector to run the IterateSeasonings automation to see it work. It updates a LookupTable, so you can view that in Robot Inspector before and after the run.
Shuurgan
CN
@ThomasSasnett Sorry, but I can't download this zip file to the local folder because of work. Can you explain this with a short picture of the automation process? Or is there something I need to improve in my automation process that I can indicate? Thank you!
BAO
Pegasystems Inc.
US
@BAOX17175074 Ideally, you can take the sample solution and run it as it would give you a working example to copy. I will post screenshots; however I can only attach them as a Word document. Are you able to download that?
Your automation is hard to see in any detail. I suggest you break it down first to its smaller parts and identify what part isn't working.
- Have you interrogated the controls correctly? I would test this during interrogation by changing which row is attached to using the Make Prototype option. I would also test at runtime by building a really simple iteration through all of the rows and showing myself a message at each one with whatever data I needed to read from each row.
- Is your automation operating correctly? Start with the main loop iterating through each row. Is it accurate to say with each row, you click a link which navigates to a new page (and thus destroys the table you are iterating)? If so, you will need to iterate something else. In my example, I collected each row into a lookup table and used that as my list to iterate through.
Shuurgan
CN
@ThomasSasnett What I'm doing is simply collecting all the useful data, such as the sitename, in the automation that collects each row of data, and then calling it in another automation and working with the datatable of the sitename collected in the input file to extract the corresponding sitename and clicking on the corresponding “Monthly Report”, I think such a loop should not break the iteration. Because before clicking the button again I've got all the information and just need to extract it. But I don't know what my problem is, if the getClone method is used on the tableRow control, how can I tell if what is added to the list is the sitename or not? Please let me know, thanks.
BAO
Pegasystems Inc.
US
@BAOX17175074 When you call the GetClones method, it returns a list of the current clones for the control. If you pass this result into a ListLoop, the loop will maintain the context of the row. This means that when you use any of the child controls within this loop, they will not be required to have a key value passed to them as they will use the key for the current row being output by the loop. If you were to connect any of the child controls outside of the loop, you would see a yellow bar appear (called a key fitting) where in order to operate on that control, you need to provide it the key for the row. You can try this by creating a new automation and adding an entry point. Connect it to the text property (or any property or method) of any of the controls beneath your row, and you will see the key fitting appear. In my screenshot here, you can see that there is no key fitting on the control lnkProduct (it is a child of trRows). The ListLoop is keeping track of the current instance of trRows it is on and is using that key to retrieve the text property of lnkProduct.
@BAOX17175074 When you call the GetClones method, it returns a list of the current clones for the control. If you pass this result into a ListLoop, the loop will maintain the context of the row. This means that when you use any of the child controls within this loop, they will not be required to have a key value passed to them as they will use the key for the current row being output by the loop. If you were to connect any of the child controls outside of the loop, you would see a yellow bar appear (called a key fitting) where in order to operate on that control, you need to provide it the key for the row. You can try this by creating a new automation and adding an entry point. Connect it to the text property (or any property or method) of any of the controls beneath your row, and you will see the key fitting appear. In my screenshot here, you can see that there is no key fitting on the control lnkProduct (it is a child of trRows). The ListLoop is keeping track of the current instance of trRows it is on and is using that key to retrieve the text property of lnkProduct.
One thing to keep in-mind is that the clone collection is in the matching order and may not necessarily match the on-screen order. If order is important, you must use some property of the row itself or one of its children to establish that.
Accepted Solution
Updated: 21 Oct 2024 20:02 EDT
Pegasystems Inc.
US
Here are screenshots of the relevant portions of my automation for you to try to recreate.
Shuurgan
CN