APEXPROGRAMMINGMATERIAL-1 (1) (1)
APEXPROGRAMMINGMATERIAL-1 (1) (1)
- We can integrate the Salesforce application with any External System using Apex
Programming(SOAP API, REST API).
- Using Apex Programming we can perform all the DML manipulations on the
records.
Types of Programming:
Note:
Implementation behind all the EAI Tools (Enterprise Application Integration
Like TIBCO, WEB METHODS, SEE BEYOND, BIZ TALK, etc) is Service Oriented
Approach.
- In Salesforce, We are using Two API's for the Service Oriented Communication.
Called as "SOAP API" and "REST API", for integrating the Salesforce with external
systems.
SOAP --> Simpe Object Access Protocol
REST --> Representational State Transfer
API --> Application Programming Interface
Primitive Datatypes:
- These are the Basic / Fundamental datatypes to store the values for temporary
usage. These are available in all programming languages.
Ex:
Integer: Requires 4 bytes of memory(Holds Only numerical Value).
Long: Occupies 8 bytes of memory
Double: This can hold a numerical value, which contains decimal point values
also.
We can store more than 2 digits after the decimal point.
Ex: double Pi= 3.1412;
Decimal: This can hold a Decimal value, which contains max of 2 digits after the
decimal point.
Ex: decimal balance = 24500.50;
Note: All Currency fields will refer Decimal Datatype by default.
- It requires 8 bytes of memory.
Char: It can hold only one character, which requires 2 bytes to store a character.
Boolean: It is used to hold True / False Values.
Byte: This datatype is used to store the bit value (0 / 1)
ID : This datatype is used to store an 18 characters ID generated by salesforce,
which is used to identify a record.
String: This datatype is used to store a collection characters including special
characters also.
Date: This Datatype is used to store the Date values.
Date/Time: This is used to hold Data Time stamp.(Date and Time)
Variable Declaration:
- Variable is a Programmatic element, which can hold a specific value for
temporary usage.
Note:
All primitive datatypes supports Static Memory Allocation.(i.e each data
type has a fixed size of memory, which will be allocated at the time of variable
definition. )
Note:
We can't increase / decrease the size at runtime.
SObject Datatypes:
- All Salesforce objects (both Standard & Custom) will be comes under SObject
Data Types.
- These will supports Dynamic Memory allocation, which will reserve the memory
during runtime of the application.
Variable Declaration:
Account acc;
Contact con;
Position__C pos;
Candidate__c cnd;
1. Standard Navigation.
2. Developer Console.
3. Execute Ananymous Window
4. Eclipse IDE.
Standard Navidation:
- Using this option, we can create user defined business logic interms of controller
classes and store into Force.com platform.
- All Apex classes will stored into Metadata Repository in Force.com platform.
Goto Setup --> Goto Build Menu --> Goto Develop --> Click on "Apex Classes".
1. Click on "New" button to create a New Apex Class.
2. Write the Business login in the editor provided by salesforce
3. Click on "Save" button.
Note:
1. When the user click on "Save" button, salesforce will forward the apex
class to Force.com platform.
2. Apex code will be compiled by using Apex Compiler, which resides in
Force.com platform.
3. If found any errors, it will immediately intimate to the user. If Not found
(Compiled successfully), Apex class will stored into Metadata Repository.
Goto Your Name --> Click on "Developer Console". It will open the
Developer console in a New Window.
1. Goto "Debug" menu
2. Click on "Execute Ananymouns Windows".
3. Write the Apex code to be get executed.
4. Click on "Execute" button to run the code.
Note: When the user click on "Execute" button, it will send the complete
code to Force.com platform to get it compiled.
Comments:
These are used to ignoring few lines of code to get it compiled and execute / Run.
Syntax:
// <Statements...>
2. Multiline comments:
- We can comment a group of statements as below.
Syntax:
/*
...
... Statements..
...
*/
Ex:
/*
integer accountNumber;
string customerName;
*/
Variable Declaration:
- Variable is a Programming element to store some value for temporary
storage.
- We can define the variables in apex programming by using the below
syntax..
Syntax:
[<AccessSpecifies>] <DataType> <Var1>[,<var2>,<var3>,...etc];
Ex:
integer x, y;
string customerName, country;
boolean isExist;
SObject DataTypes:
Account acc;
Contact con;
Position__c pos;
Candidate__c objCandidate;
...
etc.;
Assignment Operations:
To assign the value for the variables, we need to use the assignment operators.
+ --> Addition
- --> Subtraction
* --> Multiplication
/ --> Division
Mod() --> Reminder
Ex:
== --> Equals
= ==> Assignment
> --> Greater Than
>= --> Greater Than or Equals
< --> Less Than
<= --> Less Than or Equals
!= --> Not Equals
3. Assignment Operators:
- These are used to assign the values to the variables.
Ex:
= --> Assign the value to a variable
Ex: integer x =100
string customerName = 'Ramesh Kumar';
+= --> Incrementing the value and assign to a variable
4. Logical operators:
- Logical Operators are used to prepare the compound conditions.
AND --> Verifies all the conditions are valid or not. If all the conditions are
satisfied it will return TRUE. Else return FALSE.
Printing Statement:
-Salesforce Provides a built-in class called as "System". Which provides "Debug"
function to display / print the result of the statements on the developer console.
Ex:
system.debug('Welcome');
system.debug('Welcome to Apex Programming.');
Note: Apex code needs to be executed by Force.com Platform.
When user executes an apex program or code, force.com platform will compile
and execute the code and generates a “Log File”.
All log files will be stored in the location “Debug Logs” as below.
Goto Setup → Goto Monitor option in Left Panel → Goto Logs → Click on “Debug
Logs”. It will show the debug log files generated by salesforce.
// Write the Code in Execute Ananymous window and click on “Execute” button
system.debug('Welcome to Apex Programming.');
system.debug('This is my First Apex Program.');
system.debug('Debug Logs are Enabled.');
Note:
It will send the Apex program code to Force.com platform. It will compile
the code and execute. And send the response back to the client and display the
result in "Developer Console"
// Write an apex program to define the variables and print the values in
Developer console.
integer accountNumber;
string customerName;
accountNumber = 100001;
customerName = 'Ramesh Kumar';
firstNumber = 400;
secondNumber = 20;
// Addition Operation..
// Subtraction Operation..
result = firstnumber - secondNumber;
system.debug('Subtraction result is....: '+ result);
// Multiplication Operation..
result = firstnumber * secondNumber;
system.debug('Multiplication result is....: '+ result);
// Division Operation..
result = firstnumber / secondNumber;
system.debug('Division result is....: '+ result);
principleAmount = 50000;
rateOfInterest = 5;
tenure = 10;
- These are used to transfer the flow of execution of statements exist in the apex
program.
- By using this we can decide, which statements needs to be executed and which
should not to be executed by using a condition or filter.
- The user can prepare his own conditions to execute the statements.
- We can have one or more conditions, which can be combined by using logical
operators.
Syntax:
<Variable_Name> <Operator> <value>
Ex:
fNumber == sNumber
fNumber > sNumber
sNumber > 0
1. IF Conditional Statements
2. Ternary Operator
Ex:
1. Providing 5% Discount, When bill amount is more than 4000.
2. Calculating the Grade, If the student got Passed.
3. Delete the Record, If it is exist
IF Condition:
Using this statement, we can change the execution flow of the application.
Ex:
BillAmount > 4000. AnnualRevenue > 100000. Rating = 'Hot', etc..
- To Prepare the Multiple conditions (Compound conditions), we have to use
Logical Operators.
Simple IF Condition:
Syntax:
If(<Conditions>)
{
Statements..
....
}
Ex:
if(secondNumber > 0)
{
result = firstnumber / secondNumber;
system.debug('Division Result is....: ' + result);
}
IF Else Statement:
Syntax:
if(<Conditions>)
{
// TRUE Block Statements
....
}
else
{
// FALSE block Statements.
...
}
Ex:
firstNumber = 200;
secondNumber= 15;
if(secondNumber > 0)
{
result = firstnumber / secondNumber;
system.debug('Division Result is....: ' + result);
}
else
{
system.debug('Division Operation Cannot be performed');
}
// Apex program to find out the Biggest Number from the given two numbers.
firstNumber = 200;
secondNumber= 1500;
Else If Condition:
Syntax:
If(<Conditions>)
{
// Statements.
..
}
else if(<Conditions>)
{
// Statements.
...
}
else if(<Conditions>)
{
// Statements
}
...
...
else
{
// Statements..
...
}
Note:
1. If any of the condition is not satisfied, then it will execute the ELSE block
statements.
2. If one of the condition is satisfied, then it will execute that Condition
Block statements and comes out from the If condiions. (i.e. it won't check the
remaining conditions.)
Ex:
firstNumber = 2000;
secondNumber= 2000;
Nested IF Condition:
Syntax:
IF(<Conditions>)
{
// Statements...
....
IF(<Conditions>)
{
// Statements..
...
}
else
{
// Statements...
}
}
fNumber = 100;
sNumber = 0;
IF Condition Statement:
fNumber = 100;
sNumber = 0;
if(sNumber > 0)
{
system.debug('Division Result ....: ' + (fNumber / SNumber));
}
else
{
system.debug('Division Operation Cannot performed.');
}
=============================================
// Write an apex program to display the Biggest number from the given Two
numbers.
=============================================
/* Write an apex program to print the Season Name based on Month Number as
below.
Month Numbers Season Name
-----------------------------------------------------
1-4 Winter
5-8 Summer
9-12 Spring
>12 or <1 Invalid Month Number
*/
integer monthNumber;
monthNumber = 14;
==============================================
/* Write an apex program to find out the Student's Grade based on the below
requirement.
*/
maths = 50;
physics = 47;
chemistry = 39;
english = 90;
hindi = 75;
totalmarks = english + hindi + maths + chemistry + physics;
system.debug('Total Marks are....: ' + totalmarks);
averagemarks = totalmarks / 5;
system.debug('Average Marks are....: ' + averagemarks);
if(maths >= 40 && physics >= 40 && chemistry >= 40 && english >= 40 && hindi
>= 40)
{
system.debug('STUDENT GOT PASSED.');
if(averagemarks >=60)
{
system.debug('Student got - GRADE A');
}
else if(averagemarks >= 50 && averagemarks <= 59)
{
system.debug('Student got - GRADE B');
}
else if(averagemarks >=40 && averagemarks <=49)
{
system.debug('Student got - GRADE C');
}
}
else
{
system.debug('STUDENT GOT FAILED.');
}
Ternary Operator:
// Apex program to find biggest one from the given two numbers using Ternary
Operator
firstNumber = 2000;
secondNumber= 4000;
Iterative Statements:
- These are used to execute a set of statements for the specified number of times.
- These are also called as Looping statements.
1. While Loop.
2. Do-While Loop.
3. FOr Loop.
While Statement:
----------------
syntax:
While(<Conditions>)
{
// Statements...
.....
}
- It is a Pre-checking iterative statement, which will check the condition first. If the
condition is satisfied, then it will enter into the block and execute the statements.
It will repeat the step till the condition is TRUE.
If the condition is FALSE, then it will comes out of the block.
integer counter;
counter=1;
integer counter;
counter=2;
while(counter <= 100)
{
system.debug(counter);
counter += 2; // Counter = counter + 2;
}
Do-While Loop:
Do-While is a PostChecking iterative statement, which will execute the statement
atleast once and then it will check the condition.
It will iterate the loop till the condition is satisfied. Once the condition is Failed, it
will comes out of the block.
Syntax:
Do
{
// Statements.
....
}While(<Conditions>);
integer counter;
counter=100;
do
{
system.debug(counter);
counter--;
}While(counter >= 1);
FOR Loop:
---------
- It is a Pre-checking iterative statement, which will execute the set of statements
for a specified number of times.
- It provides the optimized way of writing the iterative statements.
Syntax:
FOR(<InitializationPart> ;
<Conditional Part> ;
<Increment / Decremental Part>)
{
// Statements..
...
...
}
// Apex program to Print the First 100 Numbers using FOR loop.
// Write an apex program to print Odd Numbers falls between 1 - 100 using FOR
loop;
// Write an apex program to print the first 100 numbers using Do-While
statement.
integer counter;
counter =1;
do
{
system.debug('Value is...: ' + counter);
counter++;
integer startingValue;
startingValue = 2;
integer counter;
counter = 100;
While(counter >= 1)
{
system.debug(counter);
counter--;
}
integer counter;
counter =1;
counter =1;
while(counter <= 10)
{
system.debug('Welcome to Apex Proigramming.');
counter ++;
}
Arrays:
integer[] accountNumbers = new integer[5];
accountNumbers[0] = 100;
accountNumbers[1] = 6780;
accountNumbers[2] = 1450;
accountNumbers[3] = 190;
accountNumbers[4] = 17800;
-------------------------
-----------------------------------
string[] months = new string[]
{'January','February','March','April','May','June','July','August','September','Octob
er','November','December'};
------------------------------
-----------------------------------------
- OOP provides the following basic principles needs to be followed during the
application development.
- In Object Oriented Programming, each functionality is provided in terms of
Classes and Objects.
1. Encapsulation:
- It Describes grouping of Data Members(Variables) and member functions
into a single unit called as "Class".
- It can be achieved by using Classes and Interfaces.
2. Abstraction:
- It describes, Providing the User Interface to the User, but with out
providing the complexity of the implementation.
-i.e. we can hide the backend implementation of the application.
- By using this we can achieve the "Data Hiding"
3. Inheritance:
- This is used to aquire the features of once class into another class, in-
order to avoid the duplicate code in the application.
- By using this we can achieve "Code Re-Usability"
4. Polymorphism:
- Poly means "Many", Morphism means "Forms"
- By using this, we can prepare multiple functions with Same Name, but the
functions should be differentiate in-terms of their Signature (i.e. Number of
Parameters, Order of Parameters and Type of the Parameters)
Class:
It is a blue print, which contains group of Variables and Functions together. A class
can have one or more members inside it like Variables, Functions, Constructors,
Properties, etc.
Class Syntax:
=============
<AccessSpecifiers> Class <ClassName>
{
// Class Members..
... Variable, Functions, Constructors, Properties...etc.
...
}
Ex:
Public Class SampleClass
{
integer acountNumber;
string customerName;
boolean isExist;
}
Note:
1. Class Name should be always Start with a "Capital Letter"
2. Class Name should be only OneWord. i.e. No spaces in the class name.
3. We can't create Duplicate Classes. (i.e each class should have a unique
name)
Note:
All Classes will be stored into the Metadata Repository in Force.com
platform.
Access Specifiers:
==================
- Access specifier, defines the Level of Access / Scope of the member or the Class.
- Using AccessSpecifiers, we can restrict the access of the Class or Class Members.
- Apex provides the below AccessSpecifiers
1. Private:
Private members of the class can be accesible from only within the
class.
- We can't access the members from out side of the class.
2. Public:
- Public members of the class can be accesible from within the class
and outside of the class also.
- These members can be accesible within the Entire application. But
can' accesible from Outside of the application
3. Protected:
- These members can be accesible from within the class and from the
Child or associated classes.
Note: We can't access from out side of the class.
4. Global:
- We can access these members from within the application and
Outside of the Application also.
- i.e. we can able to access these members from Extenal Systems
also.
-BatchApex Calsses, Schedule Apex Classes, Webservices should be
defined as "Global"
Note:
If the user didn't specify any access specifier for a member(Variable,
Function,...etc), then it will be Private by default.
Syntax:
--------
Ex:
Note:
Developer Console provides an Auto Save option, which saves the code in
Force.com platform by compiling the code automatically.
// Create an Apex Class to define Variables and Access the members by creating
object...
Creating Class:
---------------
public class MySampleClass
{
public integer accountNumber;
public string customerName;
}
- It will creates a New Apex Class with the specified name and send to the
Force.com Platform for compilation. If it is success, then it will Save the Apex Class
code in Metadata Repository.
Creating Class:
---------------
Public class SampleApexClass
{
/* The below statement will cause the Exception "Variable cannot be visible - Due
to Private Access.." */
system.debug('Customer Address is....: ' + sample.customerAddress);
// Assigning values...
sample.accountNumber = 100001;
sample.customerName = 'Ramesh Kumar';
Creating Class:
---------------
Executing class:
----------------
// Create Object of the Class...
SubPrograms:
============
-These are the part of the program, which can able to perform some task.
- SubPrograms are used to divide the large / complex functionality into various
small pieces to make it more understandable.
Procedure:
----------
- It contains one or more statements in order to perform a particular task.
Syntax:
-------
<AccessSpecifier> Void <ProcedureName> ([<ParametersList>])
{
// Statements..
....
}
Ex:
// Write an Apex Program to Perform the Arithmetic operations and print the
result.
Parameterised Procedures:
-------------------------
- If the procedure doesn't have any parameters, then it will provide the static
behaviour.
i.e. whenever we call the procedure, it provides the same result.
- To make the procedure dynamic, we need to supply some input values in-terms
of Parameters.
- We can pass N number of Parameters. with different types of values.
- Each parameter, should indicate the "DataType" and "Parameter Name"
Syntax:
public void ProcedureName(<DataType> <Param1>, <DataType>
<Param>,.... ,<DataType> <ParamN>)
{
// Statements;
......
}
Note: While calling the procedure, the user has to supply the values to the
parameters in the Procedure in the same order and type as defined in the
Procedure Definition.
Ex:
public void Addition(integer x, integer y)
{
system.debug(x+y);
}
Calling:
<ObjectName>.Addition(100,450) --> Valid Statement
<ObjectName>.Addition(234, 'ABC') --> Invalid / Error
}
Execution:
-----------
// Creating Object of the class..
BasicMathOperations s = new BasicMathOperations();
Functions:
==========
It is also a SubPrograms, which contains one or more statements to perform a
particular task, and will return the result to the calling environment.
Note:
Function should return the value by using "Return" statement.
Syntax:
-------
<AccessSpecifier> <DataType> <FunctionName> ([<Parameters>])
{
// Statements..
....
Execution:
---------
// Creating Object of the class..
FunctionsSample s = new FunctionsSample();
integer result;
result = s.Addition(123,478);
system.debug('Addition Result is...: '+ result);
// Concatenation Function...
system.debug('Concatenation result is....: '+ s.Concatenate('Welcome ', 'To
Salesforce'));
Constructors:
=============
- Constructor is a Special Member Function, which will execute automatically
whenever the user creates an object of the class.
- Constructors are used to assign some pre-defined values to the variables, while
loading the application
Note:
While compiling the class code, Apex Compiler will verify wether the user
has provided the default constructor for the class or not.
If yes, then it will execute the userdefined constructor.
Else, the Apex Compiler will creates a Default constructor for the class and
execute the statements.
Example:
public class ConstructorSample
{
public ConstructorSample()
{
system.debug('This is the Default Constructor.');
}
Execution:
----------
// Creating Object of the class..
ConstructorSample s = new ConstructorSample();
1. Insert:
- USed to insert the new records
- Used to insert one or more records into an object
2. Update:
- USed to update the existing records in the object
- We can update one or more records
Syntax:
Update <Object_Name>;
Note: Before Updating the record, we need to fetch the record values(using
SOQL Query) and update with the new values.
3. Delete:
- Used to Delete the existing records from an object
- We can Delete one or more records from the object
Note: To delete the record, ID of the record is enough
Note: Deleted records will be stored into the RecycleBin for 30 days.
If any of the deleted records is older than 30 days, then it will be deleted
permanently from the salesforce
Syntax:
Delete <Object_Name>;
4. Upsert:
- It is a combination of Insert + Update
- If the record is exist, then it will update the record
- IF the record is not exist, then it will create the new record
Syntax:
Upsert <Object_Name>;
5. Undelete:
- USed to Re-store the deleted records from the RecycleBin to actual object
Syntax:
Undelete <Object_Name>;
===========================================
//Inserting Records using Apex DML Statements:
// Inserting a Record....
Account acc = new Account();
insert acc;
system.debug('Account Record ID is....: '+ acc.id);
insert acc1;
system.debug('Account Record ID is....: '+ acc1.id);
// Apex Program to Create a New Record in the Customer Object (Custom Object)
insert cust;
// Inserting a Record....
Account acc = new Account();
insert acc;
con.firstname = 'Suraj';
con.lastname = 'Kumar';
con.email = '[email protected]';
con.Phone = '1233225588';
con.HomePhone = '7788995577';
con.mobilephone = '9955660000';
con.fax = '8855998855';
con.ssn_number__c = '2255887744';
insert con;
------------------------
// Apex Program to Create a Contact and Associated to an Account, with
Hardcoded Account Id value.
// Creating Contact Record..
insert con;
insert oppty;
Governor Limits:
================
- Salesforce provides a shared infrastructure to all the users, so that they can
install their required applications and accessed by their customers.
- If one user making the Salesforce server busy, by performing some continuous
operations, then other users will be in waiting stage. i.e other users are affecting.
These limits are applicable to all the users, who are accessing the salesforce
server.
Note:
While writing the code / Business logic, the developer has to keep in mind
about the governor limits.
Ex:
We can perform max. of 150 DML Operations in a Single Transaction.
Else, salesforce will raise "System.LimitException", which indicates
that you are crossing the Governor Limits for DML operations.
Sol:
To avoid this Exceptions, As a Best Practice, it is always
recommended to avoid the usage of DML statements inside the FOR loop.
Arrays(Disadvantages):
===============
SubPrograms:
============
-These are the part of the program, which can able to perform some task.
- SubPrograms are used to divide the large / complex functionality into various
small pieces to make it more understandable.
Procedure:
----------
- It contains one or more statements in order to perform a particular task.
Syntax:
-------
<AccessSpecifier> Void <ProcedureName> ([<ParametersList>])
{
// Statements..
....
}
Ex:
Parameterised Procedures:
-------------------------
- If the procedure doesn't have any parameters, then it will provide the static
behaviour.
i.e. whenever we call the procedure, it provides the same result.
- To make the procedure dynamic, we need to supply some input values in-terms
of Parameters.
- We can pass N number of Parameters. with different types of values.
- Each parameter, should indicate the "DataType" and "Parameter Name"
Syntax:
public void ProcedureName(<DataType> <Param1>, <DataType>
<Param>,.... ,<DataType> <ParamN>)
{
// Statements;
......
}
Note: While calling the procedure, the user has to supply the values to the
parameters in the Procedure in the same order and type as defined in the
Procedure Definition.
Ex:
public void Addition(integer x, integer y)
{
system.debug(x+y);
}
Calling:
<ObjectName>.Addition(100,450) --> Valid Statement
<ObjectName>.Addition(234, 'ABC') --> Invalid / Error
}
Execution:
-----------
// Creating Object of the class..
BasicMathOperations s = new BasicMathOperations();
// Accessing class members using object..
s.Addition(100,580);
s.Addition(2345,6789);
Functions:
==========
It is also a SubPrograms, which contains one or more statements to perform a
particular task, and will return the result to the calling environment.
Note:
Function should return the value by using "Return" statement.
Syntax:
-------
<AccessSpecifier> <DataType> <FunctionName> ([<Parameters>])
{
// Statements..
....
Execution:
---------
// Creating Object of the class..
FunctionsSample s = new FunctionsSample();
integer result;
result = s.Addition(123,478);
system.debug('Addition Result is...: '+ result);
// Concatenation Function...
system.debug('Concatenation result is....: '+ s.Concatenate('Welcome ', 'To
Salesforce'));
Constructors:
=============
- Constructor is a Special Member Function, which will execute automatically
whenever the user creates an object of the class.
- Constructors are used to assign some pre-defined values to the variables, while
loading the application
Note:
While compiling the class code, Apex Compiler will verify wether the user
has provided the default constructor for the class or not.
If yes, then it will execute the userdefined constructor.
Else, the Apex Compiler will creates a Default constructor for the class and
execute the statements.
Example:
public class ConstructorSample
{
public ConstructorSample()
{
system.debug('This is the Default Constructor.');
}
Execution:
----------
// Creating Object of the class..
ConstructorSample s = new ConstructorSample();
1. Insert:
- USed to insert the new records
- Used to insert one or more records into an object
2. Update:
- USed to update the existing records in the object
- We can update one or more records
Syntax:
Update <Object_Name>;
Note: Before Updating the record, we need to fetch the record values(using
SOQL Query) and update with the new values.
3. Delete:
- Used to Delete the existing records from an object
- We can Delete one or more records from the object
Note: To delete the record, ID of the record is enough
Note: Deleted records will be stored into the RecycleBin for 30 days.
If any of the deleted records is older than 30 days, then it will be deleted
permanently from the salesforce
Syntax:
Delete <Object_Name>;
4. Upsert:
- It is a combination of Insert + Update
- If the record is exist, then it will update the record
- IF the record is not exist, then it will create the new record
Syntax:
Upsert <Object_Name>;
5. Undelete:
- USed to Re-store the deleted records from the RecycleBin to actual object
Syntax:
Undelete <Object_Name>;
===========================================
//Inserting Records using Apex DML Statements:
// Inserting a Record....
Account acc = new Account();
insert acc;
system.debug('Account Record ID is....: '+ acc.id);
insert acc1;
system.debug('Account Record ID is....: '+ acc1.id);
// Apex Program to Create a New Record in the Customer Object (Custom Object)
cust.Name = 'James';
cust.email_id__C = '[email protected]';
cust.contact_number__C = '4455662211';
cust.Country_name__c = 'India';
cust.State_name__c = 'Telangana';
cust.pan_number__C = 'alppb-9293-e';
cust.passport_number__C = '34567iuytr';
cust.mailing_address__c = '#309, SR Nagar, Hyderabad, 500038';
insert cust;
// Inserting a Record....
Account acc = new Account();
insert acc;
con.firstname = 'Suraj';
con.lastname = 'Kumar';
con.email = '[email protected]';
con.Phone = '1233225588';
con.HomePhone = '7788995577';
con.mobilephone = '9955660000';
con.fax = '8855998855';
con.ssn_number__c = '2255887744';
insert con;
------------------------
// Apex Program to Create a Contact and Associated to an Account, with
Hardcoded Account Id value.
insert con;
insert oppty;
Governor Limits:
================
- Salesforce provides a shared infrastructure to all the users, so that they can
install their required applications and accessed by their customers.
- If one user making the Salesforce server busy, by performing some continuous
operations, then other users will be in waiting stage. i.e other users are affecting.
These limits are applicable to all the users, who are accessing the salesforce
server.
Note:
While writing the code / Business logic, the developer has to keep in mind
about the governor limits.
Ex:
We can perform max. of 150 DML Operations in a Single Transaction.
Else, salesforce will raise "System.LimitException", which indicates
that you are crossing the Governor Limits for DML operations.
Sol:
To avoid this Exceptions, As a Best Practice, it is always
recommended to avoid the usage of DML statements inside the FOR loop.
Arrays (Disadvantages)
Collection Classes:
===================
Collection classes provide the following benifits.
Syntax:
List<DataType> <ObjectName> = new List<DataType>();
or
List<DataType> <ObjectName> = new List<DataType>{<elements
collection>};
Ex:
List<string> lstNames = new List<string>(); --> Collection of string elements
Note: We can able to create the Nested List (i.e. one List onto another List), upto
5 Levels.
Note:
List Collection will accept the Duplicate elements also.
Methods:
--------
1. Add(<ElementName>)
- This method will add the specified element at the end of the collection.
- Once the element is added to the collection, List will generates the index
position for the element.
Ex: lstNames.Add('Welcome');
lstNames.Add('Salesforce');
lstNames.Add('12345');
Ex: lstNames.Add('Hyderabad',1);
3. AddAll(<CollectionName>)
- This method will add All the elements avialable in the specified collection
to the end of the list.
4. Get(indexposition)
- It will return the element exist in the specified index position in collection.
Ex: lstNames.get(2);
5. Sort()
- It will arrange the collection elements in the ascending order.
Ex: lstNames.Sort();
6. integer Size()
- It will returns an integer, which indicates the number of elements
available in the collection.
Ex: lstNames.size();
7. Remove(<indexposition>)
- This method will remove the element from the collection exist at the
specified index position.
Ex: lstNames.Remove(2);
8. Clear()
- It will remove all the elements from the collection.
Ex: lstNames.Clear();
9. Set(index postition, elementName)
- It will update the elementName with the specified value exist at the
specified index position.
Sample Example:
---------------
// Creating the Object for List Collection class...
List<string> lstNames = new List<string>();
lstnames.Add('Ramesh Kumar');
lstnames.Add('Welcome');
lstnames.Add('Salesforce');
lstnames.Add('Hyderabad');
lstnames.Add('India');
lstnames.Add(4, 'Russia');
system.debug('Collection Elements After inserting in middle...: ');
for(string st : lstnames)
{
system.debug('Element Name : ' + st);
}
// Remove an element from the collection...
lstnames.remove(4);
system.debug('After Removing Elements...: ');
for(string st : lstnames)
{
system.debug('Element Name : ' + st);
}
Note:
SET collection, doesn't allow the duplicate elements.
i.e. If the user insert's a duplicate element, then SET doesn't add that
element into the collection. And It won't display any error message.
Syntax:
Set<DataType> <ObjectName> = new Set<DataType>();
Ex:
Set<Id> idSet = new Set<Id>();
Set<String> namesSet = new Set<String>();
Note:
SET and LIST collection classes will treat each element as an Object by
default.
1. Add(<ElementName>):
- This method will add a new element to the collection.
Ex: namesSet.Add('Welcome');
Ex:
namesSet.AddAll(coutrySet); // Set Collection
namesSet.AddAll(cityList); // List Collection
3. Boolean isEmpty()
- It returns TRUE, the Set Collection is Empty. Else it returns FALSE.
Ex: namesSet.isEmpty();
4. integer Size()
- It returns an integer, which counts the number of elemements exist in the
collection.
Ex: namesSet.Size();
5. Remove(<elementName>)
- It remove the specified elemement from the collection
Ex:
namesSet.Remove('Welcome');
6. Clear()
- It remove all the elemements from the collection.
Ex: namesSet.Clear();
7. Clone()
- It creates a copy of the Set collection.
Ex: namesSet.Clone();
// Eample...
Note:
To get the elments from the collection, we have to pass the KEY.
Syntax:
Map<Key,Value> mapObject = new Map<Key, Value>();
Ex:
Map<string, string> lstNames = new Map<string, string>();
1. Put(<Key>,<Value>)
- This function will add the new elemement to MAP collection.
Ex: mapNames.Put('Welcome','Salesforce');
2. Integer Size()
- It returns an ineger, which indicates number of elements exist in the
collection.
Ex: mapNames.size()
3. Set<> KeySet()
- It returns all the Key's exist in the map collection interns of SET collection.
Ex:
Set<string> keys = mapNames.KeySet();
4. List<> Values()
- It returns all the Values exist i the map collection interms of List
Collection.
5. Get(<KeyName>)
- It returns the value of the given Key element.
Ex: mapNames.Get('Welcome');
6. Bollean isEmpty();
- It returns TRUE, when the collection is Empty. Else it returns FALSE.
Ex: mapNames.isEmpty();
7. Remove(<KeyName>)
- It will remove the elemement from the collection, which is associated with
the given Key.
Ex: mapNames.Remove('Welcome');
8. Clear()
- It remove all the elemements from the collection.
Ex: mapNames.Clear();
// Example....
namesMap.Remove('Red');
- While performing the DML operations, salesforce provides the governor limits,
which allows us to perform max. of 150 DML operations in a single transaction.
- To perform more DML operations, we have to use "Bulkify DML operations",
which can be implemented by using collection classes.
- Always it is recommended to use "List" collection class to peform the DML
statements.
Database Class:
Database.Query(<Select Query>) --> USed to Retrieve the data from the object by
using the Query
Database.Insert():
==================
- We can insert one / more records at a time.
- Provides the option to allow partial processing.
- we can track the result of each operation (Success / Failed)
Syntax:
Database.insert(<ListObjectname>, boolean allowPartialProcessing);
Methods:
Database.Error: Class
--------------------
- To track the Error messages occured during the record processing.
Methods:
1. getFields() --> Returns the fields which causes the errors
2. getErrorMessage() --> Returns the Error Message
3. getStatusCode() --> return the Status code of the error.
Example...
----------
// Creating List Collection to store Account Records...
List<Account> lstAccount = new List<Account>();
SOQL Queries:
SOQL --> Salesforce Object Query Language.
-SOQL Queries are used to retrieve the records from salesforce objects(Standard /
Custom).
- We can retrieve one or more records from the object based on user defined
conditions to filter the records.
- To get the required records, we need to prepare an SOQL Query with the
reruired conditions.
Query:
------
Query is a request to the database to fetch records from database objects
based on required filters.
Note:
Column_Names : Use "Field Name" value of the field (Standard Field). If it is a
Custom field, then use "API Name (postfixed by __c)".
Note: We can retrieve the data from multiple columns. Where column names has
to be seperated by a comma.
Syntax:
Governor Limits:
----------------
1. We can have maximum of 100 SOQL Queries in a single transaction.
select firstname, lastname, email, phone, fax, title, mobilephone from contact.
// SOQL Query to display Account Name, Rating, Id, Active Status, Pan Number
from account object.
// SOQL Query to retrieve Position Id, Name, Status, Location, close date and
maximum pay values from position object.
Note:
Static SOQL query should be enclosed in "[ ]" (Square Braces)
Syntax:
[ <SOQL Query> ];
Ex:
[ select id, name, rating, industry from account ];
[ select firstname, lastname, phone, email, fax from contact];
[ select position_id__c, name, location__c, position_status__C from
position__c ];
LIMIT Clause:
=============
This clause is used to restrict the number of records to be returned by an SOQL
statement.
Syntax:
[ LIMIT <Number Of Records To Return> ];
Ex:
1. select id, name, rating, industry from account limit 1
Note: While executing static SOQL Query, it may return either one or mor records.
Ex:
Account acc = [select id, name, rating, industry from account limit 1];
Ex:
system.debug('Account Id is....: ' + acc.id);
system.debug('Account Name is....: ' + acc.name);
system.debug('Account Rating is....: ' + acc.rating);
// write an Apex Program to fetch Position record and display the record values.
Note: Write the below code in "Execute Ananymous window" and execute it.
Position__C pos = [select position_id__c, name, location__C, position_status__c,
close_date__c, maximum_pay__c from position__c limit 1];
if(pos != null)
{
system.debug('Position Id is.....: ' + pos.position_id__c);
system.debug('Position Name is....: ' + pos.name);
system.debug('Position Location ....: '+ pos.location__c);
system.debug('Position Status is....: ' + pos.position_status__c);
system.debug('Close Date is......: ' + pos.close_date__c);
system.debug('Maximum Pay is.....: ' + pos.maximum_pay__c);
}
- Once all the records has stored inside the collection, we need to fetch each
record from the collection and get the values from the record.
Syntax:
List<SObjectType> <ObjectName> = [ <SOQL Query returns more
records> ];
Ex:
List<Account> lstAccounts = [select id, name, rating, industry from account
limit 5 ];
// Display records....
if(! lstAccounts.isEmpty())
{
for(Account acc : lstAccounts)
{
system.debug('Account Name is....: ' + acc.name);
system.debug('Account Rating is....: ' + acc.rating);
system.debug('Account Type is....: ' + acc.type);
system.debug('Industry Name is....: ' + acc.industry);
system.debug('Annual Revenue is....: ' + acc.annualrevenue);
system.debug('Active Value is....: ' + acc.active__C);
system.debug('-----------------------------------------------');
}
List<Lead> lstLeads = [select firstname, lastname, email, fax, phone, status from
lead limit 10];
if(!lstLeads.isEmpty())
{
for(lead ld : lstLeads)
{
system.debug('Lead First Name is....: ' + ld.firstname);
system.debug('Last Name is....: ' + ld.lastname);
system.debug('Email Id is....: ' + ld.email);
system.debug('Phone Number is....: ' + ld.phone);
system.debug('Lead Status is....: ' + ld.status);
system.debug('-----------------------------------');
}
}
// Write an apex program to display first 10 leads from Lead object using MAP
collection.
if(! mapLeads.isEmpty())
{
for(Lead ld : mapLeads.Values())
{
system.debug('Lead Id is....: ' + ld.id);
system.debug('Lead First Name is....: ' + ld.firstname);
system.debug('Last Name is .....: ' + ld.lastname);
system.debug('Email Id is.....: ' + ld.email);
system.debug('Phone Number is....: ' + ld.phone);
system.debug('Lead Status is.....: ' + ld.status);
system.debug('------------------------------------------');
}
}
// Write an Apex program to display the first 5 opportunity records from
opportunity object using Enhanced FOR Loop.
WHERE Clause:
Note:
1. Using WHERE clause is an optional statement in SOQL Queries.
2. If the user didn't use the WHERE clause, then SOQL query will returns all
the records from the object.
- User needs to define his own conditions based on one or more columns as
below.
Syntax:
[WHERE <Conditions>]
Query:
Code:
-----
List<Account> lstAccounts = [select name, rating, industry, annualrevenue,
active__c from account where rating =: 'Warm'];
if(!lstAccounts.isEmpty())
{
for(Account acc : lstaccounts)
{
system.debug('Account Record is.....: ' + acc);
}
}
// Write an Apex Program to display Account records, which are "InActive" and
Whose AnnualRevenue is morethan 100000.
if(!mapAccounts.isEmpty())
{
for(Account acc : mapAccounts.values())
{
system.debug('Account Id is.....: ' + acc.id);
system.debug('Account Name is....: ' + acc.name);
system.debug('Account Rating Value is....: ' + acc.rating);
system.debug('Annual Revenue is.....: ' + acc.annualrevenue);
system.debug('Active Status is......: ' + acc.active__C);
system.debug('Record Type Name is....: ' + acc.recordtype.name);
system.debug('-------------------------------------------');
}
}
if(!lstRecTypes.isEmpty())
{
for(RecordType rType : lstRecTypes)
{
system.debug('Record Type Id...: ' + rType.ID + ' ----> Name : ' +
rType.Name);
}
}
// Write an Apex Program to display Account Records which are associated with
"Existing Customer RecordType".
Id accId = acc.Id;
if(accID != null)
{
// Fetch contact records...
List<Contact> lstContacts = [select firstname, lastname, email, phone, fax from
contact where accountid =: accid];
if(!lstContacts.isEmpty())
{
for(Contact con : lstContacts)
{
system.debug('Contact First Name....: ' + con.firstname);
system.debug('Contact Last Name......: ' + con.lastname);
system.debug('Email ID ......: ' + con.email);
system.debug('Phone Number is.....: ' + con.phone);
system.debug('Fax Number is.....: ' + con.fax);
system.debug('----------------------------------');
}
}
// Fetch Opportunity records...
List<Opportunity> lstOpptys = [select name, stagename, closedate from
opportunity where accountid =: accId];
if(! lstOpptys.isEmpty())
{
for(Opportunity oppty : lstOpptys)
{
system.debug('Opportunity Name : ' + oppty.Name);
system.debug('Opportunity Stage Name ....: ' + oppty.StageName);
system.debug('Close Date is.....: ' + oppty.closedate);
system.debug('--------------------------------------');
}
}
}
// Write an Apex Program to fetch all Candidate details, who has applied for the
position "Java Developer".
// Write an Apex Program to fetch all activities(Task and Event) associated with
the account "Reliance Industries".
Order By Clause:
- This Clause is used to sort / arrange the resultset records either in Ascending /
Descending order, based on one or more columns.
Note:
Order By Clause is an optional statement in SOQL Query.
Syntax:
[ ORDER BY <Column Names> [ <Ascending / Descending> ] ]
Note:
Specifying the Sorting order (Asc / Desc) in Order by clause is optional.
If the user specify any order (Asc / Desc), then the records will be sorted
based on the specified order.
Else it will sort the records in Ascending order by default.
Ex:
Order by <Column Name> [<Asc / Desc>].
// Write an Apex Program to display the Position records and arrange the records
based on Name column in Ascending Order.
List<Position__C> lstPos = [select position_id__C, name, location__C,
position_status__C, close_date__C, maximum_pay__c from position__C order by
name ];
if(! lstPos.isEmpty())
{
for(Position__C pos : lstPos)
{
system.debug('Position Name ....: ' + pos.Name);
system.debug('Position Id is....: ' + pos.id);
system.debug('Location is.....: ' + pos.location__C);
system.debug('Position Status is...: ' + pos.position_status__C);
system.debug('Close Date is.....: ' + pos.close_date__C);
system.debug('----------------------------------------');
}
}
// Write an Apex Program to display All Account records associated with Banking
industry and Whose Annual Revenue is not null and arrange the records in
Descending order based on Created date.
if(!lstAccounts.isEmpty())
{
for(Account acc : lstAccounts)
{
system.debug(acc.Name + ' -- ' + acc.Createddate + ' -- ' + acc.Rating + ' -- '+
acc.industry);
}
}
// write an apex program to display all the position records and the associated
candidate records(applied candidates) in descending order based on created
date.
ALL ROWS:
- ALL ROWS Clause is used to retrieve the records information, which are exist in
the object or removed from the object (i.e Display in Recycle Bin).
- By using ALL ROWS clause we can display deleted records also from recycle bin.
Note: All Rows statement should be the last statement in SOQL Query.
Note: Each Salesforce Object contains a Hidden field called as "isDeleted", which
is a Boolean field. Which indicates whether the record is deleted from the object
or not.
- If the record is deleted from the object, then the record will hold the value for
this field as "TRUE". Else the record will hold the value for this field as "FALSE".
i.e isDeleted = TRUE --> Deleted Record.(Exist in Recycle Bin)
isDeleted = FALSE --> Record Not deleted(Exist in the Object)
// Write an Apex Program to display all position records (Both exist in the object
and deteted from the object.)
if(! lstPosition.isEmpty())
{
for(Position__c pos : lstPosition)
{
system.debug(Pos.Name + ' -- '+ pos.position_id__C + ' -- '+ pos.Location__c);
}
}
if(! lstPosition.isEmpty())
{
for(Position__c pos : lstPosition)
{
system.debug(Pos.Name + ' -- '+ pos.position_id__C + ' -- '+ pos.Location__c);
}
}
Dynamic SOQL Queries:
- Dynamic SOQL Queries are used to prepare the SELECT statement at run time
based on the user input.
- We need to add the conditions to SOQL Query at run time and store the query in
a string variable.
Ex:
string soqlQuery = 'select id, firstname, lastname, email, phone, fax from
contact ';
.....
.....
Statements..
.....
soqlQuery += ' Where email=: <value>';
Once, SOQL Query has been prepared, then we need to execute the Query at Run
time by using "Database" class .
Note: Always Database.Query() method will returns the resultset in terms of List
Collection.
if(!lstCands.isEmpty())
{
for(Candidate__C cnd : lstCands)
{
system.debug('Candidate Id is....: ' + cnd.id);
system.debug('Candidate Name is....: ' + cnd.name);
system.debug('Location is....: ' + cnd.location__C);
system.debug('Contact Number is....: '+ cnd.contact_Number__c);
system.debug('Email Id is.....: '+cnd.email_id__c);
system.debug('-------------------------------');
}
}
// Write an Apex program to display all contact records based on the user input.
Note: We need to check the input is in the form on Email or a string.
string soqlQuery ='select id, firstname, lastname, email, fax, phone from contact
where ';
if(!lstContacts.isempty())
{
for(Contact con : lstContacts)
{
system.debug('Contact Id is.....: '+ con.id);
system.debug('Contact First Name is....: '+ con.firstname);
system.debug('Contact Last Name.....: '+ con.lastname);
system.debug('Email Id is.....: ' + con.email);
system.debug('Phone Number is....: ' + con.phone);
system.debug('-------------------------------------');
}
}
LIKE Operator:
- LIKE operator is used to retrieve the similar kind of information from the
database object.
Note: LIKE operator should be used along with the WHERE clause always.
Syntax:
<Column Name> LIKE <Expression>
- While using the Like operator, we need to specify the expression, based on
which we need to search the information from table column.
Note: Expression can be perpared with the help of "Wild Card Characters".
Ex:
Where name LIKE 'Rame%';
// Write an Apex program to display all the position records which related to
"java" programing.
if(!lstPos.isEmpty())
{
for(Position__C pos : lstPos)
{
system.debug('Position Id is.....'+pos.id);
system.debug('Position Name is....: ' + pos.name);
system.debug('Location......: '+pos.location__c);
system.debug('Position Status.....: '+ pos.position_status__c);
system.debug('Close Date is.....: '+ pos.close_date__C);
system.debug('-------------------------------------------');
}
}
// Write an Apex program to display all the contact records, whose names are
ends with the word "Kumar".
string soqlQuery ='select id, firstname, lastname, name, email, fax, phone from
contact where name like : nameEndsWith';
if(!lstContacts.isempty())
{
for(Contact con : lstContacts)
{
system.debug('Contact Id is.....: '+ con.id);
system.debug('Contact First Name is....: '+ con.firstname);
system.debug('Contact Last Name.....: '+ con.lastname);
system.debug('Email Id is.....: ' + con.email);
system.debug('Phone Number is....: ' + con.phone);
system.debug('-------------------------------------');
}
}
// Write an Apex program to Delete All the Accounts whose names arfe starts
with "Database".
if(!lstPositions.isEmpty())
{
for(Position__C pos : lstPositions)
{
system.debug('Position Record.....: ' + pos);
List<Candidate__C> lstCan = [select id, name, email_id__c,
contact_Number__c from candidate__C where position__c =: pos.Id];
if(!lstCan.isEmpty())
{
for(candidate__C can : lstCan)
{
system.debug(can);
}
}
else
{
system.debug('No Candidates Found.');
}
}
}
Note: Database class Provides the flexibility to Perform the Partial Processing.
i.e. We can continue with the other records, even though it encounter
some errors while execution.
By using Database class, we can able to TRACK the result of each operation.
Note:
The Return Type of thise methods is "Database.SaveResult[]"
Ex:
Note:
The Return Type of thise methods is "Database.SaveResult[]"
Ex:
Note:
The Return Type of thise methods is "Database.DeleteResult[]"
Ex:
Note:
The Return Type of thise methods is "Database.UpsertResult[]"
Ex:
Note:
The Return Type of this methods is "Database.UndeleteResult[]"
Ex:
Database.UndeleteResult[] result =
Database.UnDelete(<List_ObjectName>, boolean AllORNothing);
9. Database.QueryLocator
10. Database.EmptyRecycleBin(List<ID>)
Database.EmptyRecycleBinResult[] result = Database.EmptyRecycleBin(List<Id>);
This method is used to remove the specified records from the RecycleBin.
// Write an Apex Program to update the Ownership field value as "Private" for all
the account records
//starts with "Account Insert"
if(! lstAccounts.isEmpty())
{
for(Account acc : lstAccounts)
{
acc.Ownership = 'Private';
}
update lstAccounts;
}
// write an Apex Program to update the Rating value as "Warm" and Industry as
"Finance" for the Account "Edge Communications".
update lstAccounts;
}
// Write an Apex Program to update All Associated Contacts Phone number value
with the Account Record's Phone value, upon updating Account Records Phone
Number.
Account acc =[select id, name, rating, Industry,Phone, ownership from account
where name =: 'Edge Communications'];
system.debug('Account Record value is....: ' + acc);
acc.Phone = '1122334455';
Update acc;
if(acc.id != null)
{
Id accRecordId = acc.id;
List<Contact> lstContacts = [select id, firstname, lastname, phone from contact
where accountid =: accRecordId];
if(!lstContacts.isEmpty())
{
for(Contact con : lstcontacts)
{
con.Phone = acc.Phone;
}
Database.SaveResult[] results = Database.update(lstContacts);
}
}
GROUP BY Clause:
================
- Group By clause is used to group the records information based on either one or
more columns.
Aggregate Functions:
--------------------
These functions will receive a collection of records as an input and generate only
one value as a Result.
1. SUM(<ColumnName>)
It will return the Sum of all the values exist in the specified column.
Ex:
Select Sum(AnnualRevenue) from account group by Rating.
2. AVG(<ColumnName>)
It returns Average of all the values exist in the specified column.
3. MIN(<ColumnName>)
It returns the smallest value exist in the specified column.
4. MAX(<ColumnName>)
It returns the Largest value exist in the specified column.
5. COUNT()
It counts the number of records exist in the object.
6. COUNT(<ColumnName>)
It returns the count of values exist in the specified column.
7. COUNT_DISTINCT(<ColumnName>)
It returns the count of values exist in the specified column.
Note:
It won't count the NULL Values and Duplicate Values exist in the
specified column.
Note:
Group By clause is an optional statement in SOQL Query.
Syntax:
if(aggResults.size() > 0)
{
for(AggregateResult result : aggResults)
{
system.debug('Rating : ' + result.get('Rating') + ' -----> Record Count : ' +
result.get('RecordsCount'));
}
}
Note:
While retrieving the records by using Aggregate Functions in the Query,
then the ResultSet should be of type "AggregateResult[]" class.
// Write an Apex Program to display the number of records exist in the Account
object.
//Static SOQL Query..
HAVING Clause:
==============
- Having clause is used to Add the Filters / Conditions along with the Group by
clause.
- While grouping the records using "Group By clause", we can apply the conditions
with the help of "Having Clause".
Syntax:
[ Having <Conditions>]
// Apex Program to display the Account Records Count based on Rating, Whose
Record Count is more than 20 records.
// Apex Program to display the Duplicate Records exist in the Account Object.
system.debug(aggResult.size());
Relationship Queries:
=====================
Relationship queries are used to retrieve the data from two or more salesforce
objects which are associated with each other.
- By using relationship queries, we can retrieve the data from both standard
objects and custom objects.
Note:
While using relationship queries, the target objects should be associated with
each other by using either Lookup or Master-Detail Relationship.
- We need to use a single SOQL Query to retrieve records from multiple objects.
- We can fetch the record information from Parent to Child Record or from Child
Record to Parent Records.
Parent To Child:
----------------
-This approach provides the ability to retrieve the Parent Record Details and along
with its associated child record details also.
// Apex Program to Display the Account Record, along with its associated Contact
records using relationship queries.
if(lstAccounts.size() > 0)
{
for(Account acc : lstAccounts)
{
system.debug('Account Id ....: ' + acc.id);
system.debug('Account Name ....: ' + acc.name);
system.debug('Account Rating ....: ' + acc.rating);
system.debug('Account Type ....: ' + acc.type);
system.debug('Account AnnualRevenue ....: ' + acc.AnnualRevenue);
system.debug('Contact Records....');
system.debug('Contacts Count.....: ' + acc.contacts.size());
// Apex Program to display Account Record and its associated Contact and
Opportunities also..
List<Account> lstAccount = [ select id, name, Rating, Active__c, annualrevenue,
industry,
(select id, firstname, lastname, email, phone, fax from
Contacts),
(select id, name, closedate, amount, stagename from
opportunities)
from account ];
if(!lstAccount.isEmpty())
{
for(Account acc : lstAccount)
{
system.debug('Account Record is....: '+ acc);
system.debug('--------------------------------------');
}
Child To Parent:
----------------
-This approach provides the ability to retrieve the Child Record Details and along
with its associated Parent record details also.
Ex:
Account.Rating, Account.Type, Account.AnnualRevenue, etc.
// Apex Program to Fetch the Contact Record and along with it's Parent Account
Record Details also.
if(lstContacts.size() > 0)
{
system.debug('Resultset Count....: ' + lstContacts.size());
/*
Write an Apex Program to display All Opportunity Records and along with all
associated Account Records,Whose Rating is "Warm" and AnnualRevenue is >
200000.
*/
if(!mapOpptys.isEmpty())
{
for(Opportunity oppty : mapOpptys.values())
{
system.debug('Opportunity Name ....: ' + oppty.Name);
system.debug('Close Date is.....: ' + oppty.CloseDate);
system.debug('Amount is.....: ' + oppty.Amount);
system.debug('Opportunity Stage is....: ' + oppty.Stagename);
system.debug('Account Name is....: ' + oppty.Account.Name);
system.debug('Account Rating ....: ' + oppty.Account.Rating);
system.debug('Account Annual Revenue is....: ' +
oppty.Account.AnnualRevenue);
system.debug('--------------------------------------------------');
}
}
Note:
Always Inner queries will execute first. Based on the result returned by the
inner query, Outer query will get execute.
SOSL Statements:
================
- By using this SOSL Statements, we can search for the information from 20
objects at a time by using a single query.
- SOSL statements can interact with either one or more objects at a time.
- SOSL Query will search the keyword in all the fields available in the object. Or
else we can specify the field names in which we want to search.
Governor Limits:
----------------
1. We can have max. of 20 SOSL Queries in a Single Transaction.
2. Each SOSL Query can returns max. of 2000 records.
3. One SOSL Query can search the keyword in 20 objects
Note:
SOSL Queries can't be supported in Triggers. i.e. we can implement the
SOSL queries only in Apex Classes.
Ex:
Search.Query(<SOSL Query>);
Note:
SOSL Statements will return the results in the form of "List<List<SObject>> "
Ex:
Static SOSL Query:
-------------------
List<List<SObject>> lstObject = [ < SOSL Query>];
- We can get the resultset which contains the records information from max of 20
objects.
- FIND keyword will search the required keyqord "SearchKeyword%" in all the
fields exist in the specified objects.
If any of the record in the objects found the search keyword, then it will return
the record will the specified fields information.
Ex:
[ FIND 'test*' IN ALLFIELDS RETURNING
Account(Name, Rating, Industry, Type, Site),
Contact(firstname, lastname, email, phone, fax),
Opportunity(name, amount, stagename, closedate),
Case(name, status, priority, description),
....
....
upto 20 objects.
]
List<List<SObject>> lstObjects = [
FIND 'apex*' IN ALL FIELDS RETURNING
ACCOUNT(Name, Rating, Industry, AnnualRevenue, Active__c),
Contact(firstname, LastName, Email, Phone, fax),
Opportunity(Name, stagename, closedate, amount),
Position__C(name, position_status__C, location__c, close_date__c,
maximum_pay__C),
Candidate__C(Name, Email_id__c, contact_number__c)
];
if(!lstAccounts.isEmpty())
{
system.debug('Account Records Size....: ' + lstAccounts.size());
if(!lstOppty.isEmpty())
{
system.debug('Opportunity Records size....: ' + lstOppty.size());
for(Opportunity oppty : lstOppty)
{
system.debug('Opportunity Record...: ' + oppty);
}
}
if(!lstPos.isEmpty())
{
system.debug('Position Records Count....: ' + lstPos.size());
for(Position__c pos : lstPos)
{
system.debug('Position Record....: ' + pos);
}
}
if(! lstCand.isEmpty())
{
system.debug('Candidate Records Count...: ' + lstCand.size());
for(Candidate__C c : lstCand)
{
system.debug('Candidate Record is....: ' + c);
}
}
Assignment:
===========
1. Create an Apex Class to Manage Account Records
1.1. We can able to search the Account with the Name / ID
1.2. CreateNewAccount() method.
This should receive the required parameters as an input, and insert
the record into the Account Object.
Note: It should not accept the Duplicate Records. (Can be identified by
using Account Name)
1.3. Update the Account Records with the New Values.
1.3.1. We can update either Single Record
1.3.2. We can update Group of Records.
1.4. SearchAccountRecords(FromDate, ToDate) Methods.
- This method has to display all the Account records which has been
created between the Two Specified dates.
1.5. Delete the Account Records from RecycleBin, which are older than 10
days.
Implementation:
===============
public class AccountsUtility
{
public boolean IsAccountExistByName( string accountName)
{
integer recordsCount = [select count() from account where name =:
accountName];
if(recordsCount > 0)
return true;
else
return false;
}
insert acc;
return acc.id;
}
if(recordId != null)
system.debug('Account Record Inserted Successfully. Record Id is...: ' +
recordId);
else
system.debug('Duplicate Account record.');
if(isexist)
system.debug('Account Record Exist.');
else
system.debug('Account Record Not Found.');
Triggers:
- These are the Custom Business Logic, Which execute based on DML Operations
- Trigger will perform the Asynchronous operations
- By using Trigger we can implement complex business logic
- We can implement complex validation Rules.
Workflow:
1. We can automate the actions using workflow. We can automate the actions as
below
1. Send Email Notification
2. Assign a New Task
3. Update the Field
4. Send an Outbound Message
Trigger Events:
1. Before Insert
2. Before Update
3. Before Delete
4. After Insert
5. After Update
6. After Delete
7. After UnDelete
Syntax:
Trigger <Trigger_Name> ON <Object_Name> ( <Trigger Events>)
{
// Business Logic..
Example:
1. Trigger.IsInsert:
- It returns TRUE, when the trigger has fired on Insert Operation. Else it
returns FALSE.
2. Trigger.IsUpdate:
It returns TRUE, when the trigger has fired on Update Operation. Else it
returns FALSE.
3. Trigger.IsDelete:
It returns TRUE, when the trigger has fired on Delete Operation. Else it
returns FALSE.
4. Trigger.IsUnDelete:
It returns TRUE, when the trigger has fired on UnDelete Operation. Else it
returns FALSE.
5. Trigger.IsBefore:
It returns TRUE, when the trigger has fired on Before performing the DML
Operation. Else it returns FALSE.
6. Trigger.ISAfter:
It returns TRUE, when the trigger has fired on After performing the DML
Operation. Else it returns FALSE.
Ex:
Trigger.New:
------------
- It Contains the Current Context Records, while performing the Insert & Update
Operations in the Object.
Trigger.Old:
------------
- It Contains the Previous Context Records, while performing the Update, Delete
and UnDelete operations in the object.
Trigger.NewMap:
---------------
It Contains the Current Context Records in the form of MAP collection.
Note:
It will be availabe in After Insert, Before Update and After Update Events.
(Not applicable for "Before Insert" event)
Trigger.OldMap:
---------------
It Contains the Previous Context Records in the form of MAP Collection.
i.e MAP is a Key, Value pair collection.
Note: While writing the Trigger, it should handle operations on both Single record
as well as Bulk Records also.
Ex:
Object Name: Account
Operation : Inserting the new records.
Event : Before
Ex:
Object Name: Candidate__C
Operation : Deleting the records.
Event : Before / After
Creating Triggers:
- We have the Following ways to create the Trigger.
1. Standard Navigation:
Goto Setup --> Got to Build --> Click on Develop --> Click on "Apex Triggers"
--> Write the Trigger Code --> Save.
2. Developer Console:
Goto Your Name --> Click on "Developer Console" --> Click on File Menu --
> Select the New Menu Item --> Click on Apex Trigger Menu Item --> Enter the
Trigger Name --> Select the Object Name from the Picklist --> click on OK.
3. Eclipse IDE.
if(customerCount > 0 )
{
cust.Name.AddError('Customer Record is Already Exist. Please
select a New Name.');
}
}
}
// Create a Trigger to make Phone Number, Email Id and Fax Number on Contact
Record is Mandatory..
if(stdcode == '040')
con.Location__c = 'Hyderabad';
else if(stdcode == '080')
con.Location__c = 'Bangalore';
else if(stdcode == '044')
con.Location__c = 'Chennai';
else if(stdcode == '020')
con.Location__c = 'Pune';
else if(stdcode == '022')
con.Location__c = 'Mumbai';
else if(stdcode == '012')
con.Location__c = 'Noida';
else if(stdcode == '048')
con.Location__c = 'Kochi';
}
}
}
}
/* Trigger To delete the associated Contact records upon deleting the Parent
Account Record. And Make the Associated opportunities as it is, upon deleting
the parent account.
*/
if(! lstContacts.isEmpty())
Delete lstContacts;
if(! lstOppty.isEmpty())
{
for(Opportunity opp : lstOppty)
{
opp.accountid = null;
}
update lstOppty;
}
}
}
Custom Settings:
- Custom Settings are also like as Custom Objects, Where we can store the
information by creating the fields.
1. Salesforce.com introduced Custom Setting, which allows you to store custom
data sets and associate them on an org-wide, profile or user basis.
2. Custom Settings are essentially custom objects that are exposed in the
applications cache and are accessible via their own API.
3. You can certainly build your own custom objects to store settings but using
custom settings is much quicker (again they are stored in the application cache)
and do not count against SOQL limits when fetched.
4. You can also use custom settings in formula fields, validation rules, Apex code
and the Web Services API.
Note: When you create a new custom settings the platform creates a custom
object in the background for you (notice the API Name field). You then add
additional fields to the custom setting in the same manner that you do for custom
objects
- Always it is recommended to use the Custom Settings while storing the Static
information. Instead of wasting one Custom Object.
- In Custom object, we have to retrieve the data by writing the SOQL Queries.
Note:
1. Whereas in Custom Settings, We can retrieve the Data without writing
any SOQL queries.
2. Custom Settings Data will be storing into the Application Cache. So that
we can efficiently use the records.
Goto Setup --> Goto Develop --> Click on Custom Settings --> Click on "New"
Button
- Enter the Custom Setting Label and Unique Name
- Select the Type as "List"
- Select the Accessibility as "Public"
- Click on "Save"
Creating Field 1:
- Goto the Custom Field Section
- Click on New, Select the Field Type as "Text" Enter the Name : "Region
Name"
- Click on Save
Creating Field 2:
- Goto the Custom Field Section
- Click on New, Select the Field Type as "Text" Enter the Name : "Region
Manager Name"
- Click on Save
Syntax:
Map<string,Custom_Setting_Name> <objName> =
<Custom_Setting_Name>.getAll();
Ex:
Map<string, QEdgeRegionalInformation__c> =
QEdgeRegionalInformation__c.getAll();
QEdgeRegionalInformation__c reg =
QEdgeRegionalInformation__c.getInstance(‘Americas’);
QEdgeRegionalInformation__c reg =
QEdgeRegionalInformation__c.getValues(‘Americas’);
cust.Region_Manager_Name__c =
mapRegions.get(cust.Region_Name__c).Manager_Name__c;
}
}
}
/**
@Author: Feroz Beg
@name: StaffMethods
@CreateDate:
@Description: This class provides the ability to get All Active users.
@Version: 1.0
@reference:
*/
return mapActiveUsers;
}
}
----------------------------
/**
@Author: Feroz Beg
@name: LeadHandler
@CreateDate:
@Description: This class provides the ability to Handle the Lead to Prospect
Synchronization.
@Version: 1.0
@reference:
*/
if(l.Do_Not_Create_Opportunity__c == true)
{
lc.SetDoNotCreateOpportunity(true);
}
lstConverts.add(lc);
}
}
if(!lstConverts.isEmpty())
{
try
{
lcResults = Database.convertLead(lstConverts);
}
Catch(DMLException d)
{
system.debug('DML Exception Occured during Lead Conversion.' +
d.getMessage() + '-- StackTrace string :'+ d.getStackTraceString());
}
Catch(Exception e)
{
system.debug('Exception Occured during Lead Conversion.' +
e.getMessage() + '-- StackTrace string :'+ e.getStackTraceString());
}
}
}
for(Lead ld : lstLeads)
{
Prospect__c p = new Prospect__c();
p.FirstName__c = ld.FirstName;
p.Name = ld.LastName;
p.Phone__C = ld.Phone;
p.Email__c = ld.Email;
p.Fax__c = ld.Fax;
p.Rating__c = ld.rating;
p.Industry__C = ld.Industry;
p.Lead_Source__C = ld.LeadSource;
p.Passport_Number__c = ld.Passport_Number__c;
p.ssn_Number__c = ld.ssn_Number__c;
p.Product_interest__c = ld.ProductInterest__c;
p.Primary__c = ld.Primary__c;
p.Company__c = ld.Company;
p.Website__C = ld.Website;
p.Annual_Revenue__c = ld.annualrevenue;
p.Lead__C = ld.id;
lstProspects.Add(p);
}
try
{
if(!lstProspects.isEmpty())
insert lstProspects;
}
catch(DMLException dex)
{
system.debug('DML Exception Occured during Prospect Creation.' +
dex.getMessage() + '-- StackTrace string :'+ dex.getStackTraceString());
}
// This method will update the associated Prospect Record, upon updating
the Lead record.
Public static void AfterUpdate(Map<Id,Lead> mapLeads, Map<Id,Lead>
oldLeads)
{
List<Prospect__c> prospectsToUpdate =new List<Prospect__C>();
if(!lstProspects.isEmpty())
{
for(Prospect__C p : lstProspects)
{
for(Lead l : mapLeads.values())
{
if(p.Lead__c == l.id)
{
p.FirstName__c = l.FirstName;
p.Name = l.LastName;
p.Phone__C = l.Phone;
p.Email__c = l.Email;
p.Fax__c = l.Fax;
p.Rating__c = l.rating;
p.Industry__C = l.Industry;
p.Lead_Source__C = l.LeadSource;
p.Passport_Number__c = l.Passport_Number__c;
p.ssn_Number__c = l.ssn_Number__c;
p.Product_interest__c = l.ProductInterest__c;
p.Primary__c = l.Primary__c;
p.Company__c = l.Company;
p.Website__C = l.Website;
p.Annual_Revenue__c = l.annualrevenue;
prospectsToUpdate.Add(p);
}
}
}
try
{
if(!prospectsToUpdate.isEmpty())
update prospectsToUpdate;
}
catch(DMLException e)
{
system.debug('DML Exception Occured during Prospect Creation.' +
e.getMessage() + '-- StackTrace string :'+ e.getStackTraceString());
}
}
}
}
Email Programming:
==================
-There may be situations in which you would not want a workflow email alert,
because either your criteria to send an email may be too complex or the person
whom you want to send an email has to be determined dynamically.
-In such situations you can choose to send an email from a Apex Class.
- While sending/ Receiving the emails, we can add the Attachments also.
Note: All Email Classes are available in the "Messaging" name space.
Governor Limits:
In s single transaction, we can have 10 email invocations.
i.e Maximum of 10 Messaging.SendEmail() methods per Transaction.
Inbound Email:
--------------
- This service is used to receive the Emails from the users or external systems.
i.e Email is coming into our Salesforce instance.
1. Messaging.SingleEmailMessage Class
2. Messaging.MassEmailMessage Class
Messaging.SingleEmailMessage:
----------------------------
- This class is used the send the Email to the specified user with the user defined
content and Subject.
Methods:
1. SetToAddresses(<Collection>)
To specify the To Address in terms of String Array or List collection.
Note: The maximum allowed ToAddresses is 100.
2. SetCCAddresses(<Collection>)
To specify the one or more CC Email Addresses.
Note: The maximum allowed is 25
3. SetBccAddresses(<Collection>)
To specify one or more BCC Email Addresses
Note: The maximum allowed is 25
4. SetReplyTo(string)
To specify the Reply-To Email Address
5. setSenderDisplayName(string)
To specify the Sender Display Name "Ex: Salesforce Support"
6. SetSubject(string EmailSubject)
To specify the Email Subject
7. SetPlainTextBody(string emailContent)
To specify the Email Content in plain text format.
8. SetHTMLBody(string emailHTMLContent)
To specify the email Content in HTML format
Messaging.MassEmailMessage:
---------------------------
- This class is used to send the Bulk Email to the Salesforce users(Contacts/
Accounts / Leads).
Methods:
--------
1. SetTargetObjectIDs(List<ID>): We have to pass the list of users/Contacts
id's to send the mass emails
======================================================
Email Class:
============
// Apex Class to send the mail to the specified recipients..
email.setSubject( emailSubject );
email.setToAddresses( toAddresses );
email.setHtmlBody(emailContent );
Messaging.SendEmailResult [] result =
Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});
System.debug('*****' + emailContent);
System.debug('****** Email Has been sent successfully to the candidate.');
}
}
------------------------------------
email.setHtmlBody('Your Account has been Created. Account Id is..: <b>' + accId
+ '</b>.<p> To View Your Account Click on the below link. <a
href=https://ap2.salesforce.com/'+accId+'> Click Here </a>');
--------------------
email.setToAddresses(toAddress);
email.setCCAddresses(ccAddress);
email.setBccAddresses(bccAddress);
email.setReplyTo('[email protected]');
email.setSubject(emailSubject);
email.setPlainTextBody(emailContent);
if(lstcontacts.size() > 0)
{
lstId = new List<Id>();
Messaging.reserveMassEmailCapacity(4);
Messaging.MassEmailMessage email = new
Messaging.MassEmailMessage();
email.SetTargetObjectIds(lstId);
email.SetTemplateId('00X28000000MAJTEA4');
Messaging.sendEmail(new Messaging.MassEmailMessage[] {email});
}
}
}
// Sending Attachments...
email.setHtmlbody(htmlBody);
if(att.size() > 0)
{
for(Attachment at : att)
{
Messaging.EmailFileAttachment file = new
Messaging.EmailFileAttachment();
file.setFileName(at.name);
file.setBody(at.Body);
file.setContentType(at.contenttype);
fileatt.add(file);
}
}
email.setFileAttachments(fileatt);
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { email });
}
}
if(hManager != null)
{
toAddresses = new string[2];
toAddresses[0] = hManager.Email_ID__c;
toAddresses[1] = '[email protected]';
}
email.SetToAddresses(toAddresses);
//email.SetFromAddres('[email protected]');
email.Subject = emailSubject;
email.SetHTMLBody(emailContent);
}
Messaging.sendEmail(new Messaging.SingleEmailMessage[]{email});
}
}
}
}
}
}
}
}
// Apex Class to send Email Notifications...
if(cndRec != null)
{
Candidate__C cnd = [select id, name, email_id__C, Location__c,
PositionName__c from Candidate__C where id =: cndRec.id limit 1];
email.SetToaddresses(toAddress);
email.SetSubject(emailSubject);
email.SetReplyTo(cnd.email_id__C);
email.SetSenderDisplayName('QEdge Support Center');
/*
// To Send the Plain Text Information..
string emailContent = 'Hi '+ cnd.Name + 'Thanks for apllying for the position
' + pos.Name + '. We will have a look into your profile and out HR Team will get
back to you shortly. Thanks & Regards, ABC Technologies ';
email.SetPlainTextBody(emailContent);
Messaging.SendEmail(new Messaging.SingleEmailMessage[]{email});
}
}
}
1. Trigger should support bulk records as well - Always use "For Loop" to process
records inside the trigger
5. Do not use DML operations inside the for loop. Add them to the list and
update/insert/delete the list out side the for loop.
7. Write the Proper Test Classes for the Trigger. And maintain minimum 1% of
code coverage for each trigger. And Overall organization wide, we have to
maintain 75% of code coverage while moving the code from sandbox to
production environment.
Note:
Recursive Triggers can be avoided by using the "Static Boolean" variables.
Do not execute the trigger on all the update. Only execute the trigger on
specific update.
Here the trigger will get executed on update of stagename field only and
will not trigger on other field's update
Error Code:
if(Trigger.isUpdate && opp.stagename == 'Qualification')
opptyIds.add(opp.Id);
9. As a Best Practice, it is Recommended to maintain only One Trigger per an
Object. Because, We dont have the option in salesforce to control the execution
order of triggers.
sample.ShowMessage();
sample.Display();
Sample.Addition(400,2300);
sample.Division(500,40);
sample.CheckEqual('Hyderabad','hyderabad');
--------------------------------
// Sample Static Method...
Public class StaticDemoClass
{
Public string customerName;
/*
StaticDemoClass s;
s = new StaticDemoClass();
*/
// Static Member...
StaticDemoClass.country = 'India';
system.debug('Country Name is.....: ' + StaticDemoClass.country);
// Static Member...
system.debug('Country Name is.....: ' + StaticDemoClass.country);
Functions:
==========
// Apex class to demonstrate the Functions...
Integer mulResult;
mulResult = m.Multiplication(200,34,45);
system.debug('Multiplication Result is....: '+ mulResult);
=========================================
// Apex class to perform string operations...
--------------- Execution....
================================
// Apex class to manage the Account Details...
if(recordId != null)
{
acc= [select id, name, rating, industry, type, annualrevenue, active__c from
account where id =: recordId limit 1];
}
return acc;
if(accId != null)
{
lstContacts = [select id, firstname, lastname, email,
phone, fax from contact where accountid =: accId];
}
return lstContacts;
}
}
return lstOppty;
}
}
// Execution:
============
// Calling the class method...
Account acc = AccountsHelper.GetAccountById('0012800000EWQ2r');
if(acc != null)
{
system.debug('Account Id is....: ' + acc.id);
system.debug('Account Name is....: ' + acc.name);
system.debug('Account Rating is....: ' + acc.Rating);
system.debug('Industry is....: ' + acc.industry);
system.debug('Type is....: ' + acc.type);
system.debug('Annual Revenue is.....: ' + acc.annualrevenue);
}
// Getting Contacts...
List<Contact> lstCon = AccountsHelper.GetContacts('001280000076fw2');
if(!lstCon.isEmpty())
{
for(Contact con : lstCon)
{
system.debug('Contact Record is....: ' + con);
}
}
- To implement the Batch Apex, we have to implement our class with an Interface
called as "Database.Batchable<sobject>".
Note: Batch Apex class should be defined as "Global". Because these Batch /
Schedule classes should be executed by the other resources of Salesforce.
Syntax:
Global Class <Class_Name> implements Database.Batchable<Sobject>
{
// Write Business Logic..
}
- It divide the all the records into the various batches of specified size.
- Batch size can be between 1 to 2000. Default batch size is 200.
- It will pass each batch records to the "Execute" method to perform the
DML operations / for further processing.
- Once the Batch has been executed with the Execute method, it will reset
the governor limits. (i.e it will bypass the governor limits).
Syntax:
1. Database.ExecuteBatch(<BatchClassObjectName>)
2. Database.ExecuteBatch(<BatchClassObjectName>, integer batchsize)
// Create the Object of the Batch Class in Anonymous Window and Execute the
Below code:
/* Apex Batch Job to Update All Account Records, whose name is starting with
'Database'.
Update Website = 'www.Reliance.com'
NumberOfEmployees = 100;
*/
return Database.getQueryLocator(soqlQuery);
}
for(SObject s : lstSObject)
{
Account accRec = (Account)s;
accRec.Website = 'www.Reliance.com';
accRec.NumberOfEmployees = 100;
lstAccounts.add(accRec);
}
if(! lstAccounts.isEmpty())
{
update lstAccounts;
}
}
Global void Finish(Database.BatchableContext BC)
{
system.debug('Current Batch ID is....: ' + BC.GetJobID());
email.setToAddresses(toAddresses);
email.setReplyTo('[email protected]');
email.setSenderDisplayName('QEdge Account Website Update Batch');
email.setSubject(emailSubject);
email.setHtmlBody(emailContent);
Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});
Execution:
---------
// Creating Object for BatchApex class...
UpdateAccountsWebsiteBatch acc = new UpdateAccountsWebsiteBatch();
Database.executeBatch(acc, 50); // Batch size is : 50
//Database.executeBatch(acc); --> Default Batch size : 200
/ Create a Batch Apex class to Delete the Account Records, Which are having the
"Delete" (Check Box)field status as "TRUE"
*/
{
global Database.QueryLocator start(Database.BatchableContext BC)
{
String Query = 'select id from Account where Delete__c = true';
return Database.getQueryLocator(query);
}
for(Sobject s : scope)
{
Account a = (Account)s;
lstAccount.add(a);
}
Delete lstAccount;
}
{
// Get the ID of the AsyncApexJob representing this batch job
// from Database.BatchableContext.
// Query the AsyncApexJob object to retrieve the current job's information.
Test Classes:
Test Class:
===========
@isTest
Public class ArithmeticOperationsClassTest
{
testmethod static void TestOperations()
{
ArithmeticOperationsClass a = new ArithmeticOperationsClass();
a.Addition(200,456);
a.Subtraction(400,200);
a.Multiplication(45,34,45);
a.Division(45,5);
}
}
===============================================
Apex Class:
===========
/**
@Author: Feroz Beg
@name: LeadHandler
@CreateDate:
@Description: This class provides the ability to Handle the Lead to Prospect
Synchronization.
@Version: 1.0
@reference:
*/
if(!mapLeads.isEmpty())
{
for(Lead l : mapLeads.values())
{
if(l.Status == 'Closed - Converted')
{
Database.LeadConvert lc = new Database.LeadConvert();
lc.SetLeadId(l.Id);
lc.SetConvertedStatus(Status.MasterLabel);
lc.setSendNotificationEmail(false);
if(l.Do_Not_Create_Opportunity__c == true)
{
lc.SetDoNotCreateOpportunity(true);
}
lstConverts.add(lc);
}
}
if(!lstConverts.isEmpty())
{
try
{
lcResults = Database.convertLead(lstConverts);
}
Catch(DMLException d)
{
system.debug('DML Exception Occured during Lead Conversion.' +
d.getMessage() + '-- StackTrace string :'+ d.getStackTraceString());
}
Catch(Exception e)
{
system.debug('Exception Occured during Lead Conversion.' +
e.getMessage() + '-- StackTrace string :'+ e.getStackTraceString());
}
}
}
for(Lead ld : lstLeads)
{
Prospect__c p = new Prospect__c();
p.FirstName__c = ld.FirstName;
p.Name = ld.LastName;
p.Phone__C = ld.Phone;
p.Email__c = ld.Email;
p.Fax__c = ld.Fax;
p.Rating__c = ld.rating;
p.Industry__C = ld.Industry;
p.Lead_Source__C = ld.LeadSource;
p.Passport_Number__c = ld.Passport_Number__c;
p.ssn_Number__c = ld.ssn_Number__c;
p.Product_interest__c = ld.ProductInterest__c;
p.Primary__c = ld.Primary__c;
p.Company__c = ld.Company;
p.Website__C = ld.Website;
p.Lead_Status__c = ld.Status;
p.Annual_Revenue__c = ld.annualrevenue;
p.Lead__C = ld.id;
lstProspects.Add(p);
}
try
{
if(!lstProspects.isEmpty())
insert lstProspects;
}
catch(DMLException dex)
{
system.debug('DML Exception Occured during Prospect Creation.' +
dex.getMessage() + '-- StackTrace string :'+ dex.getStackTraceString());
}
// This method will update the associated Prospect Record, upon updating the
Lead record.
Public static void AfterUpdate(Map<Id,Lead> mapLeads, Map<Id,Lead>
oldLeads)
{
List<Prospect__c> prospectsToUpdate =new List<Prospect__C>();
if(!lstProspects.isEmpty())
{
for(Prospect__C p : lstProspects)
{
for(Lead l : mapLeads.values())
{
if(p.Lead__c == l.id)
{
p.FirstName__c = l.FirstName;
p.Name = l.LastName;
p.Phone__C = l.Phone;
p.Email__c = l.Email;
p.Fax__c = l.Fax;
p.Rating__c = l.rating;
p.Industry__C = l.Industry;
p.Lead_Source__C = l.LeadSource;
p.Passport_Number__c = l.Passport_Number__c;
p.ssn_Number__c = l.ssn_Number__c;
p.Product_interest__c = l.ProductInterest__c;
p.Primary__c = l.Primary__c;
p.Company__c = l.Company;
p.Website__C = l.Website;
p.Annual_Revenue__c = l.annualrevenue;
p.Lead_Status__c = l.status;
// Trasfering Prospect to another user...
if((oldLeads.get(l.Id).Prospect_owner__C !=
mapLeads.get(l.Id).Prospect_owner__c) &&
mapActiveStaff.containsKey(l.Prospect_owner__C))
{
p.OwnerId = mapLeads.get(l.Id).Prospect_owner__c;
}
prospectsToUpdate.Add(p);
}
}
}
try
{
if(!prospectsToUpdate.isEmpty())
update prospectsToUpdate;
}
catch(DMLException e)
{
system.debug('DML Exception Occured during Prospect Creation.' +
e.getMessage() + '-- StackTrace string :'+ e.getStackTraceString());
}
}
}
}
Test Class:
===========
@isTest
Public class LeadHandlerTest
{
testmethod static void TestAfterInsert()
{
List<Lead> lstLeads = new List<Lead>();
lstLeads.Add(l1);
lstLeads.Add(l2);
Test.StartTest();
insert lstLeads;
Update leadsToUpdate;
insert l3;
Lead l = [select id, firstname, lastname, status from lead where id=: l3.id
limit 1];
if(l != null)
{
l.Status ='Closed - Converted';
update l;
}
}
Test.StopTest();
}
}
============================================
Apex Class:
-----------
// Apex Class to send Email Notifications...
email.SetToaddresses(toAddress);
email.SetSubject(emailSubject);
email.SetReplyTo(cnd.email_id__C);
email.SetSenderDisplayName('QEdge Support Center');
/*
// To Send the Plain Text Information..
string emailContent = 'Hi '+ cnd.Name + 'Thanks for apllying for the position
' + pos.Name + '. We will have a look into your profile and out HR Team will get
back to you shortly. Thanks & Regards, ABC Technologies ';
email.SetPlainTextBody(emailContent);
Messaging.SendEmail(new Messaging.SingleEmailMessage[]{email});
}
}
Test Class:
-----------
@isTest
Public class MessagingUtilityTest
{
testmethod static void TestEmailToCandidate()
{
insert p;
Test.StartTest();
insert c;
MessagingUtility.SendEmailTocandidate(c, 'Congratulations...!!
Your Candidature has been submitted successfully.');
Test.StopTest();
}
}
==================================
Batch Apex Class:
-----------------
return Database.getQueryLocator(soqlQuery);
}
for(SObject s : lstSObject)
{
Account accRec = (Account)s;
accRec.Website = 'www.Reliance.com';
accRec.NumberOfEmployees = 100;
lstAccounts.add(accRec);
}
if(! lstAccounts.isEmpty())
{
update lstAccounts;
}
}
email.setToAddresses(toAddresses);
email.setReplyTo('[email protected]');
email.setSenderDisplayName('QEdge Account Website Update Batch');
email.setSubject(emailSubject);
email.setHtmlBody(emailContent);
Test Class:
-----------
@isTest
Public class UpdateAccountsWebsiteBatchTest
{
testmethod static void TestAccountBatch()
{
lstAccounts.Add(a);
Test.StartTest();
insert lstAccounts;
Database.ExecuteBatch(bat);
Test.StopTest();
}
}
=====================================
Apex Class:
-----------
public class MassEmailClass
{
Public static void SendMassEmailsToContacts()
{
string lastNameStartsWith = 'b%';
if(! mapContacts.isEmpty())
{
contactIDs.addAll(mapContacts.keyset());
Messaging.reserveMassEmailCapacity(4);
Messaging.MassEmailMessage email = new
Messaging.MassEmailMessage();
}
}
Test Class?
-----------
================================================
Apex Class:
===========
Public class ProspectHandler
{
/*
* This method is used to Update the Associated Lead Record upon updating
Prospect record.
*/
if(!mapPros.isEmpty())
{
for(Prospect__c p : mapPros.values())
{
if(p.lead__C != null)
{
leadIDs.Add(p.lead__C);
}
}
leadsToUpdate.Add(l);
}
}
if(!leadsToUpdate.isEmpty())
update leadsToUpdate;
/*
try
{
if(!leadsToUpdate.isEmpty())
update leadsToUpdate;
}
Catch(DMLException d)
{
system.debug('DML Exception Occured.' + d.getMessage() + ' Stack
Trace : '+ d.getStackTraceString());
}
Catch(Exception e)
{
system.debug('Exception Occured.' + e.getMessage() + ' Stack Trace :
'+ e.getStackTraceString());
}
*/
}
}
}
}
Test Class?
-----------
There are two types of objects that you can interact with on the platform.
Setup Objects:
==============
- A "setup" object is one that must be edited from the setup or builder area of the
platform.
Non-Setup Objects:
==================
Non-Setup objects can be any one of standard objects like Account / Contact /
Lead / Opportunity...etc or any custom object created by user / developer.
UseCase:
========
When we try to perform the DML operations on both Setup Object and Non-
Setup object in a Single Transaction, Salesforce will throws the
"MIXED_DML_OPERATION Exception".
i.e. I am updating a User Record and Updating an Account record in the same
context as below.
Example:
========
Public class MixedDMLExceptionTestClass
{
Public static void DoDMLOperations()
{
// Making User Record DeActive (Updating - DML)..
u.isActive = false;
update u;
Account acc = [select id, name, rating, annualrevenue from account where
name ='Query String Test' limit 1];
system.debug('Account Record is....: '+ acc);
if(acc != null)
{
acc.annualrevenue = 60000;
update acc;
}
}
Testing:
---------
MixedDMLExceptionTestClass.DoDMLOperations();
Result:
-------
You will be receiving the "MIXED_DML_OPERATION" Exception. As we can't
perform DML operations on both Setup and Non-Setup objects in a single
transaction (and vice versa).
Solution:
=========
To avoid these issues, we need to use "Future Annotated Methods", defined with
the help of "@Future()" annotation.
FUTURE METHODS:
===============
The future annotation is a great feature on the Salesforce Platform to allow you to
execute custom logic asynchronously.
Use the future annotation to identify methods that are executed asynchronously.
When you specify future, the method executes when Salesforce has available
resources.
For example, you can use the future annotation when making an asynchronous
Web service callout to an external service.
You can call a future method for executing long-running operations, such as
callouts to external Web services or any operation you’d like to run in its own
thread, on its own time.
Note: You can also make use of future methods to isolate DML operations on
different sObject types to prevent the "Mixed DML Error".
Each future method is queued and executes when system resources become
available.
That way, the execution of your code doesn’t have to wait for the completion of a
long-running operation. A benefit of using future methods is that some governor
limits are higher, such as SOQL query limits and heap size limits
Rules / Considerations:
if(u != null )
{
system.debug('User Record is...: '+ u);
u.isActive = false;
update u;
UpdateAccount();
@future()
Public static void UpdateAccount()
{
Account acc = [select id, name, rating, annualrevenue from account where
name ='Query String Test' limit 1];
system.debug('Account Record is....: '+ acc);
if(acc != null)
{
acc.annualrevenue = 60000;
update acc;
System.debug('Account Record Updated Successfully. : '+ acc);
}
}
}
Testing:
========
MixedDMLExceptionTestClass.DoDMLOperations();
Test.startTest();
insert u;
insert a;
MixedDMLExceptionTestClass.DoDMLOperations();
Test.StopTest();
}
}
// Write an Apex Program to Update Rating Value as "Warm" for the Accounts
Associated with the Industry "Finance / Chemical / HealthCare"
list<account> lstacc = [select id, name, industry, rating from account where
industry IN('chemical', 'Finance','Healthcare')];
for(account acc: lstacc)
{
acc.rating=’warm';
}
update lstacc;
system.debug(lstacc);
// write an apex program to update all associated contacts owner with the
same as parent account owner up on changing the account owner value.
Account acc =[select id, name, ownerId from account where name =:'harsh
technologies' ];
system.debug(acc);
acc.ownerId = '00561000000rOPpAAM';
update acc;
id accid =acc.id;
List<contact> lstcon =[select id, ownerid from contact where accountid=:accid ];
for(contact con:lstcon)
{
con.ownerId = acc.ownerId;
system.debug(con);
}
update lstcon;
// Write an Apex Program to fetch all converted lead records and their
associated Account , Contact and Opportunities.
Here two ways to execute the programe:
list<lead> lstlea =([select id,name, convertedaccountid, convertedcontactid,
convertedopportunityid from lead where isconverted=:true]);
system.debug(lstlea.size());
for(lead le:lstlea)
system.debug(le);
One Top MNC Asked These Questions In Interview.Please Try To Answer These
Questions. All The Best Friends.