How I Solved It with Jennifer Lee and Deanne Walters

Clone Object-Based Calendars with Flow While Avoiding Duplicates | How I Solved It

By

Welcome to another “How I Solved It.” In this series, we do a deep dive into a specific business problem and share how one Awesome Admin chose to solve it. Once you learn how they solved their specific problem, you’ll be inspired to try their solution yourself! Watch how Deanne Walters uses Flow to create object-based calendars so everyone can quickly see what campaigns are on the horizon in a dynamic calendar view. As an added bonus, keep watching after Deanne’s demo to see how I turned Deanne’s solution into an agent with Agentforce.


Key business problem

As admins, we often think of information in a record or spreadsheet format. I know end users can vary on how they want to see information displayed, which is why we have nice report charts or dashboards. Have you ever considered displaying data in a calendar format? This helps with scheduling or trying to compare dates, especially dates in a range. Salesforce has a native way to do this with object-based calendars with a key limitation of needing to be manually created by each user until now.

How I solved it

In a happy accident, I realized that what was behind the object-based calendars I had been creating was saved as records in the Calendar object. I then went to my favorite automation tool, Flow Builder, to see if I could get and create Calendar records from it. I could!

Create the object-based calendars

The first step is to create object-based calendars with the user you want to clone the calendars from. I usually do this under my own users as an admin. To do this, go to the Calendar tab.

Calendar page in Month view.

Next, click the gear icon next to My Calendars and select New Calendar.

My Calendars gear clicked to show New Calendar button.

Next, pick which object you want to create a calendar for. In this example, I’m creating one with the Campaign object since it natively has a start and end date field.

First step of the Create Calendar pop-up.]

You start by naming this calendar view. Then, you need to select a date (or date/time field) to be the start date and end date. You should make sure the start date is always before the end date or it will not show on the calendar view. Next, select the field name you want to display for the calendar item. Also, you can optionally filter by a list view.

Second step of the Create Calendar pop-up.

Once created, it will appear on your calendar.

Calendar page with All Active Campaign calendar showing.

Much like your email calendar, you can set different views. If you’re using date fields for your start and end date, I recommend using the Month view. This will give you a cleaner look and will let you see a larger timeframe.

View button clicked to show different calendar views.

Create a screen flow to clone object-based calendars

Here’s an overview of what the screen flow will look like once finished. We’re going to let the users select the calendars they want to add and then dedupe them before creating any new ones.

Completed screen flow.

The key thing that makes this flow work is that object-based calendars are saved into Salesforce as records in the Calendar object. We can access those records in Flow that same way we would for Accounts or Contacts. There is a field called OwnerId on the Calendar object. That field controls who can see the object-based calendars. So, in the clone, we’ll change the OwnerId to the running users so they will be able to see the newly created object-based Calendars.

Now it’s time to start on the screen flow. We’ll need to get existing Calendar records associated with the person who created them because we want to follow Flow best practices and not hard code IDs in our flows. We start with a Get Records element to find the person who created the Calendars. In this example I’m filtering by name, but you can also filter by username or email address.

Flow Get Records element page for user filtering by first and last name.

Next, we need to retrieve the Calendar records from the Calendar object using a Get Records element. Then, filter on OwnerId equals the user you just looked for from the previous step. You also want to make sure ‘All records’ is checked.

Get Records element page for Calendar.

Next, we’ll create a Collection Choice Set for users to select from on the screen. Create a Collection Choice Set resource using the Get Calendars (previous element) in the Collection field. The Choice Label should be Name, and Choice Value should be Id. With this set up, users will see the Name while the backend will be able to access the ID.

Collection Choice Set edit page.

In our Screen element, add an input element for the question and select CalendarChoices for the choice. If you want to let users add multiple calendars, I recommend using a Checkbox Group component.

In my question, I’m asking, “What calendars would you like to add?”, the type is Checkbox Group, and the Choice just has the CalendarChoices choice set.

Screen element with question.

Now, we need to loop through all the records in the collection to get the multiple IDs from a single variable into a calendar collection. This is what it will look like at the end.

Flow canvas with a Loop, Decision, and two Assignments.

The Loop will use the calendar collection from our first Get Records element of the Calendar records. This is because the output from the checkbox group selection is not a collection.

Loop element page.

The first element after the Loop for each record is a Decision element. In this Decision, for the ‘Yes, selected’ outcome, the condition is:

{!What_calendars_would_you_like_to_add}/Calendar Selection > What calendars would you like to add contains {!Check_for_Selected_Calendars.Id}/Current Item from Loop Check for Selected Calendars > Calendar ID

The value is the calendar ID of the current item from the Check for Selected Calendars Loop.

The screen has a list of IDs that are listed one after another in the same variable. So, by checking if it contains each Calendar from the Loop, we can separate out the Calendars that were selected and Calendars that were not selected.

Decision element page with the screen question in the Resource and ID of current item from Loop in Value.

If the calendar was selected, then that outcome should lead to the next Assignment.

There are two updates to make to the Calendar record. The first update is to set the Is Displayed field on the current Loop item to True.

{!Check_for_Selected_Calendars.IsDisplayed}/Current Item (from Loop Check for Selected Calendars > Is Displayed) equals True

When this is set and users go to the Calendar tab, the new Calendars automatically show up. This is optional but does make for a smoother experience for the end user.

The second update is to set the owner field on the current Loop item to the running user.

{!Check_for_Selected_Calendars.OwnerId} (that is, Loop Check for Selected Calendars > Owner ID) equals {!$User.Id} (that is, Running User > Id)

This is what controls whose view the calendar is available for.

Assignment element with above assignments.

Before the next step, we need to create a new variable. The name of the variable is CalendarCreationCollection. The data type is Record. The Object is Calendar. Allow multiple values is true.

Edit view of CalendarCreationCollection variable.

After your last Assignment, you need another Assignment element to add the current item in Loop to the Calendar record collection, so it should look like this:

CalendarCreationCollection Add {!Check_for_Selected_Calendars} (that is, Current Item from Loop Check for Selected Calendars)

Assignment element with above assignments.

While you could just create the calendars from here, users could go through this flow multiple times and end up with duplicate calendars. To prevent this, consider adding a duplicate check here. In this case, we’re deduping on the calendar name.

The first step is to get all of the calendars that the running user currently has using a Get Records. The object should be Calendar, filter on OwnerId equals the running user’s ID, and make sure to store all records.

Flow Get Records element for Calendar filtering on OwnerId.

This what the deduplication Loop will look like. It is a Loop within a Loop because you need to compare each calendar the running user already has with the calendars that were added to the creation collection.

Flow canvas with a Loop, Decision, and two Assignments.

The first Loop you’re creating is one that uses the collection variable that you just got in the Get Current Calendars Get Records element with the current users’ calendars.

Loop element page named Look for Duplicate Names with Calendars from Get Current Calendars in Collection variable.

Directly after that, add another Loop element with the calendar creation collection.

Loop element page named Compare Existing Calendars to New Calendars with CalendarCreationCollection in Collection variable.

Now for the comparison. Use a Decision element to determine whether the calendar name matches. For the ‘Yes, Matches’ outcome, the resource is the current Loop item for the Loop. Look for Duplicate Names > Calendar Name matches the current Loop item for the Loop Compare Existing Calendars to New Calendars.

Current Item from Loop Look for Duplicate Names > Calendar Name Equals Current Item from Loop Compare Existing Calendars to New Calendars > Calendar Name

Make sure to not accidentally put the same current item under both Resource and Value.

Decision element page with outcome ‘Yes, Matches’ with the operator as equals.

If the decision is true and the calendar names did match, then use an Assignment element to remove the current item from the Compare Existing Calendars to New Calendars Loop from the calendar creation collection /Current Item from Loop Compare Existing Calendars to New Calendars.

It should look like this:

CalendarCreationCollection Remove All {!Compare_Existing_Calendars_to_New_Calendars} (that is, Current Item from Loop Compare Existing Calendars to New Calendars)

There are a variety of Remove operators you could use. In this example, I used Remove All in case it had somehow been added multiple times.

Assign with variable is CalendarCreationCollection, operator is Remove All, and Value is Current Item from Compare Existing Calendars to New Calendars Loop.

Once both of those Loops are complete, the CalendarCreationCollection is now deduped. Add a Create Records elements to create the records in the CalendarCreationCollection.

Create Records element.

Now for the final element. Use a Screen element to direct the users to the Calendar tab. The message I have is “Click here to see your new calendars!” This way, the end users can simply click the hyperlink here and get to the Calendar tab.

Screen element with display text component.

I like to build my hyperlinks in formulas because then I can have a mix of hard-coded and dynamic elements. Also, when linking from within Salesforce, you don’t have to specify the domain, which means your links will work in both the sandbox and production.

The formula is:

/lightning/o/Event/home?startDate="&TEXT({!$Flow.CurrentDate})&"view=month

This formula will take the end user to not only the Calendar tab but also to today’s date and put the calendar view in Month for them.

Flow formula editor with the Data Type as text.

To add this as a hyperlink, click the hyperlink button, and then in the Link URL, enter the merge code for the formula.

Display text component with hyperlink editor up with Link Title as ‘here’ and Link URL as {!FinalURL}.

Since you can’t add custom buttons to the Calendar page, think about where to put it for easy access. In this example, I created a Lightning page called Add Calendars and placed the screen flow there.

Frontend Lightning page with title Add Calendars and embedded Clone Calendars screen flow.

Business results

I have seen hours of manual work put into taking data out of Salesforce and putting it into another tool to get a calendar view. This setup completely removes the need for that manual work, saving hours of staff time each week, and also is automatically up to date. It also lets end users do self service and get their own information without admin assistance.

Do try this at home

I used Campaigns because they have a start and end date, but you can use pretty much any other object you have in your org. If you only have one date field, set the start and end date to use the same field. Let your (or your end user’s) imagination go wild on what they want to see in a calendar view.

Intimidated by Loops? Check out the resources below. Also, you can simplify this to just letting people select one calendar and then check if they already have that one calendar before creating the one Calendar record, and you can completely get rid of the need for Loops.

Resources

 

Want to see more good stuff? Subscribe to our channel!

SUBSCRIBE TODAY
How I Solved It with Jennifer Lee and Dee Ervin

Search Unsearchable Field Data Types | How I Solved It

Welcome to another “How I Solved It.” In this series, we do a deep dive into a specific business problem and share how one Awesome Admin chose to solve it. Once you learn how they solved their specific problem, you’ll be inspired to try their solution yourself! Watch how Dee Ervin searched unsearchable field data […]

READ MORE