Designing Process Builder Criteria to Handle Record Types with Old Data

I haven’t blogged in forever… I have an excuse. Here she is:

DR-82-255.12.full

My beautiful girl, Teagan Elizabeth Goerke

I had to give you all a good reason for being absent for so long. Now that the cute stuff is over, let’s get down to business. Process Builder business that is.

I recently ran into this scenario and you might run into it too. I’ll share how to fix it.

Business Scenario: Old records have no Record Type associated with them but more recent records do have a record type assigned

Error: Process fails with “The flow failed to access the value for [example] because it hasn’t been set or assigned.”

The more relevant error in our scenario is this:

Error element myDecision (FlowDecision).
The flow failed to access the value for myVariable_current.RecordType.Name because it hasn’t been set or assigned.

When records don’t have a record type assigned they technically do. It’s called the Master Record Type and each object gets one when it’s created, even standard objects. You just can’t see it. So, it’s odd that this error would come up with this scenario. I would expect it if we were working with a lookup variable that wasn’t required. But I didn’t expect it for Record Type. But it seems Process Builder can’t see the Master Record Type either. Bummer.

We have two fixes:

  1. Update all our records with a Record Type – Somewhat impractical for some situations
  2. Design our Process Builder to work with blank Record Types – Much more practical

I’ll focus on #2.

You should read this article as it describes the fix: https://help.salesforce.com/articleView?id=Process-fails-with-The-flow-failed-to-access-the-value-for-example-because-it-hasn-t-been-set-or-assigned&language=en_US&type=1

But here’s a walk through:

Screenshot - 8_26_2017 , 7_25_16 AM

No Record Type

Now our Process

In our first design we only accommodate for the Record Type:

Screenshot - 8_26_2017 , 7_29_19 AM.png

But this design will cause errors for blank record types.

A better design is to first check for a blank record type as well as a specific record type. Like this:

Screenshot - 8_26_2017 , 7_32_41 AM

It’s important to note that you should always put the blank Record Type criteria step as always before any additional Record Type criteria evaluation against other values. It doesn’t have to absolutely be first but it needs to be before all the other Record Type references.

As a best practice from a Design perspective, if your Object contains records with blank Record Types then you should build your Processes to accommodate those records or your users will get errors and no one likes flow errors.

WalkMe adds a Free Chrome Extension for the Salesforce Power User

I don’t pitch products on my blog. Or Companies. But if you’re going to release something super useful and make if free then you get a shout out. WalkMe recently released a super useful Chrome Extension called Super Tools (https://supertools.walkme.com/#). I installed it this morning and its already helping me be more productive. There are two features of Super Tools that are key for any Salesforce User but your Power Users will find it most useful.

SuperSearch

This tool takes over the Global Search result and returns a scrollable result page within the Global Search. It also groups by object type and searches Reports!

Image 04-06-2017 06-04-09

SuperSearch – Better

Image 04-06-2017 06-04-10

Standard Global Search – Meh… Ok

SuperEdit

Have you ever exported a report just to make a few changes you didn’t want to do through the UI? Have you ever opened a bunch of tabs off of a report so you could edit the records manually? No more! With SuperEdit you can now inline edit directly in the report.

Image 04-06-2017 06-04-08

I can’t stop myself from making Star Wars references

5 Salesforce Quirks every Salesforce Admin should know – Part 1 0f 5 – Lead Master-Detail Relationships

I wanted to do a series of posts on those quirky things in Salesforce that you run into and when you do you end of doing one of these:

200-1

But, every Salesforce Admin should know about these. In this post, and the next 4, I’ll outline a few quirky features in Salesforce and how to avoid/use them to your benefit. Today, we start with Lead Master-Detail Relationships.

2016-12-31_0637

The long and short of it is that you can’t create a Master-Detail relationship on the Lead Object. If you’re really interested in the documentation that describes this here you go – https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/relationships_among_objects.htm

As always, I encourage you to vote on this Idea – https://success.salesforce.com/ideaView?id=08730000000Bq50

So, Master-Detail Relationships give us some great benefits like the ability to do Roll-Up Summaries for instance. Here’s some work arounds.

  1. Create a lookup field and make the field required
  2. Create a lookup field and use
  3. Create a Many-to-Many relationship via a Junction object
  4. Use an app like Lookup Helper (https://appexchange.salesforce.com/listingDetail?listingId=a0N30000009wj3REAQ) or Roll-Up Helper (https://appexchange.salesforce.com/listingDetail?listingId=a0N30000009i3UpEAI)
  5. Utilize Flow/Process Builder
  6. Apex

The important thing to remember, when you’re planning implementations around Leads you need to consider the Master-Detail Relationship limit in your design.

Multi-Select Picklist Formulas

Business Problem:

Most Salesforce Administrators have run into this issue from one time or another.  A Multi-Select Picklist is not accessible in formulae.  This is frustrating because Multi-Select picklists are great choices for data quality and user experience and it’s not always known at the planning stages that you will need to utilize the field in question for a formula.  
 
Formula Solution:
 

IF(
INCLUDES(Multi_Select_Picklist__c , “A”), “A”,
IF(
INCLUDES(Multi_Select_Picklist__c , “B”), “B”,
IF(
INCLUDES(Multi_Select_Picklist__c , “C”), “C”
, NULL
)
)
)

A while back, Salesforce.com released the use of the INCLUDES()function which is a function that checks a text based value and returns a boolean (true/false) value.  Since the database result of a Multi-Select Picklist is a text based value we can utilize the INCLUDES() function.  By database result, I mean how the value is actually stored in Salesforce.com.  When you save a Multi-Select Picklist it’s values are saved as text with comma’s separating the values you selected.  In the example above, If I selected all the values the value that is stored is actually “A, B, C”

But… what if I select more than one option in my Multi-Select Picklist?  In this case, you must build in each option included in a AND() Function.  Here’s an example:

IF(
AND(
INCLUDES(Multi_Select_Picklist__c , “A”),
INCLUDES(Multi_Select_Picklist__c , “B”)
)
, “A; B”, NULL
)

Using a Picklist in a Validation Rule

Business Problem:

It’s not uncommon for businesses to use picklists to ensure data quality and conformity.  This often comes up when working with Opportunities.  A good example of this is listing the Competitor that you lost a deal to in order to track who your biggest competitor is.
 
Formula Rule Solution:
 

AND(
ISPICKVAL(StageName,”Closed Lost”),
NOT(
ISPICKVAL( Competitor__c, “Competitor_Picklist_Value1”)),
NOT(
ISPICKVAL( Competitor__c, “
Competitor_Picklist_Value2“)),
NOT(
ISPICKVAL( Competitor__c, “
Competitor_Picklist_Value3“)
)
)

Let’s break this validation rule down.  In this rule I am introducing the NOT() function which is a great function for determining is something is NOT true… or false if you are following the logic.  However, the NOT() function only works with one parameter at a time.  Let me explain.

THIS IS POOR SYNTAX:

NOT(
ISPICKVAL( Competitor__c, “Competitor_Picklist_Value1”),
ISPICKVAL( Competitor__c, “Competitor_Picklist_Value2”),
ISPICKVAL( Competitor__c, “Competitor_Picklist_Value3”)

)


The NOT() function will only work with one parameter.

The odd thing here is that if your picklist is actually a multi-select picklist you don’t need all this mumbo-jumbo.  All you need is something that looks like this:

AND(
ISPICKVAL(StageName,”Closed Lost”),
ISBLANK(Competitor__c)
)

Next Birthdate Formula

Business Problem:

Often times businesses will want to track customers/clients birthdays.  However, it’s also nice to know that a birthday is coming up (in the future) instead of just the birthday date. 
 
Formula Rule Solution:

IF(
AND(
MONTH( Birthdate ) >MONTH(TODAY()),
DAY(Birthdate) + 1 > DAY(TODAY())
),
DATE( YEAR(TODAY()), MONTH( Birthdate), DAY(Birthdate)),
DATE( YEAR(TODAY())+1, MONTH( Birthdate), DAY(Birthdate))
)

 
 
* This formula works with any date field but Birthdate is the standard field name on Contacts
** Please note: Person Account fields are not yet available via formula’s so this PersonBirthdate will not work here.

Print the Month based on a Date Field

Business Problem:

Often times you might want to filter a report based on the Month of a specific date or you will need a field to display on a record based on a date field.  This is great for formula concatenations or reporting purposes
Formula Rule Solution:
IF(
Month(datevalue(Any_Date_Field_Here__c)) = 1, “January”,
IF(
Month(datevalue(Any_Date_Field_Here__c)) = 2, “February”,
IF(
Month(datevalue(Any_Date_Field_Here__c)) = 3, “March”,
IF(
Month(datevalue(Any_Date_Field_Here__c)) = 4, “April”,
IF(
Month(datevalue(Any_Date_Field_Here__c)) = 5, “May”,
IF(
Month(datevalue(Any_Date_Field_Here__c)) = 6, “June”,
IF(
Month(datevalue(Any_Date_Field_Here__c)) = 7, “July”,
IF(
Month(datevalue(Any_Date_Field_Here__c)) = 8, “August”,
IF(
Month(datevalue(Any_Date_Field_Here__c)) = 9, “September”,
IF(
Month(datevalue(Any_Date_Field_Here__c)) = 10, “October”,
IF(
Month(datevalue(Any_Date_Field_Here__c)) = 11, “November”,
IF(
Month(datevalue(Any_Date_Field_Here__c)) = 12, “December”,
NULL
))))))))))))
 
This is a relatively simple formula but let’s break this down anyways.  The Month() function takes a date field value and gives you the number representation of that date.  Therefore, if you want to display the actual Month in words you need an additional statement.  The Datevalue() function breaks a date field down further and allows Salesforce to turn the date into a number.  So, when you have the Month(Datevalue()) functions together you can get a Number representation from the Month field.