Repeating or cyclic actions on list items can be a critical part of a workflow strategy, such as incrementing a counter, looping through a list of names or sending repeating task reminders, but since SharePoint 2010 the approach has become more difficult.
SharePoint 2007 allowed a workflow to call itself recursively; the workflow could use its own OnItemChanged event by writing new values back to the original item, again and again, stepping through whatever series of changes were needed. However, this could easily become a burden to the SP Server, as a large number of iterations could be loaded onto a single loop of the SP Workflow Timer job.
In SharePoint 2010 this ability was removed so that a list workflow could not trigger an OnItemChanged event to call itself repeatedly. This made single-workflow loops in SP Designer Workflows impossible, but of course the need for looping remains.
By using instead two lists with cooperating workflows, a recursive call can be simulated while also adding a logging capability.
Cooperating with Helpers
The diagram below shows how this works. A new list item is created in the Work List, tripping the OnItemCreated event of the main workflow. This workflow handles all calculations with workflow variables, and never writes back to itself, instead creates a new item in the Recursion Call List. This list has a helper workflow that is triggered OnItemCreated. If needed, it can write back items in itself (Recursion Call List) because it has no OnItemChanged event.
While testing, you can reduce the timer job and helper workflow delay, but try to avoid repetitions that create a large batch on the same cycle.
A Real World Example
Out-of-the-box Approval processes can be easily added to SP Designer workflows and include the capability to issue a reminder if not completed by a due date. Using recursive techniques, it's possible for one Approval process to call another when the due date is reached.
In this example, a workflow is triggered by OnItemChanged events and if conditions are right, sends out an approval workflow. If the initial approval task is not completed within 7 days reminder approval tasks are sent out.
The Main workflow is presented below.
- Each time the workflow is started, it first tests two conditions, Report Completed and Report Accepted, which helps bound the Approvals between two events. The report must first be completed before an approval is attempted, and approvals shouldn't be sent out after it's accepted.
- A column in the list tracks if this is the first time through (New) or a subsequent run (First), which will determine which Approval process is used. In this way, we can present different Task email titles or copy.
- The default Modified list column always timestamps an item, useful in an OnItemChanged event. To this 7 days are added, and copied to another workflow variable (NextApprovalDueDate).
- The first run Approval process is then started, with the Task email assigning the NextApprovalDueDate to the Due Date for Task Process.
The process is repeated, with later passes running through the IfElse segment using a one-day delay and a slightly different task Title.
Hijacking the Approval Process
Nothing in the diagram above indicates a recursive call. For that we use the Approval process itself, within the Task Behaviors designer.
In point 4 above, clicking the word "Approval" opens the task information page. Clicking open the breadcrumb menu near the top opens up the default logic of the Approval process.
Select "Task Behaviors" here:
A SharePoint Approval process has built-in event handling to track the process and issue notifications.
When a Due Date for Task Process is reached, the "When a Task Expires" event is triggered. Simulating recursion starts with replacing the out-of-the-box code.
A new item is created in the "RecursiveApprovals" list, to which we pass the values that we will want written BACK to the current list.
Remember, we can't have the current workflow trigger its own OnItemChanged event, so we
use another list to temporarily hold these values and then feed them back to our first list.
In this case we send over the Title, ID, aCountCycles counter, a state variableNewItemChoice, and the NextApprovalDueDateworkflow variable.
At no time has our Main workflow written back to the original item.
The Helper Workflow
The RecursiveApprovals list has a simple workflow started by the OnItemCreated event that increments the counter and state variables, pauses for 7 minutes and then writes back the updated variables to the original list:
This will trigger the first list's OnItemChanged event, beginning the cycle again in what is in essence a recursive call.
- SharePoint Approval processes send out notification emails to the task initiator and recipient for many task contingencies. Because the Approval process is started and stopped many times, these notifications could be burdensome. This could be mitigated with additional logic in the Approval process or simply by removing these notices altogether.
- While testing, developers would initially want to set the delays shorter, however delays of under 4 minutes tends to result in unexpected and inconsistent behavior, even with a short Workflow Timer job increment. One test may loop 10 times and the next 3. If you experience this, reset the delays to above 10 minutes. In the real world, these delays are typically measured in days.
- The SharePoint Workflow Timer Job default setting recurs every 5 minutes. This can be set lower during testing by going to Central Admin > Monitoring > Review Job Definitions, and paging to "Workflow". Click on the link and adjust it as desired, as low as 1 minute.
- Items in the helper list are created fresh each loop. They could potentially be deleted, or they could be saved as a very useful log of the process.