Professional Documents
Culture Documents
Salesforce
Salesforce
#salesforce
Table of Contents
About 1
Remarks 2
Examples 2
Installation or Setup 2
Salesforce Products 2
Sales Cloud 2
Service Cloud 2
Marketing Cloud 2
Community Cloud 2
App Cloud 3
IoT Cloud 3
Health Cloud 3
Heroku 3
Examples 4
Assert Methods 4
Using testSetup 5
Assertion Methods 6
Syntax 7
Parameters 7
Examples 7
Basic trigger 7
Remarks 10
Examples 11
ProcessDefinition 11
ProcessNode 12
ProcessInstance 12
ProcessInstanceHistory* 13
Remarks 14
Introduction 14
Examples 15
Creation 15
Management 15
Custom Setting 16
Validation Rule 18
Workflow Rules 19
Explanation 19
Apex Class 19
Unit Test 19
Examples 26
Introduction 27
Examples 27
UserInfo 27
Examples 28
$Resource 28
$Label 28
$User 28
Chapter 9: Page Navigation with help of list wrapper class in sales force. 29
Introduction 29
Examples 29
Pagination Controller 29
Introduction 33
Examples 33
Syntax 34
Examples 34
Using a Semi-Join 37
Dynamic SOQL 37
Examples 38
Examples 39
IDEs 39
Browser extensions 39
Debuggers 39
Examples 41
Bulkification 41
Examples 42
Basic page 42
Examples 43
Credits 44
About
You can share this PDF with anyone you feel could benefit from it, downloaded the latest version
from: salesforce
It is an unofficial and free Salesforce ebook created for educational purposes. All the content is
extracted from Stack Overflow Documentation, which is written by many hardworking individuals at
Stack Overflow. It is neither affiliated with Stack Overflow nor official Salesforce.
The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.
Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to [email protected]
https://riptutorial.com/ 1
Chapter 1: Getting started with Salesforce
Remarks
This section provides an overview of what salesforce is, and why a developer might want to use it.
It should also mention any large subjects within salesforce, and link out to the related topics. Since
the Documentation for salesforce is new, you may need to create initial versions of those related
topics.
Examples
Installation or Setup
The best way to get started with Salesforce is to get your own Developer Edition.
Salesforce Products
The Salesforce application consists of several products which can be integrated with each other:
Sales Cloud
Marketing Page, Salesforce Documentation
Service Cloud
Marketing Page, Salesforce Documentation, Trailhead
Marketing Cloud
Marketing Page
Community Cloud
Marketing Page, Salesforce Documentation
https://riptutorial.com/ 2
Marketing Page, Salesforce Documentation, Trailhead
App Cloud
Marketing Page
IoT Cloud
Marketing Page
Health Cloud
Marketing Page, Salesforce Documentation
Heroku
Marketing Page
https://riptutorial.com/ 3
Chapter 2: Apex Testing
Examples
Assert Methods
delete allContacts;
allContacts = [SELECT Id FROM Contact];
System.assertEquals(0, allContacts.size());
}
This test class will test the IsBlank(...) method of SomeClass. Below is the example SomeClass. This
class has only the one, basic static method, but you will be unable to deploy it to a production
instance for use until you have reached the code coverage threshold.
As one can see, this method is simply a if statement with three branches. To write an effective
test class, we must cover each branch with code, and use System.assertEquals(...) statements to
verify that the proper data was received from IsBlank(...).
@isTest
public class SomeClass_test {
@isTest
public static void SomeClass_IsBlank_test() {
String testData;
https://riptutorial.com/ 4
// SomeClass.IsBlank() returns true for Null values
System.assertEquals(true, SomeClass.IsBlank(testData));
testData = '';
testData = 'someData';
Using testSetup
You can use a method annotated with @testSetup to write code that will have been executed before
each test run:
@isTest
public class AccountServiceTest {
private static final String TEST_ACCOUNT_NAME = 'My Test Account';
@testSetup
public static void setUpAccountData() {
Account a = new Account(Name = TEST_ACCOUNT_NAME);
}
@isTest
public static void testFetchAccount() {
Account a = AccountService.fetchAccount();
System.assertNotEquals(null, a, 'Account should not be null');
System.assertEquals(TEST_ACCOUNT_NAME, a.Name, 'Account name should be correct');
}
}
While you can use the @testSetup annotation to designate a method to be run before tests are
executed, this method will usually only be run once. If you need code to be run before each test,
you can use a static block:
@isTest
public class MyTest {
static {
https://riptutorial.com/ 5
// code here will be run before each test is executed
}
}
Assertion Methods
System.assert(Service.isActive());
System.assert(!Service.getItems().isEmpty(), 'items should not be empty');
System.assertEquals(4, Service.getItems().size());
System.assertNotEquals(null, Service.getItems());
https://riptutorial.com/ 6
Chapter 3: Apex Triggers
Syntax
• trigger <name> on <object-api-name> (<events>) { // your trigger logic }
Parameters
parameter description
object-api-
Object on which the trigger will fire. Can be any standard or custom object.
name
Events which will fire the trigger. Are a combination of either before/after with
events any of insert/update/delete. There's also after undelete without before
counterpart.
Examples
Basic trigger
https://riptutorial.com/ 7
/** Records on Trigger execution **/
//Returns data in state before DML. Records are read only
//Not available for Insert Operation
//Format: List<sObject>
List<Contact> old_contacts = Trigger.old;
System.debug('Trigger:Data:Old : ' + old_contacts);
//Returns data in state before DML. Records are read only
//Not available for Insert Operation
//Format: Map<Id, sObject>
Map<Id, Contact> old_contacts_map = Trigger.oldMap;
System.debug('Trigger:Data:OldMap : ' + old_contacts_map);
//Returns data in state after DML.
//Allowed for modifications in before context only
//Not available for Delete Operation
//Format: List<sObject>
List<Contact> new_contacts = Trigger.new;
System.debug('Trigger:Data:New : ' + new_contacts);
//Returns data in after before DML.
//Allowed for modifications in before context only
//Not available for InsertOperation
//Format: Map<Id, sObject>
Map<Id, Contact> new_contacts_map = Trigger.newMap;
System.debug('Trigger:Data:NewMap : ' + new_contacts_map);
https://riptutorial.com/ 8
}
}
}
}
https://riptutorial.com/ 9
Chapter 4: Approval Process Objects
Remarks
Approval Process is a very amazing feature in Salesforce to automate the business process. An
approval process is a set of the steps necessary for a particular record to be approved or rejected
by approver or set of approvers.
A step can apply to all records included in the process, or just records that meet certain
administrator-defined criteria. An approval process also specifies the actions to take when a
record is approved, rejected, recalled, or first submitted for approval.
ProcessDefinition and ProcessNode objects act as a template and store the master
configurations for Approval Process itself.
https://riptutorial.com/ 10
Examples
ProcessDefinition
Represents the definition of a single approval process. Use this object to read the description of an
approval process. The definition is read-only. We can not modify the record created in
ProcessDefinition Object. But we can describe, query, search and retrieve the approval processes
information.
~ Query ~
SELECT CreatedById,CreatedDate,Description,DeveloperName,LastModifiedById,
LastModifiedDate,LockType,Name,State,SystemModstamp,TableEnumOrId,Type,Id
https://riptutorial.com/ 11
FROM ProcessDefinition
The records are created when we create a new approval process using Salesforce user interface
of Approval Process.
ProcessNode
Represents the Process Steps created for particular approval process(ProcessDefinition). This
object is used to read the description of process step. In simple words ProcessNode records
describes a step in a process definition. We can describe, query, search and retrieve the approval
processes Steps.
~ Query ~
SELECT Description,DeveloperName,Name,ProcessDefinitionId,SystemModstamp
,Id,FROM ProcessNode
As we can see ProcessDefinitionId field is acting like a foreign key which is referring
ProcessDefinition Object or Table for which steps or process nodes are created. This object is
also read only as ProcessDefinition Object.
ProcessInstance
~ Query ~
SELECT CompletedDate,CreatedById,CreatedDate,ElapsedTimeInDays,
ElapsedTimeInHours,ElapsedTimeInMinutes,Id,IsDeleted,LastActorId,
LastModifiedById,LastModifiedDate,ProcessDefinitionId,Status,
SubmittedById,SystemModstamp,TargetObjectId FROM ProcessInstance
All ProcessInstance fields are automatically populated once the record is submitted for approval,
with two exceptions fields: CompletedDate and LastActorId that are populated only after the
approval process instance is complete. The ProcessDefinitionId field is the reference or foreign
key ID of the ProcessDefinition Object.
https://riptutorial.com/ 12
~ Query ~
SELECT CreatedById,CreatedDate,ElapsedTimeInDays,ElapsedTimeInHours,
ElapsedTimeInMinutes,Id,IsDeleted,OriginalActorId,ProcessInstanceId,
ActorId,SystemModstamp FROM ProcessInstanceWorkitem
SELECT ActorId,Comments,CreatedById,CreatedDate,ElapsedTimeInDays,Id,
ElapsedTimeInHours,ElapsedTimeInMinutes,OriginalActorId,ProcessInstanceId
,StepNodeId,StepStatus,SystemModstamp FROM ProcessInstanceStep
ProcessInstanceHistory*
The ProcessInstanceHistory is the object which is neither searchable nor queryable & this is the
read-only object which shows all steps and pending approval requests associated with an
approval process (ProcessInstance). But we can use this object to replicate the related list
functionality of the Salesforce user interface for approval processes which will be shown in my
next blog post soon. We can use ProcessInstanceHistory for a single read-only view of the both
ProcessInstanceStep and ProcessInstanceWorkitem objects. We can query
ProcessInstanceHistory by querying it in a nested soql query on the parent ProcessInstance
object. The nested soql query references StepsAndWorkitems, which is the child relationship
name for ProcessInstanceHistory in the ProcessInstance object. This is very useful object to solve
various business problems.
~ Query ~
https://riptutorial.com/ 13
Chapter 5: Custom Settings
Remarks
Introduction
Unlike custom objects which have records based on them, custom settings let you utilize custom
data sets across your org, or distinguish particular users or profiles based on custom criteria. This
means, for example, that admins can edit hierarchy custom settings to deactivate Workflow /
Validation Rules for single users or profiles, without having to switch them off for the whole org
(see the Using Hierarchy Custom Settings To Disable Workflow / Validation Rules example
above).
• Code is updating old records, which were last edited before a validation rule was activated &
therefore don't meet the newer rule's criteria.
• Code is inserting new records without the values required by a validation rule's criteria.
• They would trigger an Email Alert or Field Update which would overwrite or interfere the
changes you are making to the record.
Use of a custom setting grants admins some declarative control over code so one of the many use
cases is that when utilized, they can make it unnecessary to deploy code in order to disable
triggers (see the Using Hierarchy Custom Settings To Disable Apex Code example above).
A key benefit for developers is that custom setting's data is exposed in the application cache,
which enables efficient access without the cost of repeated queries to the database. This data can
then be used by formula fields, validation rules, flows, Apex, and the SOAP API - see the
Salesforce documentation.
The limits & considerations for custom settings are documented here.
When you go to create a new Custom Setting, the following message will be displayed
https://riptutorial.com/ 14
types using using packages or Metadata API tools.
Custom Metadata Types have additional benefits vs List Custom Settings as described in this
answer. And according to the lead developer of CMDs "There’s a lot more planned for custom
metadata types than custom settings on steroids."
Examples
Creating & Managing Custom Settings
Creation
To create a Custom Setting, go to:
Classic
Setup > Develop > Custom Settings > New
Lightning
Setup > Custom Code > Custom Settings > New
Create your setting (see the Remarks later in this document for the differences between Hierarchy
& List custom settings). You can ignore the Visibility picklist, unless you plan to deploy your setting
in a managed package.
To create your setting fields click the New button and follow the usual process for creating a
custom field.
Management
Once you have created your field(s) you can start configuring the setting by clicking the Manage
button.
It's easier to manage the setting if you create a new view and include any fields that you've
created to give yourself a comprehensive overview of the setting, at a glance. The Setup Owner is
the user or profile that the setting applies to.
To manage the setting at the org level, click the New button above the Default Organization Level
Value header (in red box below).
To manage the setting at the user or profile level, click the New button in the blue box below.
https://riptutorial.com/ 15
Using Hierarchy Custom Settings To Disable Workflow / Validation Rules
Custom Setting
https://riptutorial.com/ 16
Custom Setting Field
https://riptutorial.com/ 17
example, their profile -
Validation Rule
AND(
/* the below is the reference to the Val_Rule_Cntrlr__c custom setting's checkbox field
All_Opportunity_Disabled__c
*/
$Setup.Val_Rule_Cntrlr__c.All_Opportunity_Disabled__c = FALSE,
https://riptutorial.com/ 18
In the above rule, both pieces of criteria must evaluate to TRUE in order for the rule to be triggered.
Since All_Opportunity_Disabled__c checkbox will evaluate to TRUE when the running user's profile is
System Administrator, the rule will evaluate to FALSE.
Workflow Rules
The same approach can be applied in order to deactivate Workflow Rules.
Explanation
In this example a simple Trigger has been created to change the Close Date of an Opportunity,
that's about to be inserted or updated, to a date 10 days in the future.
The Apex Controller custom setting's checkbox field enables the code to be disabled at the user /
profile / org level.
Apex Class
Id userId;
Apx_Cntrlr__c userApexController;
Boolean userSetting;
userId = userinfo.getUserId();
userApexController = Apx_Cntrlr__c.getInstance(userId);
userSetting = userApexController.Close_Date_Update_Disabled__c;
if (userSetting == false) {
for(Opportunity opp : Trigger.new) {
opp.CloseDate = date.today().addDays(10);
}
}
Unit Test
@isTest
public class CloseDateUpdateTest {
@testSetup
static void dataSetup() {
Profile p = [SELECT Id FROM Profile WHERE Name = 'System Administrator' LIMIT 1];
https://riptutorial.com/ 19
'en_US',EmailEncodingKey = 'UTF-8',LanguageLocaleKey = 'en_US');
insert u;
}
test.startTest();
system.runAs(u){
for(Opportunity o : opportunities2){
system.assertEquals(date.today().addDays(10), o.closeDate, 'CloseDateUpdate
trigger should have changed the Opportunity close date as it was not disabled by the
apexController custom setting');
}
}
test.startTest();
system.runAs(u){
https://riptutorial.com/ 20
test.stopTest();
for(Opportunity o : opportunities2){
system.assertEquals(date.today().addDays(1), o.closeDate, 'CloseDateUpdate trigger
should not have changed the Opportunity close date as it was disabled by the apexController
custom setting');
}
}
You may wish to update your custom setting's during the execution of your code, to switch off
validation or workflow rules.
In the below code, I have created a Schedulable Apex Class which will update the Close Date of
any Opportunities whose Close Date is less than or equal to 6 days from the current date,
changing the date to 20 days in the future.
I will use my Custom Setting Val_Rule_Cntrlr__c to deactivate any validation rules which would
prevent me from updating the Opportunities that meet my criteria.
Id userId;
Val_Rule_Cntrlr__c setting;
Boolean validationRulesAlreadyDisabled;
List<Opportunity> processedOpps = new List<Opportunity>();
Date d;
https://riptutorial.com/ 21
d = system.today().addDays(6);
if (processedOpps.size() > 0) {
update processedOpps;
}
To make sure that my validation rules are being deactivated by the changes to my custom setting
in my class, I have created a checkbox field Trigger_Validation_Rule__c (which would not be visible
to users or added to page layouts) & a validation rule with this criteria:
AND(
$Setup.Val_Rule_Cntrlr__c.All_Opportunity_Disabled__c = FALSE,
Trigger_Validation_Rule__c = TRUE,
/* allow the above criteria to be met while inserting the Opportunities, without triggering
the rule, in the @testSetup portion of the test */
NOT(ISNEW())
)
I then set the checkbox field to true when creating my Opportunities so that the rules criteria would
be met, if the custom setting field is not edited by my code.
@isTest
private class WE_ScheduledCloseDateUpdateTest {
@testSetup
static void dataSetup() {
Profile p = [SELECT Id FROM Profile WHERE Name = 'System Administrator' LIMIT 1];
https://riptutorial.com/ 22
upsert valRuleCntrlr;
Test.startTest();
System.assertEquals(CRON_EXP, ct.CronExpression);
System.assertEquals(0, ct.TimesTriggered);
System.assertEquals('2022-03-15 00:00:00', String.valueOf(ct.NextFireTime));
Test.stopTest();
// test results
Integer updateCount = 0;
Integer skipCount = 0;
https://riptutorial.com/ 23
for(Opportunity o : opportunitys) {
if (o.Name.contains('Update') &&
updateCount == 0)
{
System.assertEquals(date.today().addDays(20), o.CloseDate, 'Opportunity\'s
Close Date should have been updated as it was less than 7 days away');
updateCount = 1;
}
if (o.Name.contains('Skip') &&
skipCount == 0)
{
System.assertEquals(date.today().addDays(15), o.CloseDate, 'Opportunity should
not have been updated as it\'s Close Date is more than 7 days away');
skipCount = 1;
}
}
// check that both lists of Opportunities have been tested
System.assertEquals(2, updateCount + skipCount, 'Count should be 2 once all assertions
have been executed');
// check that the class does not change the custom setting's field to false, if it was
true before class was executed
static testmethod void testSettingUpdates() {
// switch the custom setting field to true before the scheduled job executes
Val_Rule_Cntrlr__c setting;
setting = Val_Rule_Cntrlr__c.getInstance(u.Id);
setting.All_Opportunity_Disabled__c = true;
upsert setting;
System.runAs(u) {
Test.startTest();
System.assertEquals(CRON_EXP, ct.CronExpression);
System.assertEquals(0, ct.TimesTriggered);
System.assertEquals('2022-03-15 00:00:00', String.valueOf(ct.NextFireTime));
Test.stopTest();
}
setting = Val_Rule_Cntrlr__c.getInstance(u.Id);
// check that the class did not change the All_Opportunity_Disabled__c field to false
System.assertEquals(true, setting.All_Opportunity_Disabled__c);
}
https://riptutorial.com/ 24
Read Custom Settings online: https://riptutorial.com/salesforce/topic/4927/custom-settings
https://riptutorial.com/ 25
Chapter 6: Date Time Manipulation
Examples
Easily Find Last Day of a Month
If you need to find the last day of the month, you can do complicated DateTime gymnastics or you
can use the following method.
Say you want to find the last day of February 2021. Do the following:
Integer month = 2;
Integer day = null;
Integer year = 2021;
// Create a new DateTime object for the first day of the month following
// the date you're looking for.
DateTime dtTarget = DateTime.newInstance(year, month, 1);
//In this case we would be sure that month would not be out of bound
dtTarget = dtTarget.addMonths(1);
// Then use the .addDays() method to add negative 1 days. This gives you
// the last day of the target month.
DateTime lastDayOfMonth = dtTarget.addDays(-1);
day = lastDayOfMonth.day();
System.debug(lastDayOfMonth);
System.debug(day);
This works for all the add methods, allowing you easily and quickly find DateTimes in the past.
https://riptutorial.com/ 26
Chapter 7: Global Variables in classes
Introduction
In this topic I would like to mention all possible global variables which can be used in Apex code.
Like [UserInfo Class][1]. I suggest we just list a global classes/variables and links. If you know
about a global class/variable but can't find a documentation, please provide as much information
as possible. [1]: https://developer.salesforce.com/docs/atlas.en-
us.apexcode.meta/apexcode/apex_methods_system_userinfo.htm
Examples
UserInfo
https://riptutorial.com/ 27
Chapter 8: Global Variables on Visualforce
pages
Examples
$Resource
Can be used in conjunction with the URLFOR function to reference files inside of a zipped static
resource:
$Label
The $Label variable can be used to display text defined in your custom labels.
You can do formatting with labels as well. Suppose you have a custom label named
Welcome_Message defined as
<apex:outputText value="{!$Label.Welcome_Message}"
rendered="{!NOT(ISBLANK($User.ContactId))}">
<apex:param value="{!$User.Contact.FirstName}" />
</apex:outputText>
$User
The $User variable gives you access to all the standard and custom fields on the User object for the
currently logged in user.
https://riptutorial.com/ 28
Chapter 9: Page Navigation with help of list
wrapper class in sales force.
Introduction
Slaesforce StandardSetController hold only List of sObject, It will not holdslist of wrapper class
object. Below source code demonstrates the usage of Paginating using Wrapper Class in sales-
force.
Examples
Pagination Controller
i am going to show all the contacts in the form of pagination and there should be one checkbox for
each contact to selected or deselect contact to perform delete operation on contacts. So i need to
be create a wrapper class to hold contact and Boolean Variable for selection. First create Wrapper
class for controller Pagination Insert below code into pagination controller.
Now Retrieving Data in Apex to Paginate with the help of StandardSetController. The
StandardSetController is an extremely powerful tool with built-in functionality that you can use to
greatly simplify the custom code in your Visualforce pages. Because the server returns only the
data for the page being requested, the StandardSetController can significantly reduce view state,
especially compared to the view state you would get while using SOQL.
https://riptutorial.com/ 29
size=Page_Size;
string queryString = 'Select Id,Name, Email, Birthdate, Phone, MobilePhone
from Contact order by Name';
setCon = new
ApexPages.StandardSetController(Database.getQueryLocator(queryString));
setCon.setPageSize(size);
noOfRecords = setCon.getResultSize();
}
return setCon;
}set;
}
Now you have the contacts in the Variable setCon , whenever your requested for
setCon.getRecords() it will retrieve the first 10 contact records from the setCon. Here i have create
simple wrapper class to show you the demo. You can create your own wrapper class based on
requirement. But always you must be aware that ApexPages.StandardSetController hold only List
of sObject, it will not hold the list of wrapper class object . That's the reason i have written extra
code below to accomplish this future in different way. Below code convert list of contacts into list of
wrapper class objects, So that when ever you call contacts in visual force page it will receive the
list of wrapper class object.
public Pagination() {
selectedContactIds=new set<id>();
}
Now you have written code for generating result But how to navigate across the page? This can
be done with easy step with ApexPages.StandardSetController.Look at the below code beauty of
the StandardSetController, No need to maintain page number,offset and limit etc.. Just use the
StandardSetController methods. Copy the below code into Pagination controller.
https://riptutorial.com/ 30
set;
}
Your almost done with Paginating the contacts. Last few methods i have added to fulfill my entire
page functionality. As i mention earlier we have additional checkbox for selecting contact and
perform delete operation on selected contacts.
https://riptutorial.com/ 31
setCon = null;
selectedContactIds=new set<id>();
getContacts();
setCon.setPageNumber(1);
return null;
}
Read Page Navigation with help of list wrapper class in sales force. online:
https://riptutorial.com/salesforce/topic/10744/page-navigation-with-help-of-list-wrapper-class-in-
sales-force-
https://riptutorial.com/ 32
Chapter 10: SalesForce CI Integration
Introduction
Place to use Jenkins and Sonar for CI
Examples
How to configure Jenkins to deploy code on Development or Production org ?
How we can use jenkins in our SalesForce product development. What are the tools plugins are
available for Jenkins Integration How to solve CI configuration issue.....etc
1. Jenkins: The leading open source automation server, Jenkins provides hundreds of plugins
to support building, deploying and automating any project.
2. Sonar Qube: SonarQube provides the capability to not only show health of an application but
also to highlight issues newly introduced.
3. Apache Ant: Apache Ant is a Java library and command-line tool whose mission is to drive
processes described in build files as targets and extension points dependent upon each
other.
4. Apache Maven: Apache Maven is a software project management and comprehension tool.
Based on the concept of a project object model (POM), Maven can manage a project's build,
reporting and documentation from a central piece of information.
5. SfApexDoc: Support for JavaDoc like documentation creation tool. Can be used by
Ant/Jenkins to create Documents.
6. JUnit format Report for APEX: Extends the Force.com com.salesforce.ant.DeployTask to
accept an optional junitreportdir argument that defines the folder that a JUnitReport XML file
is output into. This file can be consumed directly by the Jenkins continuous integration tool to
produce trend graphs and test result details or by the JUnitReport Ant task.
7. Version Control System: Can use GIT, SVN or any other Version Control system
8. PMD Apex: Contains the PMD implementation to support the Apex programming language.
9. Sonar for Apex(enforce-sonarqube-plugin): The plugin has support for the Apex language
grammar, the current list of checks is focused mainly on test components. The support for
more SFDC components is in progress.
https://riptutorial.com/ 33
Chapter 11: Salesforce Object Query
Language (SOQL)
Syntax
• SELECT Id FROM Account
• SELECT Id, Name FROM Account
• SELECT Id FROM Account WHERE Name = 'SomeAccountName'
• SELECT Id, Name, (SELECT Id, Name FROM Contacts) FROM Account
• SELECT Id, Name FROM Account WHERE Id = :apexVariableName
Examples
Basic SOQL Query
This will return the Id and Name fields from the Account table. No filtering or sorting will be
applied.
This will return the first 100 Accounts from an unordered list.
SELECT Id, Name, Phone FROM Lead WHERE Phone LIKE '(%) %-%'
This will return Leads with a phone number matching the specified format. "%" acts as a wild card
character.
Using LIKE '% %' also enables a developer to replicate a CONTAINS( ) formula.
https://riptutorial.com/ 34
Will return Leads with a lead source that contains Google i.e. 'Google AdWords' & 'Google Natural
Search'.
SELECT Name, Title FROM User ORDER BY Title ASC NULLS FIRST
SELECT Id FROM Contact ORDER BY LastName ASC NULLS LAST, FirstName ASC NULLS FIRST
A very useful feature many people overlook is the ability to construct a Map using a SOQL query.
Map<Id, Account> accounts = new Map<Id, Account>([SELECT Id, Name FROM Account]);
System.debug(accounts);
When you run this code, accounts then contains a Map of your Account objects, keyed on Id. The
output to the debug log would look similar to this:
You are now able to look up the Account objects using their Id. Furthermore, if you want a
collection of unique IDs, you can call the keySet() function of the Map class, like so:
System.debug(accounts.keySet());
This is very useful when you need to query to get records and access them repeatedly in your
code.
When object's are linked by a lookup or master-detail relationship, the parent records field's can
be referenced from the child record or 'base object' in a query. This is also known as upwards
traversal.
https://riptutorial.com/ 35
SELECT FirstName, Account.Name, Account.Category__c FROM Contact
When the base object is a custom lookup field, the __c in field's name Primary_Influencer__c, for
example, will be changed to __r.
SELECT Id, Name, (SELECT Id, FirstName, LastName FROM Contacts) FROM Account
To perform a query in Apex, surround the query with square brackets. The result can be assigned
to a list, or to a single object.
To reference a variable in a query, add a colon (:) before the variable name.
When assigning to a single object, a query that returns anything other than a single row will throw
a QueryException.
try {
Account a = [SELECT Id FROM Account WHERE Name = 'Non-existent Account'];
} catch (QueryException e) {
// List has no rows for assignment to SObject
}
try {
Account a = [SELECT Id FROM Account];
} catch (QueryException e) {
// List has more than 1 row for assignment to SObject
}
https://riptutorial.com/ 36
Attempting to use a field that you did not include in the query will throw a SObjectException
Using a Semi-Join
Selecting all accounts that have open opportunity records under them
Dynamic SOQL
You can execute a database query from a String rather than a regular SOQL expression:
Since dynamic SOQL queries are not compiled, their schema references are not validated, so it is
preferable to use Apex variable interpolation using the :variable syntax where possible.
https://riptutorial.com/ 37
Chapter 12: Salesforce REST API
Introduction
Force.com REST API Documentation. Full list of API's is here
Examples
OAuth2 access_token and list of services
{
"access_token":
"00D6F0xxx001g1qs!ARsAQL7BRiQQ0lgTW7zXu3kILJBxxxxxHvDnChF2ETBFJpX0T2LsBsm8MVABhAvINAyZqgDIAHhJDp6QjuF6Z
"instance_url": "https://ap4.salesforce.com",
"id": "https://login.salesforce.com/id/00D6F000001xxxxAA/0056F000006DMcxxxx",
"token_type": "Bearer",
"issued_at": "14878401xxxxx",
"signature": "Ra5Sdm6gq4xxxeZYk3H2yBIVpZ6hBUDgkQ4Tjp9Q="
}
Then do
{
"tooling": "/services/data/v20.0/tooling",
"eclair": "/services/data/v20.0/eclair",
"prechatForms": "/services/data/v20.0/prechatForms",
"async-queries": "/services/data/v20.0/async-queries",
"query": "/services/data/v20.0/query",
"chatter": "/services/data/v20.0/chatter",
"wave": "/services/data/v20.0/wave",
"search": "/services/data/v20.0/search",
"identity": "https://login.salesforce.com/id/00D6F000001g1qsUAA/0056F000006DMcMQAW",
"sobjects": "/services/data/v20.0/sobjects",
"serviceTemplates": "/services/data/v20.0/serviceTemplates",
"recent": "/services/data/v20.0/recent",
"connect": "/services/data/v20.0/connect",
"licensing": "/services/data/v20.0/licensing"
}
https://riptutorial.com/ 38
Chapter 13: Tools for Development
Examples
IDEs
Browser extensions
Debuggers
○ Realtime debugging
○ Force.com IDE
○ requires special licensing from salesforce
• Welkin Suit
https://riptutorial.com/ 39
○ Stand alone IDE
○ Subscription required
• Illuminated Cloud:
• Salesforce DataLoader
• Dataloader.io
• Jitterbit
• SFXOrgData
• DreamFactory Monarch
• Pentaho Kettle
• Talend
https://riptutorial.com/ 40
Chapter 14: Trigger Bulkification
Examples
Bulkification
If you do row-by-row processing in Salesforce, you'll probably reach the governor limit quickly.
This is especially true with triggers and things that fire when you don't expect them. One
documented method of escaping the governor limit is bulkification.
Bulkifying Apex code means making sure that the code properly handles more than one record at
a time. When a batch of records initiate Apex, a single instance of that Apex code is executed, but
that instance needs to handle all of the records in that given batch.
Not Bulkified:
Bulkified:
https://riptutorial.com/ 41
Chapter 15: Visualforce Page Development
Examples
Basic page
<apex:page>
<h1>Hello, world!</h1>
</apex:page>
If your page is for displaying or editing information about a particular type of record, it may be
helpful to use a standard controller to reduce the amount of boilerplate code you need to write.
By using a standard controller, your page will be displayed with an ?id=SALESFORCE_ID parameter,
and you automatically get access to all merge fields on the record.
<apex:page standardController="Account">
This is a page for {!Account.Name}
</apex:page>
• cancel() - returns the PageReference for the cancel page (usually navigates back to a list view)
• delete() - deletes the record and returns the PageReference for the delete page
• edit() - returns the PageReference for the standard edit page
• save() - saves the record and returns the PageReference to the updated record
• view() - returns the PageReference for the standard view page
<apex:page standardController="Account">
Name: <apex:inputField value="{!Account.Name}" />
<apex:commandButton value="Update record" action="{!save}" />
</apex:page>
https://riptutorial.com/ 42
Chapter 16: Working with External Systems
Examples
Making an outbound callout
This is an example on how to call a web service from salesforce. The code below is calling a
REST based service hosted on data.gov to find farmers markets close to the zipcode.
Please remember in order to invoke a HTTP callout from your org, you need to tweak the remote
settings for the org.
https://riptutorial.com/ 43
Credits
S.
Chapters Contributors
No
Approval Process
4 Ajay Gupta
Objects
Date Time
6 kurunve, LDP, RamenChef
Manipulation
Global Variables in
7 Andrii Muzychuk
classes
Global Variables on
8 Ben
Visualforce pages
SalesForce CI
10 Sanjay Kharwar
Integration
Salesforce Object
abhi, Alex S, Andrii Muzychuk, battery.cord, Ben, ca_peterson,
11 Query Language
Doug B, Eric Dobbs, LDP, Ratan Paul
(SOQL)
Salesforce REST
12 radbrawler
API
Visualforce Page
15 Ben
Development
https://riptutorial.com/ 44
Working with
16 abhi, mnoronha
External Systems
https://riptutorial.com/ 45