Cool Links & Stuff
Links to trailhead, blogs, resources... anything we find useful
- Salesforce Architecture resources
- Trailheads we like
- Cool Links
- Official Salesforce Customer For Life Scoping Questionnaire
- The official Salesforce Sandbox Preview Checker
- The Salesforce Lightning Object Creator (is broken to hell)
- Salesforce Optimizer
- Order of Execution (by Alexd0t)
- How to check off records on a list view and pass them all to a Flow (button)
- How to get the current org's domain in a flow
- How to check if user is in Classic or LEX in a formula field!
- Find records MUCH faster with these tricks!
- Salesforce Demo Orgs
- Awesome Admin Soundcloud Link
- Passing a list of Ids to a Flow from a related list in LEX
- SSO and OAuth 2.0 Flows for Salesforce
- How to roll your own "ISCHANGED", "PRIORVALUE", and "ISNEW" in before-save flows
- How to check if user is in Classic or LEX in a formula field!
- SOQL and SOSL Reference
- [ADMIN] - How to Delete Multiple Records Without Apex Code in Salesforce
Salesforce Architecture resources
Official Salesforce Docs
Undesrstanding the multinenant Architecture
https://www.developerforce.com/media/ForcedotcomBookLibrary/Force.com_Multitenancy_WP_101508.pdf
The architecture Resources page
Probably my favourite page in the Salesforce Help system. Links to trailhead,s whitepapers, and much more.
https://architect.salesforce.com
The CTA Journey doc
Here to give you an overview of how to aim for being a CTA. Some nice tips here and there
Tech design Articles
How to decided for specific streaming events depending on your objective and architecture.
https://developer.salesforce.com/blogs/2018/07/which-streaming-event-do-i-use.html
External Links
The TOGAF 9 cert
Is a nice non-SAlesforce way to get into architecture. Has its own studies, etc, but is focused on general systems design and architecture concerns.
Useful Blogs Posts
Archladies is a nice resource for anyone looking to see how to get to CTA.
Trailheads we like
Basic Trailheads
Consultant:
https://trailhead.salesforce.com/en/content/learn/modules/consulting_partner_basics
BA:
https://trailhead.salesforce.com/en/content/learn/trails/force_com_admin_beginner
https://trailhead.salesforce.com/en/content/learn/trails/force_com_admin_intermediate
https://trailhead.salesforce.com/en/content/learn/trails/force_com_admin_advanced
https://trailhead.salesforce.com/content/learn/projects/customize-a-salesforce-object
https://trailhead.salesforce.com/content/learn/projects/build-a-simple-flow
More advanced BA:
https://trailhead.salesforce.com/en/content/learn/superbadges/superbadge_lex
https://trailhead.salesforce.com/en/content/learn/superbadges/superbadge_process_automation
https://trailhead.salesforce.com/en/content/learn/superbadges/superbadge-service-cloud-admin-specialist
Really advanced BA:
https://trailhead.salesforce.com/en/content/learn/modules/big-data-strategy
Developer:
https://trailhead.salesforce.com/en/content/learn/superbadges/superbadge_apex
https://trailhead.salesforce.com/en/content/learn/modules/apex_patterns_sl
https://trailhead.salesforce.com/en/content/learn/modules/apex_patterns_dsl
Cool Links
Name | Link |
David Liu's training course | https://bit.ly/go-apex |
Alex Edelstein's Unofficial SF, rich in Flow goodness |
|
Open Force, the other opensource SF repo | https://www.open-force.org/ |
SFXD github | https://sfxd.github.com |
Tsalb's awesome LWC utils | https://github.com/tsalb/lwc-utils |
Custom Report Type Stuff | https://admin.salesforce.com/ultimate-guide-report-types |
Lightning Migration story and examples | https://medium.com/@jason.mclain/a-salesforce-lightning-migration-24e9a7f8719 |
Justin Lyon's (jlyon11) personal org - Sample LWCs and Aura Components | https://github.com/jlyon87/jml-dx-box |
Official Salesforce Customer For Life Scoping Questionnaire
Attached to the article is the old (but still valuable) CFL scoping questionnaire. (Attachments are top left of the article)
The purpose of the document is to capture the Customer’s high-level business overview and intended usage of Salesforce.com so that Partner can quickly and accurately attain implementation scope for delivery of a Statement Of Work (SOW).
The official Salesforce Sandbox Preview Checker
https://sandbox-preview.herokuapp.com/
Are you taking advantage of the Sandbox Preview window to test, catch, and report bugs before they bite? Enter your Sandbox instance below to determine what needs to be done, based on what instance your sandbox org is currently on.
The Salesforce Lightning Object Creator (is broken to hell)
Lightning Object Creator is completely broken and currently just can't be used.
https://object-creator.salesforce.com/
Salesforce Optimizer
Salesforce is an incredibly powerful tool, but as veteran admins know, maintaining a suite of features across your org can be cumbersome. Salesforce Optimizer takes the guesswork out of how to best maintain features so that they can be enhanced to help your users get work done.
The app presents the recommendations in a more interactive and actionable format. Unlike the PDF report, you can sort and filter the features included in Salesforce Optimizer by impact and estimated effort time on the Results tab. Zero in on optimizations that you can handle quickly or the tasks that are high-priority and need to be tackled first.
The feature page includes historical trending graphs or a data list containing the data to review.
https://appexchange.salesforce.com/appxListingDetail?listingId=a0N3A00000FMczdUAD
Order of Execution (by Alexd0t)
PDF version attached to this article (top left of the screen)
How to check off records on a list view and pass them all to a Flow (button)
Flow Actions are really useful! However, they aren't available everywhere. This article will tell you how to place a flow button on a list view or related list, and pass into the flow the ids of the selected records so you can use and act on them.
How to set it up:
The first step is to build your flow. Within the flow, create a variable called "ids" without the quotes (warning: it's case sensitive). This variable should be a Text variable which allows multiple values, and should have Available for Input selected. If you do this, the variable will be populated with the list of ids of the records that you selected on your list view.
Now you will probably want to act on those records, which means you'll need a Record Collection variable. Until recently, you'd need to use invokable apex to fetch a Record Collection without querying inside a loop. But now we have a new IN operator which you can use inside a Get Records, like this:
Make sure to store ALL the matching records.
Building the Flow:
Here is an example flow I set up with this method. The flow updates the Owner of the selected Contacts.
First I show a list of Users to choose from.
Then we use a Get Records (screenshot above) to fetch all the contacts which were selected in the list view - their ids are automatically stored in the ids
variable.
After that, we loop through the contacts, update each contact's owner to the one selected in the first step, add the contact to a new collection variable, and when the loop is done, Update Records with that new collection variable to send our changes to the database.
(Note: if you'd like, you can replace the entire loop with a Map Collection action from unofficiasf.com)
Setting up your button:
To set up this button, visit Object Manager and find the object you're using (in the above example, Contacts).
Enter this URL for the Content Source:
/flow/Contacts_List_Mass_Change_Owner?retURL=003/o
(Change it to match the url of your flow, which you can get from the View Details and Versions page). You can leave out the ?retURL=003/o
part, I'll explain it later.
Or, you can add it to Related List view by editing the page layout of the parent object (for example: Accounts). You'll need to click the wrench icon to edit the related list, and the button should be available to be added there.
Configuring the flow finish behavior:
One caveat with launching a flow from a url button (as opposed to a Flow Action) is that the flow does not launch in a modal, instead, it replaces the page you are looking at. This means that you will need to manually set your flow's finish location or it will loop back to the beginning of the flow when it's done (which might cause an error and will definitely cause confusion).
You can set the flow return url via retURL in your custom button (to hardcode a specific URL). Usually you'd use that to redirect to an object's home page, or to a specific record (ie: if the button was placed on a record page). The code posted above (?retURL=003/o
) would take you to the Contacts home page when the flow finished. However, if your button is on a list view, those options are less useful.
I was therefore seeking a way to direct the user back to the list view they were looking at. For a while it seemed impossible, but eventually (after a lot of googling) I found a way to write a Visualforce page which, upon load, simply redirects to the list view you were looking at most recently for that object. (This should most often be the list view you clicked the button from, but your results may vary if you've been multitasking in different tabs.)
You will need to create a Visualforce page for each object you want to use this for, but you can reuse the pages between multiple buttons. Here's the page I created for Contacts:
<apex:page standardController="Contact" recordSetVar="contacts" action="{!list}">
</apex:page>
Overwhelming, right? Well, all you need to do is copy/paste that code into a new Visualforce page in Dev Console, and if you're not doing this for Contacts, change the two references to the object name. I called my page ContactLastListView.
Now we'll go back to our button and set its retURL (or place to go when finished) to that page. Like this:
/flow/Contacts_List_Mass_Change_Owner?retURL=apex/ContactLastListView
Alternatively, if you are putting this button on a related list, you'll probably want to navigate back to the record you were looking at. You can do this by setting the retURL of your button to the id of the parent record, like this:
/flow/Contacts_List_Mass_Change_Owner?retURL=/{!Account.Id}
Now don't forget to test your flow button and make sure it works as intended!
Credits to @Hz and @ric_hoo for their help with figuring this all out.
How to get the current org's domain in a flow
LEFT($Api.Partner_Server_URL_470, FIND( '/services', $Api.Partner_Server_URL_470))
https://customer-customization-9925.cs2.my.salesforce.com/
URLHow to check if user is in Classic or LEX in a formula field!
=IF($User.UIThemeDisplayed = "Theme4d","LEX","Classic")
Find records MUCH faster with these tricks!
Here are some neat tricks to help you [impress your coworkers and] navigate to records much faster
Chrome users: Create custom search engines that you can access with keywords.
If you follow the below instructions, you'll be able to do either of these from the Chrome search bar:
- Type 'sf', press TAB, type the name of a record or anything you want to use to search for it, and press ENTER. You will be taken directly to search results.
- Type 'id', press TAB, type (or paste, more likely) the ID of any record, and press ENTER. You will be taken directly to the record.
Instructions (and you can modify the kewords if you'd like):
- Click the three vertical dots in the top right corner
- Click Settings
- Scroll down to Search Engines and click 'Manage search engines'
- Click Add
- We recommend adding two search engines
- Search Engine Title: Salesforce
Keyword: SF
URL: https://mydomain.my.salesforce.com/_ui/search/ui/UnifiedSearchResults?str=%s&searchAll=true - Search Engine Title: Salesforce ID
Keyword: ID
URL: http://mydomain.my.salesforce.com/%s
- Search Engine Title: Salesforce
- (In both, replace 'mydomain' with your actual my domain. If you don't have My Domain set up, replace 'mydomain.my' with 'login'.)
NOTE: the first search engine listed in Step 5 takes you to search results in Classic. If anyone figures out how to do this in LEX, just ping @solo admin and I'll [be eternally grateful and] update it here.
UPDATE 3/23/2021: Thanks @Sylvoka for finding this article with instructions on how to do this in LEX: https://sfdad4tec.medium.com/salesforce-lightning-global-search-in-chrome-url-address-bar-8aebd3175ef9. It works perfectly!
Quickly navigate to a record from anywhere on your (Windows) computer with Autohotkey!
Autohotkey is a scripting language that lets you write scripts that can run in the background, until you press a key combination that you have set up, and then boom! It does something cool.
I wrote a script that runs when you press control-shift-2 (you can change that to anything you want). I first copy any record's ID to the clipboard, and then press control-shift-2, and it opens that record as a new tab in whichever browser window you were in most recently.
Here is the script:
^+2::
clp := clipboard
url := "http:\\mydomain.my.salesforce.com/" . clp
Run, %url%
- Install AutoHotKey (https://www.autohotkey.com/ . Click Download and follow the prompts)
- Create a new text file using your favorite text editor.
- Copy and paste the script into the file (change the word 'mydomain' to your actual my domain. If you don't have My Domain set up, replace 'mydomain.my' with 'login'.)
- Save the file with a .ahk file extension
- To set this script to always run in the background, press win-r (the Windows key and the letter r at the same time) and type shell:startup. In the folder that opens up, create a shortcut to the ahk file you created in steps 2-4.
- Here comes the fun. From a report, from excel, from an email, from anywhere... find a record's ID and copy it. Press control-shift-2 and bam!
- If you want to modify the keyboard shortcut for this script, you would change that in line 1. See this link for more info: https://www.autohotkey.com/docs/Hotkeys.htm . (tl;dr: ^ means control, + means shift, ! means alt, # means windows key)
Search from Salesforce Navigator Chrome Extension
- If you already have the Salesforce Navigator extension installed (and you should!), you can get to search results easily without much setup required
- Assuming you have the extension mapped to the control-shift-space shortcut (if not, click here to set that up: chrome://extensions/shortcuts), when you are in any Salesforce tab, just press control-shift-space, type a question mark (?), and then type whatever you want to search for. Press enter (or control-enter to open the results in a new tab).
- This works even in LEX!
- To install the extension:
Classic version: https://chrome.google.com/webstore/detail/salesforce-navigator/ecjmdlggbilopfkkhggmgebbmbiklcdo?hl=en
LEX version: https://chrome.google.com/webstore/detail/salesforce-navigator-for/pbjjdhghffpemcglcadejmkcpnpmlklh?hl=en - Salesforce Navigator also helps you get to almost any page in setup with the wave of a magic wand (kind of)
Salesforce Demo Orgs
This contains a list of signup links for demo orgs depending on which cloud you want to learn.
Most of these can be found via Google, but I guess centralizing them here is easier.
Basic Developer Org
https://developer.salesforce.com/signup?d=70130000000td6N
Financial Services Cloud
https://developer.salesforce.com/promotions/orgs/fscplayground
CloudCraze / B2C Commerce
This one will require you to butter up your AE to get a test license.
NPSP Trail
https://www.salesforce.org/trial/nonprofit-ee/
Retail Cloud
Unobtainable outside of SDO for now.
Awesome Admin Soundcloud Link
... Technically this is a Salesforce link so I'll leave it here.
If you're following this link and listening to this
I AM SO SORRY.
Passing a list of Ids to a Flow from a related list in LEX
Source: https://www.xbaf.com/flow-list-buttons
Submitting multiple records to Flows
“How do I submit multiple records into my process?”
This sounds like an obvious job for Flow and a List Custom Button, right? We open the list view, tick a few checkboxes, click the list button… but quickly find the Selected Record IDs are nowhere to be found in Flow.
There are a few workarounds to inject the checked rows:
- Use code or a package to run the flow as a batch process
- Add a custom field and use mass edits to invoke process builder
- Create a VF page with
apex:interview
to inject the selected records - Use GETRECORDIDS in a JavaScript custom button (alarm bells ringing…)
Here’s an easier way to access Selected Record IDs
After clicking multiple checkboxes in any list view, the selected records are accessible – the key is to launch the Flow using its URL in the button content:
Then, configure the ‘Nudge Owner’ flow so the posted IDs are received:
- Create a new Collection Variable resource
- Enter the Unique Name called
ids
- Set the Type to
Input Only
When configured correctly, Salesforce automatically populates the collection variable with the IDs of the selected checkboxes. Now we can loop over the collection variable and perform business logic.
Note:
- This parameter isn’t documented anywhere.
- The name of the
ids
collection variable is case sensitive. - Remember to “close the loop” otherwise only the first ID is handled by Flow.
The same technique works on Detail Page Buttons: if an id
variable exists in the flow, it is automatically populated with the current Record ID context. For want of a better term, these “standard parameters” act the same as standard controllers:
Mass flow actions can be bulkified too, they need not be limited by iterations of the loop element. Plugins using the @InvocableMethod
annotation do support collection variables – the ids
list can be passed straight in.
Benefits of standard flow parameters
Standard flow parameters eliminate the need for Visualforce Pages to arrange input records. They behave like an interface contract. ISVs can automatically deploy surgical, self-contained customizations more easily with the Metadata API. Further:
- Avoiding the VF page also avoids any need to modify Profiles.
- Using URL custom buttons avoids hard dependencies on packaged Flows.
- Documentation isn’t required to explain how to set context sensitive inputs.
True, distributing flows using Visualforce Pages offers more granular access control since the entry point is restricted by its associated page – this is applicable in sites and communities or portals.
Otherwise, any reason not to do this?
Update: vote for official support! Idea: support standard id/ids flow variables
https://www.xbaf.com/flow-list-buttons
SSO and OAuth 2.0 Flows for Salesforce
With a lot of examples:
https://www.lucidchart.com/documents/view/61d9b688-5613-4823-8aae-fb3bfe7103d8/n0zg1RAWc2Bh
How to roll your own "ISCHANGED", "PRIORVALUE", and "ISNEW" in before-save flows
How to roll your own "ISNEW", "ISCHANGED", and "PRIORVALUE", and in before-save record-edit flows
UPDATE: As of Summer 21, all of this can be done natively, and will perform better since it doesn't require any extra queries.
To check ISNEW(), simply check if the $Record__prior variable is null.
Archive:
Record Edit flows are pretty cool, and will hopefully replace PB altogether.
There are a few features still missing, and included in those are ways to check if a record is new, if a field was changed, and what the previous value is.
Until they are added in for real, here are some tricks to build it yourself.
For a little background - these flows will automatically contain a variable called $Record, which refers to the record that was created/modified thereby calling the flow. You can access any of the record's fields via $Record.FieldName.
ISNEW()
To tell if the record is new (ie: was just created and not yet saved), you simply need to check in your flow if the ID field is null. You'd do this either in a formula or in a decision by checking $Record.Id.
ISCHANGED()
To check if a specific field was changed, you'll want to do a Get Records. Fetch the record whose Id matches $Record.Id and store it in a record variable. Then you can use a decision to check if any field in your record variable is the same as the same field in the $Record variable. For example, check if $Record.Name = AccountRecord.Name. If they match, it means the field has not been changed.
PRIORVALUE()
The method for PRIORVALUE() is very similar to that of ISCHANGED(). You'll just want to check what value is in the field from your Get Records variable.
DISCLAIMER:
These tricks only seems to work in "before-save" flows, since a record that wasn't ever "saved" doesn't have an Id, and if it's an existing record, the database still stores old values. If someone figures out tricks for these please ping @solo-admin.
How to check if user is in Classic or LEX in a formula field!
=IF($User.UIThemeDisplayed = "Theme4d","LEX","Classic")
SOQL and SOSL Reference
[ADMIN] - How to Delete Multiple Records Without Apex Code in Salesforce
Resource Link:
https://webkul.com/blog/delete-multiple-records-without-apex-code-in-salesforce/
Explanation:
This link is a resource that will help you with mass deleting records without needing to use Apex Code. Making it easier for you to delete unnecessary data within your org.