You are viewing limited content. For full access, please sign in.

Question

Question

Workflow and multiple For Each Value

asked on November 25, 2014

G'day all from Sydney, Australia.

 

I'm working on a solution where I have to use Workflow to export a bunch of metadata into a CSV file. I'm using a For Each Value to recurse each line, but my problem is that there are multiple entries that need to recurse at the same time. How do I recurse the 2nd item (or 3rd, 4th, etc.) without having them duplicate?

 

For example, let's say I have columns labelled NAME, ADDRESS, PHONE, EMAIL and the following sample data:

 

"Paul Snedden", "Sydney", "+61123456789, +61987654321", "email@email.com, anotheremail@email.com"

 

Side note, sorry if that's not the best way to show my metadata...it's the best I could come up with :)

 

As you can see, I have two PHONE entries and two EMAIL entries for the one person. Thus, I'm using a For Each Value (Current Value - PHONE) to export the first entry as:

"Paul Snedden", "Sydney", "+61123456789", "email@email.com"

 

That's perfect, and as required.

 

The second entry in my export file, however, comes out as:

 

"Paul Snedden", "Sydney", "+61987654321, "email@email.com"

 

The PHONE entry recurses correctly, but the EMAIL one doesn't because I can't determine a method of recursing the EMAIL entry inside the PHONE entry.

 

If I use another For Each Value using EMAIL, then I get the following:

 

"Paul Snedden", "Sydney", "+61123456789", "email@email.com"

"Paul Snedden", "Sydney", "+61123456789", "anotheremail@email.com"

"Paul Snedden", "Sydney", "+61987654321", "email@email.com"

"Paul Snedden", "Sydney", "+61987654321", "anotheremail@email.com"

 

Thus, embedding a For Each Value inside a For Each Value doesn't help.

 

Any suggestions? I hope this makes sense :)

0 0

Replies

replied on November 25, 2014 Show version history

Paul,

The problem as I see it is that there might be one or two phone numbers AND one or two email addresses. (I am assuming that the count of phone numbers and the count of email addresses do not have to be the same)

As a .NET developer my first 'go-to' when I can't make something work easily with the canned activities is to use the script activity and code it up myself.  (When you hit nails every day with a hammer its easy to keep using it instead of looking for another tool!) 

Even so, doing this in a script could also get a bit 'kludgy'.  Here is some pseudo-code that might accomplish what you are looking for.  (Note: This is pseudo-code only, it would have to be cleaned up to actually work in a script activity...)

'Store the values in each field to a string array...
'Doesn't matter how many values are in each string array, 
'some can contain 1 value and some several values...

Dim names() As String = NameField.ToString.Split(",")
Dim addresses() As String = AddressField.ToStrong.Split(",")
Dim phoneNumbers() As String = PhoneField.ToString.Split(",")
Dim emails() As String = EmailField.ToString.Split(",")

'Initialize the variables to hold the last good value found
'in each string array...

Dim nameToWrite As String = ""
Dim addressToWrite As String = ""
Dim phoneToWrite As String = ""
Dim emailToWrite As String = ""

'Initialize a flag variable indicating whether or not 
'to write an CSV record...

Dim okToWrite As Boolean = False

'Ok, now step through the string arrays 5 times..
'NOTE: Assuming no field value will hold more than 5 values!

For i As Integer = 0 To 4
    
    'If the length of the Names array is less than the current
    'counter then store the new value, otherwise keep the previous value found.
    'If this is a new value then set the flag to write a new CSV record...

    If i < names.Length Then
        nameToWrite = names(i)
        okToWrite = True
    End If
    
    'Do this for each string array...
    
    If i < addresses.Length Then
        addressToWrite = addresses(i)
        okToWrite = True
    End If
    
    If i < phoneNumbers.Length Then
        phoneToWrite = phoneNumbers(i)
        okToWrite = True
    End If

    If i < emails.Length Then
        emailToWrite = emails(i)
        okToWrite = True
    End If

    'If at least one of the string arrays introduces a new value then write the
    'new CSV record out with the last good value from each string array...
    
    If okToWrite Then
        'Write CSV out with nameToWrite, AddressToWrite, phoneToWrite, emailToWrite
        'NOTE: CSV export code here...
        
        'Set up for the next iteration...
        okToWrite = False
    Else
        'No new values found to write so exit the loop prematurely...
        Exit For
    End If
    
Next

 

If you decide to go the script route and need further assistance I am glad to help.  You can email me at cprimmer@qfiche.com.

Good luck!

0 0
replied on December 3, 2014

I'm almost certain you can do this without a script activity, however, it's not trivial to do.  To be clear, you want to take field values from a set of documents and create a CSV file using that data.  But two of the fields, Phone Number and E-mail, are multi-value fields and thus can have multiple values?

I'm going to assume you're getting the field values using a Retrieve Field Values activity.  This activity can create multi-value tokens for multi-value fields.

Multi-value tokens can be "indexed into" using the Token Editor, much like you can access the value at a specific index of an array.  Additionally, you can use the Length token function (again, from the Token Editor) to determine if there are multiple phone numbers or e-mail addresses.

Within the For Each Value activity, you can use the Iteration token as the index for a multi-value token.  This means that if you're adding a record for the second phone number, you can index into the E-mail token to get the second e-mail address.

Now, it gets a little bit trickier if you have different numbers of phone numbers and e-mail addresses.  You may actually want to use a Repeat activity as a "for" loop and index into both tokens.  This allows you to set the condition on the Repeat to be something like "while Iteration < Max(number of e-mails, number of phone numbers)".  Inside the Repeat activity, you would need to use a Routing Decision to check if the current iteration value will exceed the number of e-mails/phone numbers, and if it does, what value it should use.

Another tool you'll probably need is the Assign Token Values activity.  A common pattern with this activity is to create a blank multi-value token before the For Each Value activity, then add another one inside the For Each Value activity that appends values to the 'container' token you just created.  In this way, you can represent lines of CSV file and then easily write them all to a file or e-mail or whatever (again, look at the token indexing for separating each value with a new line).

I hope this helps!

0 0
You are not allowed to follow up in this post.

Sign in to reply to this post.