About three years ago I released an open source Dynamics CRM solution for scheduling and executing recurring workflows. My solution would execute a FetchXML query to return a set of records and then start a workflow for each of those records without requiring any external processes or tools. This is a generalized approach to solving a class of problems that includes the following scenarios:
- The birthday greetings problem: How can you, on a daily basis, send an e-mail to every contact with a birthday = today (where the date value for today is obviously different every day)?
- The monthly update problem: How can you, on a monthly basis, generate an activity for every account with status reason = X (where it's important that the process only runs on a certain day of the month based on status reason values as of that exact date)?
Of all the CRM sample code and solutions I've ever shared, I think this was probably the most popular, but it had one glaring flaw. My original solution would only retrieve a maximum of 5,000 records per run because it didn't include any result paging code. Today I have released an updated version of my solution for CRM 2016 that does include result paging, and I've also moved hosting for the solution source code to GitHub.
How it works
In case you're unfamiliar with the previous version of my solution, my approach requires three components (the names have changed in the updated version):
- A custom workflow activity (AlexanderDevelopment.WorkflowScheduler) that can execute a supplied FetchXML query and initiate the workflow for each retrieved record.
- A custom entity (Recurring process) to hold the FetchXML query and scheduling details.
- A workflow (Recurring workflow runner) to run the AlexanderDevelopment.WorkflowScheduler activity on a recurring schedule.
A "Recurring process" record is created, which starts a corresponding "Recurring workflow runner" workflow in a timeout state. When the next run date == the current time, the "Recurring workflow runner" workflow advances the next run date, and then it initiates the AlexanderDevelopment.WorkflowScheduler activity with the FetchXML query and workflow lookup from the "Recurring process" record. The AlexanderDevelopment.WorkflowScheduler executes the FetchXML, loops through the results and starts the specified workflow from the lookup for each record. A newly started "Recurring workflow runner" workflow then waits for the next run date to start the process again.
Here's what a "Recurring process" record looks like:
Here's the "Recurring workflow runner" workflow:
The default result page size is 1,000, but you change it in "Recurring workflow runner" workflow definition:
Putting it all together
As mentioned above, the source code for the solution is available in a GitHub repository here. You can also download a CRM solution ready to load into your system directly from the repository releases area.
Happy workflow scheduling!