How To

Let’s Get With The Flow – Loop Basics

LoopdeLoop

Ever have an automation use case where you need to take a collection of records and do something with them? The only declarative (clicks, not code) automation tool that can stand up to the task is Flow Builder.

As someone who identifies with an Admin, I have to admit, it took me a while to understand how to configure loops in flow.  I hope these basic steps help you in understanding how to configure a basic loop.

Here are a few lessons learned from implementing this use case:

  • Learn how to create a loop, set values via assignments, add a loop record to a collection and handle DML (database actions) outside of the loop.
  • Provide descriptions, where provided, in Salesforce. This may be tedious step, I know, but your future self will thank you when you are trying to remember what you configured or assist other/future admins when troubleshooting or enhancing what was built. This includes variables, the purpose of a flow, what each flow element does, etc.

What’s a loop? Think of it as an assembly line. Every item going down the assembly line has the same actions taken on it. In the Salesforce world, if you have a group of records that you need to perform the same actions on for every record in this grouping would go through a loop. Each record, when it is its turn to go down the assembly line will be placed into a record variable, in my case, I call varLoopRecord. After it’s done with its turn, then that record is removed from varLoopRecord and the next record is stored in varLoopRecord. This continues to happen until we are done with the last record in the collection and therefore, ends the loop.

ILoveLucyAssemblyLine.gif

Start a loop path, iterating through the records in a collection variable. For each iteration, the flow temporarily stores the record in the loop variable (in my example, varLoopRecord). Often times, within a loop, you would want to make decisions and set certain values to fields in the loop record.

A collection variable is a list of records you wish to take action on. A loop uses a loop variable to store the values for the current record in the collection. When the loop completes taking action on the one loop record, Salesforce then places the next record into the loop variable. To keep track of changes made along the loop path, add the loop record variable as a record to a new collection variable.

One very important note: Avoid the bad Apex development practice of making a DML operation within a loop. You do not want to hit Salesforce-imposed ‘governor’ limits on how many database operations you can do in a single transaction. This same limit applies to flows as well.

Business Use Case:  Addison Dogster is the system administrator at Universal Containers. Mary Markle is the Director of Operations. She would like to automatically update cases with a status of Escalated to a High priority and set the IsEscalated checkbox to true.

Solution: This blog post will just cover solution of getting the group of cases that have the Escalated status and taking action on those records.

The outcome looks like this:

FlowWithaLoop.PNG

This flow does the following: (1) get the cases where the status is set to Escalated and store the records in a collection, (2) a decision to determine whether records were found in the query, (3) put each record in a loop record variable, (4) set the priority to “High” and the IsEscalated checkbox to true, (5) add the loop record variable into a new collection of records that will be updated and after the last record in the collection is completed, (6) update the records in the new collection.

Steps: 

1. Let’s create the flow. For those using Salesforce Classic, flow can be found in Create | Workflows & Approvals | Flows. In Lightning Experience, it is found under Process Automation | Flows.

A. Let’s create our flow resources.

Best practice tip: Provide a description so you and other/future admins know what this flow resource is used for.

Let’s create a text variable called “varLoopRecord” that will store the loop record variable, where Record is the Data Type and Case is the Object.

varLoopRecord.PNG

Create a record collection variable resource called “CollectionToBeUpdated” that has a record data type, Case as the object and is set to allow multiple values (collection).

CollectionToBeUpdated.PNG

B. Next, we will use Get Records flow element to query the Case object to get all the records with the status of Escalated.

Object: Case

Filter the Case Records by Status Equals Escalated.

How many records to store: All records

For the “How to Store the Data” option, I chose to use “Automatically store all fields.”

Best practice tip: Provide a description so you and other/future admins know what this flow element is used for.

FlowWithaLoop-GetRecords.PNG

C. We will a Decision flow element to determine whether records were found in the previous step. If not records were found, the flow would fault when it get to the step in the flow where it tries to do things with the loop record variable — there is no record to work with!

Best practice tip: Provide a description so you and other/future admins know what this flow element is used for.

For the “Records Found” outcome, we need to check record collection has items. Set the conditions to the following:

{!Get_Contacts} Is Null {!GlobalConstant.False} (This is a double negative. Which means, there is at least one record in the collection).

The default outcome: No Records

FlowWithaLoop-Decision.PNG

View image full screen

D. We now need a Loop flow element where we will take each record in the Get Contacts record collection variable to iterate through. Configure it as follows:

Best practice tip: Provide a description so you and other/future admins know what this flow element is used for.

Collection Variable :{!Get_Contacts}

Loop Variable: {!varLoopRecord}

FlowWithaLoop-Loop.PNG

E. For a loop record variable, we need an Assignment flow element to assign values to fields that we will update in this flow. We will assign “High” as the priority and true to the IsEscalated checkbox field in the Loop record variable. Configure it as follows:

Best practice tip: Provide a description so you and other/future admins know what this flow element is used for.

Set the variable values to:

{!varLoopRecord.Priority} Equals High

{!varLoopRecord.IsEscalated} Equals {!GlobalConstant.True}

FlowWithaLoop-Assignment.PNG

View Image Full Screen

F. We need another Assignment flow element to assign the loop record {!varLoopRecord} to a new collection (!CollectionToBeUpdated} that will be updated after the loop ends.

I have to admit, this configuration trips me up. It reads backwards AND you don’t need to specify the Id of the loop record variable, just specify the loop record variable. Here we are added the {!varLoopRecord} to the collection {!CollectionToBeUpdated).

Best practice tip: Provide a description so you and other/future admins know what this flow element is used for.

Set the variable values to:

(!CollectionToBeUpdated} Add {!varLoopRecord}

As noted earlier, but worth noting again, please avoid database actions within a loop. Close the loop and make your DML action outside the loop to avoid hitting Salesforce governor limit for the number of DML actions within a transaction.

FlowWithaLoop-AssignmentAddtoCollection.PNG

View Image Full Screen

G. Now that we’ve closed the loop, we want to update all the records in the collection (!CollectionToBeUpdated} with an Update Records flow element. This will update the priority to “High” and IsEscalated to true for all records in the collection.

Configure it as follows:

How to Find Records to Update and Set Their Values: Use the IDs and all field values from a record or record collection

Record or Record Collection: {!CollectionToBeUpdated}

FlowWithaLoop-UpdateRecords.PNG

View image full screen

H. Add the subflow Send Flow Fault Email. For instructions on how to create this, go to Step 2 of blog post: Maximize Maintainability With Process Builder and Componentized Visual Workflow. Set your flow starting point. And connect the flow elements, fault connectors and outcome connectors to match the below…

FlowWithaLoop-Connectors.PNG

I. Save/Save As and provide the following properties.

Best practice tip: Provide a description so you and other/future admins know what this flow is used for.

FlowWithaLoop-Properties.PNG

View image full screen

I. Click the “Activate” button.

Note: This flow can be set as a scheduled flow or invoked by a process or invoked by a button. The initiation will not be covered in this blog post.

Now, before you deploy the changes to Production, don’t forget to test your configuration changes.

  1. Create a few cases with the status of Escalated with a priority that is not set to High and IsEscalated is unchecked.
  2. Initiate the flow.
  3. Verify the cases were updated (priority is now set to High and the IsEscalated checkbox is now set).

Deployment Notes/Tips:

  • Flow can be deployed to Production in a change set (or can be deployed using a tool such as Metazoa’s Snapshot).
  • You will find flow in a change set under the Flow Definition component type.
  • Activate the flow post deployment as flows deploy inactive in Production, unless you have opted in on the Process Automation Settings screen, to “Deploy processes and flows as active.” NOTE: With this change, in order to successfully deploy a process or flow, your org’s Apex tests must launch at least 75% of the total number of active processes and active autolaunched flows in your org.

6 thoughts on “Let’s Get With The Flow – Loop Basics

  1. Thanks Jen! I don’t work with Flows as often as I’d like, but when I do, I feel like I end up having to spend half a day getting my head wrapped back around Loops. This will be a great reference for me in the future!

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s