Workflow Loop Through Multiple SharePoint Items
So, here’s what we have.
- A list of tasks (just using the task list template)
- Create your workflow on your list of people. I named my workflow “Test loop through tasks”, and set it so that it automatically starts when an item is created. You’ll be using a LOT of variables in here, so let’s just create them ahead of time. (Use the Local Variables button in the ribbon) Here are their names and types:
Name Type dictionary Dictionary responseCode String JSONresults Dictionary dataset Dictionary index Integer count Integer myID Integer calc Number Index Plus One Number MyStatus String StringOfItems String myTitle String myAssigned String DueDate Date/Time Add One Number
- In Stage 1 of your workflow, add your first action. Build a dictionary. Click the blue word this, and your dictionary is going to have 2 items in it:
- The Build a dictionary item will then look like this. Click OK.
- The next action to add is Call HTTP Web Service. Click the first this, and put this in it:
Mine looks like this:
(How do you get the GUID? In this case, I want to look through my task list, so one way is to go to my task list in SharePoint Designer, and in the List Information section it says List ID.)
The HTTP method is HTTP GET.
- Click the drop-down box on this action to call the web service. Choose Properties. In the RequestHeaders box, choose the variable called dictionary. The screen should look like this (of course with your own website in the address). Click OK.
- Click dictionary, and choose the variable JSONresults. Output to the variable called dataset.
- Add the action Count items in a dictionary. Click on dictionary. Choose the variable called dataset. Output to the variable called count. This variable is going to tell me the total number of items in that other list, my task list.
(After this action, for fun I like to add a Log to history list action, and just log the variable called count. Logging, just in general gives me more info on my workflow status page later.)
- Add the action called Set workflow variable. Click workflow variable and select the one called index. Click value and type the number 0
This variable is going to allow me to loop through all the items in the other list, starting at zero, up to the total number of items in the list, the count.
- Add another Set workflow variable. Set the StringOfItems variable to say:
This is the variable that we’re going to use to append information to it. For each task, later we’re going to append text to this so that eventually this variable can be inserted into an email that will go to the person and list all of their tasks.
- Next, it’s time to add the loop. So in the ribbon, click the Loop button and choose to Loop with Condition.
- At the top of the loop, click the first value. Select the workflow variable called index. For the operator, select is less than. For the second value, choose the variable called count. Click OK.
Here’s a screenshot for reference, of what the whole loop is going to look like, and now we’ll go through the steps:
- Inside the loop, add the action called Get an item from a dictionary. What I originally wanted to do was to make it only get the items where the assigned to field (in the task list) equals the name of the assigned to field in my list of people here. I couldn’t for the life of me get this to work with a people field. So, instead I’m using the Status field to get only tasks that aren’t completed, and getting the due date field so that I can get just the overdue ones.
Click item by name or path. Use the string builder to do this. Most of this text is typed in there, except for the variable index I used the Add or Change Lookup button.
See where it says Status… that’s the status column in my task list. This word may be different in your own solution if you’re not dealing with tasks or statuses. How did I know to just type the word Status, when the field is called Task Status? This is important. Go to your task list settings page, and click the name of the Task Status column. Look at the URL. See the part where Field= will tell you the actual name of the column.
This part can get a bit more complicated if you have fields that have spaces or other weird characters in them. If I put a space in my column name when I created it, it will look something like Column%5Fx0020%5Fname
You then have to decode it to get what you need. Go here and put your column name in the Encoded box and click URLDecode. Then it will give you this in the Plain box: Column_x0020_name
That value is what you put in the spot where I put Status.
- Add another action to Get item from dictionary. Instead of the status field, this time we’ll be getting the due date. Here’s what these last two actions look like:
I’m using these two fields because that’s my “Where”. I am only going to want tasks that have a certain status and a certain range of due dates. The fields used here will potentially be different in your own solution.
- With the orange line directly under that last condition, insert another If any value equals value. And the variable DueDate is less than Today (Current Date). This will narrow down my list to only get items that are overdue and haven’t been completed.
- Inside of this IF section in the workflow, insert an action Get item from dictionary. This is similar to step 14, except this is getting the ID of each item that hasn’t been completed and is overdue.
- Next add an action to Set Workflow Variable. Set the variable MyAssigned. Click value, and click the fx (function) button. This is where I choose the Workflow Tasks (the list I want to loop through), and I want to get the Assigned To field for the items where the ID is in my list of IDs of the items that aren’t completed and are past due. The only reason I’m doing the Assigned To part here is because I wanted to do it at step 14 and that portion wouldn’t work with a people field.
- Add another action to set workflow variable. Set the variable called myTitle to the value of the task name.
- Add the action Log to History List. Log the variable called myID.
- Next, add an IF condition: If Any Value equals value. If the variable myAssigned equals Current Item: Assigned To. This will narrow down the list to only items in the task list that are assigned to the same person in the Assigned To field in the list we’re running this workflow from.
- Add an action to Set Workflow variable. Set the variable StringOfItems to this:
What the heck is all of this? This is where you create what you want the email to look like. Be sure to hit the enter key (carriage return) after you insert that first lookup to the StringOfItems. Basically I want it to show the title of each task as a hyperlink to that task, and I want to show when it’s due. This is going to loop through all of the person’s tasks that are not completed and overdue, and put them all in one big list in this variable.
- Put the cursor at the very bottom of your Loop, still inside it, and insert an action Do Calculation. Calculate the Variable: index plus 1
Output this to the variable called Index Plus One.
- Add an action to Set Workflow Variable. Set the index variable to the value of the Index Plus One variable.
This causes our loop to loop again until it’s finished going through all of the items in the task list.
- In the transition to stage section, GoTo end of workflow. Publish the workflow.
- In the Transition to stage section, Go To Stage 1.
- Publish again.
So, the solution to this is to manually create the items in the Loop through tasks list.