Hello @whitestar
I see you have some problems with your workflow. So I will try to help explain them in a simple manner.
Best Practices (do as you develop and don’t leave until later):
— Rename all Sequence containers and activities to something unique, while also leaving the name of the activity. For example, For each acct in Account array
or Assign Account array
. By renaming these activities, you are able to navigate your code and locate exceptions much quicker.
— Be more consistent on your variable naming. If your standard is to use the data type prefix, do this for all variables and consistently use the ‘_’ or not. Also, maintain this standard consistently for arguments but include the direction prefix along with the data type prefix.
(I’m not a fan of the data type as a prefix, and think it’s out-dated and a 101 practice from 20+ years ago. So I don’t typically encourage the data type prefix, and much prefer grouping variables by something that describes their use, followed by the noun of what it’s used for and the verb of what it is doing or storing. However, whichever plan you have for variable standard, just be consistent.)
— Avoid using the index to reference a column in a row when your column names are reliable. For example, row("Name").ToString
to reference the name of the row item.
— Annotate all variables and arguments so you can understand how the variables will be used.
— Annotate all For each blocks and If blocks so you can understand why you are looping or why you have an If condition and for what purpose
— Set the TimeoutMS property for all activities that use an element/selector. If the element “should” already be loaded then use a TimeoutMS of 0; if the element needs loading time, then use a TimeoutMS of a few seconds depending on expected loading time. Since the Attach Window should be the first thing it is waiting for, you should be able to use a 0 for the timeout of each element inside, unless they follow a button which causes a new form/page to have to load. Then, the next element would need a timeout, while the others following could use a 0.
— Your Attach Window selector is too generic and will attach to any IE window open. You should check this to ensure it is unique enough to only attach to the specific window associated with the web application. In addition, all elements inside should leave off the first line of the selector when they share that line with the Attach Window container, in order to use a partial selector. I am mentioning this because you are using the full selector for one of your elements I noticed, which means if you need to change the first line of the selector, it requires multiple edits rather than one.
— Remove all outer Sequences or Bodies that have only 1 embedded activity. For example, you have a For each inside a Sequence and that is the only activity, and in another place you have a Sequence inside another Sequence. Only times to use outer Sequences is when you have either A) more than one activity inside a block or B) a desire to group tasks together for better organization - Note: remember to rename the Sequence or Body blocks to identify what that sequence of actions is doing. EDIT: Adding a tip that you can use to fix this: select inside activity, ctrl+x to cut, then select Sequence or Body, delete, select inside block and ctrl+v to paste activity back in; this is most user-friendly way to maintain this standard I think.
— Avoid using the ‘idx’ property in selectors, unless there’s no way to get around it or if the selector is still unique anyway. For example, you have this in the Type Into using the index of an array, and you might be able to directly use the value in the array in an aaname property if available.
— Keep the logic organized in simple steps: 1) get entire data set, 2) filter data set to items to be processed, 3) Loop over filtered items, 4) Loop over columns only if necessary, 5) validate value of item and change value or throw BER if needed, 6) input item into application. So in most cases, you would only have 1 loop; I think you are over-complicating it.
— Each task that gets performed in an application should be implemented as a separate workflow and deployed into a Library. The Library would just perform the action for one item. This way, you can call this action for each individual item. Since, it will be a centralized Library with version control, you will be able to integrate it into any future projects. This should be done from the start of designing the pieces for a project, and I cannot stress this enough
Problems to solve:
— Your Send Hotkey is wrong. using [k(down)] will not work for this as that is a string expression for the keystroke, but Send Hotkey does not receive expressions. You can only select the down key by clicking on the dropdown, and if you would like multiples, then copy and paste the activity or run it through a loop. Or you can use a single Type Into to perform the multiple key presses with the expression you had used. Note: you could probably leave the selector blank for this as long as your Attach Window is unique enough to allow the keystroke to only occur within the intended application.
— You are looping over the data set twice, and I think that is what you are trying to solve by adding a break. You will want to instead only loop the data set once. Unfortunately, the Filter Data Table activity outputs a new Data Table, therefore you lose the entire data set. If you would like to loop over the entire data set but also filter it, then you will need to use a .net solution that outputs to an Array of DataRows. For example, Assign ExcelDT.AsEnumerable.Where(Function(r) r("Name").ToString.Trim <> "" And r("Number").ToString.Trim <> "" And r("Reason").ToString.ToUpper.Contains("NO")).ToArray
, and store that to a variable of type Array<Of DataRow>
. You can also use a sql .Select() syntax, but it is not my preference.
I am not sure how your application works, so I can’t comment much more on the problems. It looks as though you are looping over a series of potential selectors containing “Surname#”, then typing in each selector containing the corresponding “Code#” with the letter ‘F’. There has to be a better way to do this…
Without seeing more of the application or a more specifically defined problem, like what is it actually doing that is wrong. Please also make use of Write Line, Message Box, or Debug to see how activities and variables are used during the steps which are causing issues.
Regards.