How to continue counting from the last previous item in For Each loop after placing Break activity?

Hi,

I have a For Each loop for counting numbers.

I place a Break activity in the loop. If the condition is true, it will proceed the Break activity.

I know that Break activity will exit the For Each loop and continue the next activity in the workflow.

However if I want to continue counting from the last previous item in For Each loop using another loop, is there any methods to know the previous item and continue counting from there?

Eg. There are 1,2,3,4,5 in a list. After the Break occurs, the last item that has been counted is 3. How do I continue from 4?

Maintain a counter for every time loop.

Once the break activity ovcurs,

Use the counter to continue from there.
Example:

For index=counter to list.Count
To access the list value : list(counter)

I believe the newer For each has an Index output property.
but, if not, then you can store this at the beginning of the for loop using .IndexOf()
For example,

For each item in arr
    index = Array.IndexOf(arr, item)

However, this needs to be adjusted for String and Int loops because it will find the first item in the array if there are duplicates in the array. You can adjust this by using the startIndex property.
Array.IndexOf(arr, item, index+1)

Then, since it will be starting the loop again, you can use .Skip() to jump to the index that was previously stored.
For example (assuming index starts on -1),

For each item in arr.Skip(If(index<0, 0, index))
    index = Array.IndexOf(arr, item, index+1)
    If condition
        Break

A datatable loop will look like this:

For each row in dt1.AsEnumerable.Skip(If(rowIndex<0, 0, rowIndex))
    rowIndex = dt1.Rows.IndexOf(row)
    If condition
        Break

This is also useful for error handling when an error might push your process out of the sequence and need to start over again.

You can also use a counter instead of using the .IndexOf(), but I don’t know if that is a good approach to be honest for ForEach loops.

So, something like that.

Regards.

2 Likes

Hi @KarthikByggari and @ClaytonM,

Sorry for the late reply!
I will try it out and let you all know again

Thanks for helping me! :slight_smile:

1 Like

Hi @KarthikByggari,

I have put a counter in the For Each loop.
When I continue the counter in another loop, it managed to continue from the previous number.
However it still restart counting the values.

Eg. There are 10,11,12,13,14,15 in a list. The counter is 0. After the Break occurs, the last item that has been counted is 12. The counter stop at 3. When I continue the counter in another loop, it did continue from 4. However, instead of counting from 13, it restarts and count from 10 to 15.

How do I make it count from the last counted number?

Thank you :slight_smile:

Hi @Ying_Zhen_Lee
You will need to use that counter in the ForEach with .Skip(), like I showed above.

For each item in arr.Skip(If(index<0, 0, index))

That way, when it starts a new ForEach loop, it skips to the index that it was on previously.
The reason I put If(index<0,0,index) was so you can start at -1, since indexes start on 0 and you will do index+1 at the beginning of the loop.

Regards.

1 Like

Hi @ClaytonM,

Thanks for your help!

I tried to use the .Skip() method. However it shows the following error

error

What do they mean by ‘Skip’ is not a member of ‘System.Array’ ?

Thank you

Make sure you have System.Linq imported (in Import tab next to Arguments)
.Skip should be a member of System.Array so I’m guessing the namespace is not imported for it.

The error basically means it doesn’t exist and can’t be used with Arrays. If you were to type a period next to your variable, it will list all the members of that variable type. If it is not listed, then we have a problem! :stuck_out_tongue:

.Skip should be a member though, so verify my first suggestion in the Imported Namespaces to see if it helps.

Regards.

Hi @ClaytonM,

The System.Linq is in the imported namespaces :sweat_smile:
However the System.Array is not in the imported namespaces.

Is it because of the System.Array ?

Thank you

The System.Array is a type of variable, so you don’t need to import it.

One thing that I have seen happen is a glitch where the member doesn’t work. What I have done in the past is delete it and retype it in which fixed it.

If that doesn’t help. Then can you upload an example workflow where the validation error is there? Thanks.

I probably won’t get back to you for several hours though, but maybe someone will help you. Regards.

Oh also, if you upload a workflow on version 2018.4, I can’t open it inside a ForEach cause there was an update to that activity. Instead move your line to a Write Line activity outside the ForEach.

Thanks.

Hi @ClaytonM,

Thanks for the suggestion!

I tried retyping it but it did not fixed.

I will upload an example workflow here

Thank you :slight_smile:

Hi @ClaytonM,

The following is the example workflow with the validation error, a word document

example_workflow.zip (11.9 KB)
word_example.zip (8.7 KB)

Thank you :slight_smile:

Ok, I looked at it and figured out your word_array variable is of the wrong type. You want it to be an Array Of String.

After that, it should be a System.String[] type

That fixes the member error. The other error is because your If statement is trying to return a number in the True side and a GenericValue in the False side; both sides need to be the same type.

To resolve this, you can change the counter variable to an Int32 type in the variables pane (this is the recommended approach). Alternatively, you can convert the False side of the If statement to an integer like so, Convert.ToInt32(counter.ToString)

Let me know if there are any issues getting that to work.

Regards.

Hi @ClaytonM,

Thanks for your help! There is another error.

error_2

When I try to put Convert.toInt32, the error disappear.
However when I run the workflow, it say input string was not in a correct format

error_3

Do you know why I cannot use Convert.toInt32 ?

Thank you

Yes. if there is a chance that itemB.ToString.Substring(0,4) is not a number or empty, you will want to check if it is a number before using it like a number.

You can do this with vb using IsNumeric()

For example,
In an If activity, you can use the condition: IsNumeric(itemB.ToString.Substring(0,4))
Then, use Convert.ToInt32() in the True side as you please, and place additional logic in the false side.

You can also do this with an inline If statement in your vb expression: For example,
If(IsNumeric(itemB.ToString.Substring(0,4)), Convert.ToInt32(itemB.ToString.Substring(0,4)), 0)
That would basically check if it’s a number, and if not then use 0 as the number.

Hope that helps.

Regards.

Hi @ClaytonM,

itemB.ToString.Substring(0,4) is a string. However, I don’t get why cannot use Convert.toInt32() to convert String to Integer ?

Thank you

You can convert a string to integer, however if the string has non-numeric characters, it will give you that error - which is why I suggested that you use IsNumeric() to check string before conversion.

Also, if itemB.ToString.Substring(0,4) is supposed to only contain numeric characters, then you should check it in a Write Line or Message Box to make sure you are extracting the correct string.

Hi @ClaytonM,

Thank you for your help! I managed to solve the error, I did not put it in the correct place :sweat_smile: