Salesforce, Python, SQL, & other ways to put your data where you need it

Need event music? 🎸

Live and recorded jazz, pop, and meditative music for your virtual conference / Zoom wedding / yoga class / private party with quality sound and a smooth technical experience

Reuse your Flows with Subflow

12 May 2023 🔖 professional development salesforce
💬 EN

Table of Contents

Thanks for coming to watch “Reuse your Flows with Subflow.”

Video, slides, and a session recap can be found below.

Abstract

Join me at the Columbia, MD Salesforce Women in Tech group to discover advanced techniques and unleash the true power of Flows!

In this presentation, I’ll show you how to simplify your Flow design with the Subflow action.

By creating reusable building blocks, you can save time and effort when building Flows, and avoid duplicating code.

I’ll share tips and tricks for advanced planning and designing cookie-cutter-like Flows, so you can use them for many variations on a theme.

I’ll also show you how to take advantage of ideas from computer science like “Don’t Repeat Yourself” and “Application Service Layers,” to make your Flows more efficient and effective.

This workshop is perfect for admins who want to take their automation skills to the next level and learn how to create more powerful and flexible Flows with Subflows.

What we did

  1. Found common ground on a few definitions.
  2. Looked at 2 existing flows, both dealing with Account records, that had an awful lot in common.
  3. Built a 3rd flow to capture the shared parts following the beginner-level “Don’t Repeat Yourself” principle. Simplified the other 2 flows, replacing their redundant parts with “subflow” cross-references to the new 3rd flow.
  4. Edited our 3rd flow to be even better (no longer specific to Account records), using the intermediate-level “Application Service Layer” concept. Added a 4th flow, dealing with Contact records, that also cross-referenced the freshly-improved 3rd flow.

Definitions

We started out with a quick level set:

  1. What is Salesforce Flow? (Answer: absolutely, positively, a very serious programming language you can apply best practices to that, sadly, are largely still only taught in books using traditional “handwritten code” programming languages.)
  2. What are the types of Salesforce Flow, and why use them?
    • Screen
    • Triggered (you’re probably most familiar with record-triggered, but there are others)
    • Autolaunched
  3. What is a Subflow? (Answer: typically, me being too lazy to say “Autolaunched Flow.”)

Touring flow 1 and 2

I started the hands-on demonstration with a tour of 2 existing Flows in a Salesforcescratch org I’d spun up from this codebase:

  1. “demo 1,” a screen flow that lets a human search for an Account record and see a quick summary of facts about it, including a “bonus detail” (which sales representative might be most interested in that Account).
  2. “demo 2,” a record-triggered flow that posts Chatter messages to just-created/edited Account records (tagging the sales representative who would probably be interested in that Account)

When we started, there was a lot of redundancy between the two flows: each Flow had its own copy of a Decision element whose job was to try to figure out which sales representative would be interested in a given Account, based on name and address:

  1. Salesforce user #1/4 watches A-M inside the United States.
  2. Salesforce user #2/4 watches A-M outside of the United States.
  3. Salesforce user #3/4 watches N-Z inside France.
  4. Salesforce user #4/4 watches N-Z outside of France.

A flowchart for this logic woud look roughly like this (ignore the names “Anush,” “Benita,” “Cathy,” & “Darweesh” – I’m lazily recycling a graphic from another post that contains Salesforce usernames that weren’t in this demo):

Flowchart with an A-M vs. N-Z decision followed by an inside vs. outside US decision for A-M and inside vs. outside France decision for N-Z


Refactoring for reusability

“Refactoring” is a fancy word for “editing your old Flows so that what they do doesn’t change, but how they do it incorporates a new technique you learned.”

In this case, we followed the “D.R.Y.” (“Don’t Repeat Yourself”) programming best practice and broke out the overlap between “demo 1” and “demo 2” into a 3rd Flow, “demo 3.” This is also known as thinking about “modularity” in our programming.

Then we edited “demo 1” and “demo 2” to cross-reference “demo 3” and deleted the decision elements out of “demo 1” and “demo 2” altogether.

After validating that “demo 1” and “demo 2” behaved exactly the same as before (even though their Flow Builder elements looked quite trimmed-down), I edited “demo 3” to show how easy life can be when you reuse Autolaunched Flows as Subflow:

  • Edit once, update everywhere!

(My 1 edit to the logic of “demo 3” was instantly reflected in the behavior of both “demo 1” & “demo 2.”)

Melody Lwo said it best at Salesforce Flowsome:

“The most common case (for Subflow) is when you have many flows and in each of them there is the same set of actions, you can make that set of actions into a Subflow so you do not need to create those actions again and again.”

Here are a few hints that it might be time to “D.R.Y.” out your Flows:

  1. You copied and pasted things around a Flow, or between Flows.
  2. You hit save as and based a second Flow off of a first.
  3. Some branches of your decision elements look an awful lot alike.

(I love this 25-color highlighter set for circling sections of Flow screenshots I’ve printed to paper and marking them as possible Subflow candidates.)

Steps:

Create flow 3

I created a new “demo 3” autolaunched flow containing the same decision element that the other two contained.

I created it by saving “demo 2” as a new flow and changing the flow type under the advanced settings, so my next steps will include some deletion of parts.

  1. I added a new Variable-typed resource to it called InputAccount, setting its data type to Record -> Account, and checked the Available for input checkbox under Availability Outside the Flow.
  2. I added a new Variable-typed resource to it called InputFirstHalf, setting its type to Boolean, and checked the Available for input checkbox under Availability Outside the Flow.
  3. I renamed its Variable-typed resource (the one with a data type of Record -> User) from SuggestedUser to OutputSuggestedUser, for clarity, and checked the Available for output checkbox under Availability Outside the Flow.
  4. I changed the A-M/N-Z branch to use InputFirstHalf instead of the old formula-field-typed variable AccountInitialIsFirstHalf that “demo 2” used.
  5. I deleted the old AccountInitial and AccountInitialIsFirstHalf variables that were left over from cloning “demo 2.”
  6. I changed A-M’s inside/outside the US branch to use {!InputAccount.BillingCountryCode} instead of {!Record.BillingCountryCode}.
  7. I changed N-Z’s inside/outside France branch to use {!InputAccount.BillingCountryCode} instead of {!Record.BillingCountryCode}.
  8. I deleted the Chatter-posting element that was left over from cloning “demo 2.”

Then I saved and activated the “demo 3” flow.

(Tip: If I ever think “demo 3” is a little too big, I can totally use Subflow to break it up into even more Autolaunched Flows.)

Edit flow 1 to use flow 3

  1. I inserted a Subflow element into “demo 1” right before the decision element.
  2. I toggled on setting a value for InputAccount in my subflow element and passed it {!GetSelectedAccount}.
  3. I toggled on setting a value for InputFirstHalf in my subflow element and passed it {!AccountInitialIsFirstHalf}.
  4. I toggled on manually saving a value from the subflow’s “OutputSuggestedUser” and said I’d like to save it into {!SuggestedUser}.
  5. I deleted the existing decision element, including all of its branches.
  6. I saved a new version of “demo 1” and activated it.
  7. I ran the “demo 1” screen flow and verified that it still displayed exactly the same information that it used to.

Edit flow 2 to use flow 3

  1. I inserted a Subflow element into “demo 2” right before the decision element.
  2. I toggled on setting a value for InputAccount in my subflow element and passed it {!Record}.
  3. I toggled on setting a value for InputFirstHalf in my subflow element and passed it {!AccountInitialIsFirstHalf}.
  4. I toggled on manually saving a value from the subflow’s “OutputSuggestedUser” and said I’d like to save it into {!SuggestedUser}.
  5. I deleted the existing decision element, including all of its branches.
  6. I saved a new version of “demo 2” and activated it.
  7. I edited an Account record and verified that Chatter messages still posted exactly like they used to.

Edit flow 3 and retest flows 1 and 2

  1. In “demo 3,” I changed N-Z’s inside/outside France branch to be a Japan-oriented branch instead.
  2. I saved and activated a new version of “demo 3.”
  3. I edited the Billing Country Code of an Account record whose name started with “S” and made sure the “demo 1” and “demo 2” Flows still worked as expected, only now branching on inside/outside Japan instead of France.

Intermediate subflow: service flows

I took the “DRY” programming principle even further by showing off the “application service layer” programming best practice.

I edited “demo 3” to be … “service-flavored,” for lack of a better phrase … which made it even more reusable – e.g. with Contact records, not just Account records.

I completely removed all references to the idea of “Account” or “Billing Address” from “demo 3.”

(I also had to make some minor edits to “demo 1” and “demo 2” to make them compatible with the new and improved version of “demo 3.”)

Of course, I validated that “demo 1” and “demo 2” behaved exactly the same as before – it’s always important to “regression test” thoroughly when you “refactor” to make sure you didn’t break anything that used to work.

Then I showed off that I could now create “demo 4,” a record-triggered flow that posts Chatter messages to just-created/edited Contact records (tagging the sales representative who would probably be interested in that Contact).

And, of course, if I edited “demo 3” yet again, the benefit of this extreme reusability offered to me by making my Autolaunched Flow “service-like” is that the updated behavior would be instantly reflected in the behavior of “demo 1,” “demo 2,” and “demo 4.”

  • Edit once, update everywhere! Yay!

(One day, you might feel particularly superpowered as a programmer if an Apex developer writes some code that also uses your service-ified Autolaunched Flow.)

--- ---