Removing name from Person/Group(Multiple value) with a designer workflow
-
09-12-2020 - |
Question
I have a list where I store groups that are required to fill up a form, and every group has his user list stored in a Person/Group field with multiple values enabled. What I want to do is a workflow that every time a user fill up a form, his name will be removed from this multiple value field based on a group ID. I already tried replacing his name with a blank space but it didn't work, any idea of how can I remove a name from a multiple person field?
Thanks.
Solution
I believe the key here is using Dictionaries (which are only available in SPD2013 workflows). The value of a multi-person field is treated by the workflow engine as a JSON object containing an array of user ID's, like this:
"Attendees": {
"__metadata": {
"type": "Collection(Edm.Int32)"
},
"results": [
92,
479,
21,
55
]
}
In a SPD2013 workflow you can set a dictionary variable to a multi-value field like this and then iterate through the contents like an array. The process requires a lot of tedious steps but it works basically like a for loop in any programming language.
So, if you already know the ID of the person who needs to be removed from the field, the procedure would go like this:
Set up an index variable. This will be incremented during each iteration of the loop block.
Create a new dictionary variable called "results" and use the get an item from a dictionary activity to get the results array from the field value JSON object. This contains the user id's as plain numbers.
Count the number of items in the dictionary and save to a variable
Create a Number variable called
lastIndex
and set it to the count of items inresults
minus 1Create a String variable
output
but do not set a value yet (we are going to build a JSON object with this to set as the new value of the field)Add a Loop block to the workflow and set it to run the number of times as there are items in the array.
For each item in the array, get the value at the index variable by using the get item from dictionary activity. Enclose the index variable in parentheses
Here, compare the
current
value to the user ID that we want to remove. If that value equalscurrent
then we simply do not add it to the output string. We also must compareindex
tolastIndex
in order to format the output string correctly. If we are handling the last item in theresults
array then we do not want to add it to the output string with a trailing comma.* In the below screenshot, the IF statement is this:
if( index !== lastindex && current !== BadUserId ){
output = output + current + ","
} else {
output = output + current
}
As the final action inside the loop, increment the index variable
After the loop, set the output variable to itself in brackets so that it has correct notation for an array
Create a new dictionary called
type
that contains this Name / Value pair: {type
:Collection(Edm.Int32)
}Create a new dictionary called
ValueCollection
and give it two Name/Value pairs: {results
:results
,__metadata
:type
}Finally, set the multi-value person field to the
ValueCollection
field.
*There is a potential flaw here, which is that if the bad user id occurs at the end of the array then you may still end up having a trailing comma. It may be more effective to use Regular Expression Matching but I have not tried that.
OTHER TIPS
Possibly have another list thats starts off empty, and when a user completes the form - add their name to this list. Then do a comparison within the workflow to see who is on list 1 but not list 2 - they are the people still to complete the form.