Pagination using standard set controller salesforce We can use Standard set controllers provided by salesforce to implement pagination in visualforce. It is very easy to implement pagination using standard set controller. We can easily navigate …
Pagination using StandardSetController with wrapper class without losing data during pagination Click here for Demo – Pagination with wrapper Very often, we need pagination in our visualforce page, and we use wrapper class to show …
Salesforce Certified Sharing and Visibility Designer Exam Tips How to pass Salesforce Certified Sharing and Visibility Designer Exam My Experience This is one of easiest exam from all architect exam. I believe it should be …
Salesforce is all about managing your valuable data in a way that allows you to provide personalized services to your customers. The CRM platform allows you to record, store, track, and analyze records that facilitate …
Salesforce Certification Salesforce Certification – Guide to pass all salesforce Certifications Salesforce is one of the fastest-growing, most in-demand skill sets today. From software developers to solutions architects, to project managers and marketing and sales …
How to pass Salesforce Certified Integration Architecture Designer Exam
My Experience
This exam sounds difficult. But in my experience this is easy exam. Out of all architect exam, I scored maximum in this exam. If you have worked on 2-3 integration projects and you have good hands-on experience in integration, then 1 week of study is enough for this exam. Like all other architect exam, I went through all links in free self-directed resource guides. Some of topics are repeated, so you can skip those topics. This one was 4th architect exam for me, So I was very confident for this exam. When I submitted exam, I was sure that I will pass this exam.
Credential Overview
The Salesforce Certified Integration Architecture Designer credential is designed for those who assess the architecture environment and requirements and design sound and scalable technical solutions on the Force.com platform that meet end-to-end integration requirements. Candidates should have experience communicating solutions and design trade-offs to business stakeholders.
Here are some examples of the concepts you should understand to pass the exam:
Held a technical architect role on multiple complex deployments or gained equivalent knowledge through participation and exposure to these types of projects
Thorough understanding of Web Services in general and SOAP and REST specifically; understands the basic workings of HTTP/S
Understand the different Force.com APIs and is able to design solutions using the appropriate API
Understand data migration considerations, design trade-offs, and common ETL tools
Experience with common integration patterns used on the Force.com Platform
Understand patterns/mechanisms to secure integrations such as TLS for HTTP
Salesforce Certified Data Architecture and Management Designer Exam Tips
How to pass Salesforce Certified Data Architecture and Management Designer Exam
My Experience
This exam was 2nd architect exam for me. Its not that much easy if we compare it with Sharing and Visibility Exam. But if you do good preparation and study all topics mentioned in resource guides, then you can easily crack it. Good understanding of data and security/sharing model in an LDV (large data volume) environment and best practices around LDV migration are required for preparing for the exam. Following are most important topics:
Large Data Volumes (LDV)
Skinny Tables
Indexes
Data Loading(LDV)
Data Quality
Credential Overview
Salesforce Certified Data Architecture and Management Designer Exam
All this is copied from official certification page and guide.
The Salesforce Certified Data Architecture and Management Designer credential is designed for those who assess the architecture environment and requirements and design sound, scalable, and high-performing solutions on the Force.com platform as it pertains to enterprise data management.
Here are some examples of the concepts you should understand to pass the exam:
Aware of platform-specific design patterns and key limits
Understand large data volume considerations, risks, and mitigation strategies
Understand LDV considerations with communities
Ability to design a data and sharing model that supports an LDV environment
Understand data movement best practices in an LDV environment
Understand strategies to build an optimized and high-performing solution
The Salesforce Certified Data Architecture and Management Designer candidate has the experience, skills, and knowledge of:
Salesforce Certified Sharing and Visibility Designer Exam Tips
How to pass Salesforce Certified Sharing and Visibility Designer Exam
Sharing and Visibility Designer Exam
My Experience
This is one of easiest exam from all architect exam. I believe it should be easy for everyone who has good knowledge about salesforce security model. Salesforce Security is fundamentals of Salesforce platform. Everyone who starts learning salesforce always learns Salesforce security.
Exam had mix of questions. Most of questions were scenario based. 10-20% question were very tricky and required good understanding of basic concepts. Exam was little bit lengthy. So time management is very important. This was 1st architect exam for me. So I studied for 2 weeks. When I submitted exam, I was not 100 % sure if I will pass or not(1st architect exam is always a fear). But I scored very well in exam. Following are basic topics that you should know:
Profiles & Permission Sets
OWD
Role Hierarchy
Sharing Rules
Apex Managed Sharing
Record Locking related issues
Territory Management
Communities
Account & Opportunity Teams
Salesforce licenses
Credential Overview
All this is copied from official certification page and guide.
The Salesforce Certified Sharing and Visibility Designer credential is designed for those who assess the architecture environment and requirements and design sound, scalable, and high-performing technical solutions on the Force.com platform that meet sharing and visibility security requirements. Candidates should have experience communicating solutions and design trade-offs to businesses and IT stakeholders.
Here are some examples of the concepts you should understand to pass the exam:
Creation of criteria based and ownership based sharing rules
Understanding org wide defaults
Understanding different types of licenses
Describing the fundamental concepts around role hierarchy
The Salesforce Certified Sharing and Visibility Designer candidate has the experience, skills, knowledge, and ability to:
Describe the usage and implementation of sharing rules, both criteria based and ownership based.
Architect the appropriate object relationships given a scenario.
Articulate how Org-Wide defaults may impact a security model.
Articulate how different Salesforce license types may impact a security & sharing model.
Describe how the Role Hierarchy may impact the decisions made when designing a security model.
Describe how Profile configuration may impact a security and sharing model.
Describe the fundamental concepts around role hierarchy, apex sharing etc. to different levels of audience.
Articulate different security capabilities with respect to record visibility, CRUD based security, record level access and the differences between the three.
Describe the limits of declarative capabilities and when a more custom security solution is required with associated risks and limitations.
Articulate what Apex Sharing is and when it should be used.
Articulate the security implications of using Dashboards, Apex run as an Administrator, VisualForce pages or other “run in context” tools to expose aggregate data.
Identify and mitigate performance and scalability concerns for a recommended solution.
Develop a test process to validate a security model.
Articulate use cases for complex sharing such as territory management or account teams should be used.
A candidate for this exam will likely need assistance with the following:
Designing and implement a tokenization strategy.
Identifying off platform data security considerations.
Determining non-core platform data security considerations (E.g. AppExchange) and other Salesforce products (E.g. Heroku).
Describing how specific security constructs work (E.g. SSL, RSA).
Identifying common use-cases for requirements gathering.
Determining performance issues and scalability of large data sets with sharing.
Determining what types of sharing are impacted in an LDV scenario.
Determining security requirements around certain kinds of data: PCI, PII, HIPPA, etc.
Articulating security concepts such as Least Privilege, Defense in Depth, and Failure Securely.
Implementing project and development lifecycle methodologies.
Defining identity management and SSO architecture.
In this article, I will cover a step by step guide for using Salesforce Command Line Interface Data Loader:
So first of all what is Command Line Interface Data Loader, and why should we use it from Command Line when there is already a visual user interface provided? Well, the answer is:
You can automate the data loading process using the CLI data loader. Suppose you want some data from your org to be extracted every night.
You may want a CSV file which is kept at a particular location on a machine, to be uploaded into an org at a fixed time.
NOTE: The CLI data loader functionality is only available for Windows Operating System.
Prerequisites for using CLI Data Loader:
First of all, make sure you have the Admin rights on the machine.
Then, download the data loader setup file on the machine by going into Salesforce environment Setup –> Data Management –> Data Loader. Choose the option “Download Data Loader for Windows“. It will download the latest version of data loader setup file. Install it by following the setup wizard.
Also, you need to have the required version of JRE (Java Run Time Environment). Go to step a and b only if you don’t have the JRE already on the system, otherwise only check step c.
Setup the environment variables and then check the installation by following the steps given by Mr. Arun on this link: Setup Environment Variables Java
Before going to further steps:
Validate your data loader directory looks like below screenshot.
Make sure that you validate the JRE installation and version by hitting Java -version command on your Command Prompt Window as shown in the screenshot below.
data loader directory structure
All Looks good? Yes? Okay, let’s start step by step on how to use Salesforce CLI Data Loader now:
Step 1:Prepare your key for encrypting the password of your org:
Open the command prompt window, and navigate to the bin folder of data loader directory (steps shown in screenshot below). We need to navigate to bin location, because encrypt.bat and process.bat both files exists here at this location.
Use the command encrypt.bat -g anyKeyTextOfYourChoice . You can use any text you want to use as an Encryption key. In my screenshot, I have used myKey, but you can use any of your choice.
Once you will hit enter, it will show you the encrypted version of your text. Copy that value (highlighted in screenshot), and save it in a .txt file and save the file at some proper location on your machine. It will be used in further steps. I have saved mine at “D:\data loader files\encryptionKey.txt” location.
Prepare the encryption key
Step 2:Encrypt your Salesforce environment password by using the encrypted key prepared above.
On the same Command Prompt Window, use the command encrypt.bat -e <yourOrgPassword> <location of the txt file with encrypted key>
Our command was like: encrypt.bat -e nitish$0413 “D:\data loader files\encryptionKey.txt”.
Copy the encrypted value of your password, we will use in further steps when creating process-conf.XML file.
Step 3:Create the mapping file and save it in .sdl format
You need to create the mapping file by putting the CSV file header name on left side and Salesforce API name on right side.
Save the file in .sdl format on your machine.
If there are multiple fields and complex mapping, you can also take help of Dataloader field mapping UI, and save the mapping file from there instead of creating everything manually.
Note:Make sure that API Name of fields should be exactly as in Salesforce. The API names are on the right-hand side of the = character in the mapping file. Capital and Small letters also make a difference and you may face issues.
#Mapping values created by Nitish on 11th Aug
NAME=Name
INDUSTRY=Industry
NUMBEROFEMPLOYEES=NumberOfEmployees
Here is the screenshot of our CSV file which we are gonna upload:
CSV File Screenshot
Step 4:Prepare the process-conf.XML file according to our requirements
One sample process-conf.XML file has already been given in the data-loader directory Samples folder.
Copy that sample file and paste in the location at D drive, where we stored the encryptionKey.txt file as well.
Keep all other files like mapping file, data files at the same location, which is “D:\data loader files”.
Edit the process-conf.XML file now and change the contents of the file as given below. This file contains the information and specifications about all the operations you need to perform in your data load. For ex:
What is the action you want to perform (insert, update, export etc.)
Step 4:Hit the final command, and run the process for data load.
You need to be at the same location as shown in above CMD screenshots, because process.bat file resides there only.
Hit the command process.bat “<file path to process-conf.xml>” <process name>
Replace <file path to process-conf.xml> with the path to the directory containing process-conf.xml & replace <process name> with the process specified in process-conf.xml.
In our case, it was process.bat “D:\data loader files” accountInsert. accountInsert is the process name mentioned in the process-conf.XML file.
process-conf.XML file can contain many processes and you need to run one at a time by using the above command.
Once the process is run, the success and error CSV files will be available at the location you mentioned in process-conf.XML file.
Now you have learned how to use data loader CLI version to load the data, you can also schedule mutiple operations by creating a .bat file and write multiple commands to execute multiple processes one by one. You can get more information about creating .bat file in the PDF at the link below. Check out the last paragraph on P.6 of the cheatsheet for an example:
Note:You should also take a look at the process-conf.XML file provided in samples folder of data loader default directory, to understand some other tags needed to upsert, export operations of data loading.
Salesforce has already provided a cool out of the box feature where you can generate HTML for the web to lead form, which you can simply put on your website. It is very simple to generate the customized form with fields of your choice to generate leads for your company through various company portals or social platforms.
But till some time back, there was no spam check and anyone with wrong intentions could create junk lead data repeatedly in your company’s org, just by writing some small script. Because of this, it becomes a concern for the organization to keep a track of the Lead data quality on a large scale which results in more resources wasted in correcting data quality.
Spring ’17 release enhancement introduced a feature, which allows you to enable spam filtering with reCAPTCHA from Google. This option is available in out of the box feature itself on the same screen as previous.
But before generating the form (web-to-lead HTML) now, you need to register for an API Key pair with Google for your domain.
Steps to register for an API key with Google Account:
Login to your company’s google account or for your practice you can log in to your own personal Google account.
Once logged in, Register here for the reCaptcha with google.
Don’t forget to give your domain name, otherwise, your captcha box won’t work and will give you an error. The domain name has to be of that site, which will host your web-to-lead form. In my case, I have shown SFDCPOINT.COM, just for example. My demo domain is different, so I registered that as well later.
Click on Register after checking the checkbox “Accept the reCAPTCHA Terms of Service“.
You will get the Site Key and Secret Key on the next page, just copy and save it somewhere.
NOTE:After clicking on register, and before testing your web to lead form on your website, there should be a gap of at least 30 minutes, as Google can take some time to activate the key for your domain.
Now you are done with the registration of API Key Pair with Google. Now Let’s use the same site key and secret key in Salesforce in order to get Salesforce Web to lead form with reCAPTCHA feature.
Steps to configure the Site Key and Site Secret in Salesforce:
Go to Setup –> Leads –> Web-to-lead.
Click on “Create Web-to-Lead Form” button.
Select the fields you want on the form, give the redirect URL, and come down to enter the API Key Pair information.
Select “Enable Spam Filtering” checkbox to see the API key information section.
Clik on the Lookup icon to enter the info about the site key and secret.
In the popup window, Click New Button.
Enter the name of your choice, and Site Key and Secret Key, Click Save. If you encounter “Insufficient Privileges” error while saving the key information, then follow the instructions in Step 8 else go to Step 9.
Go to Setup -> user interface. Make sure to select the checkbox “Show Quick Create”. Click on Save button at the bottom. Repeat the Steps 5 – 7 again.
Click on Generate button, and you have the HTML code ready to put on your company’s website and start capturing leads from there.
Create API Key Pair In Salesforce
lookup screen
Enter key and secret
If you see the error “Insufficient Privileges”, then follow the screenshot below:
Show Quick Create
HTML Code generated with a few modifications, which are explained below after the code:
<!-- ---------------------------------------------------------------------- -->
<!-- NOTE: Please add the following <META> element to your page <HEAD>. -->
<!-- If necessary, please modify the charset parameter to specify the -->
<!-- character set of your HTML page. -->
<!-- ---------------------------------------------------------------------- -->
<META HTTP-EQUIV="Content-type" CONTENT="text/html; charset=UTF-8">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="https://www.google.com/recaptcha/api.js"></script>
<script>
function timestamp() {
var response = document.getElementById("g-recaptcha-response");
if (response == null || response.value.trim() == "")
{
var elems = JSON.parse(document.getElementsByName("captcha_settings")[0].value);
elems["ts"] = JSON.stringify(new Date().getTime());
document.getElementsByName("captcha_settings")[0].value = JSON.stringify(elems);
}
}
setInterval(timestamp, 500);
</script>
<script type="text/javascript">
function recaptcha_callback(){
$('.button').prop("disabled", false);
}
</script>
<!-- ---------------------------------------------------------------------- -->
<!-- NOTE: Please add the following <FORM> element to your page. -->
<!-- ---------------------------------------------------------------------- -->
<form action="https://webto.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8" method="POST">
<input type="hidden" name='captcha_settings' value='{"keyname":"SecondCaptcha","fallback":"true","orgId":"00DQ000000Ee123","ts":""}'/>
<input type="hidden" name="oid" value="00DQ000000Ee123"/>
<input type="hidden" name="retURL" value="http://www.sfdcpoint.com"/>
<!-- ---------------------------------------------------------------------- -->
<!-- NOTE: These fields are optional debugging elements. Please uncomment -->
<!-- these lines if you wish to test in debug mode. -->
<!-- <input type="hidden" name="debug" value=1> -->
<!-- <input type="hidden" name="debugEmail" value="nitish@test.com"> -->
<!-- ---------------------------------------------------------------------- -->
<label for="first_name">First Name</label><input id="first_name" maxlength="40" name="first_name" size="20" type="text" required="true"/><br/>
<label for="last_name">Last Name</label><input id="last_name" maxlength="80" name="last_name" size="20" type="text" required="true"/><br/>
<label for="email">Email</label><input id="email" maxlength="80" name="email" size="20" type="text" required="true"/><br/>
<label for="phone">Phone</label><input id="phone" maxlength="40" name="phone" size="20" type="text" /><br/>
<label for="company">Company</label><input id="company" maxlength="40" name="company" size="20" type="text" required="true"/><br/>
<div class="g-recaptcha" data-sitekey="6LfU8ikUAAAAALP-P1aIMcWaEGqXOpsd6mhL1234" data-callback="recaptcha_callback"></div><br/>
<input type="submit" name="submit" id="submitBtn" disabled="true" class="button"/>
</form>
In the above code, I have made small modifications, just to make sure that form doesn’t submit until somebody has verified captcha by clicking “I am not a robot”.
I have set the disabled=”true” on submit button. I have used a data-callback attribute of div in which reCaptcha is there, and called a javascript method recaptcha_callback. This javascript method will be called if a user has verified himself, and in this method, I have enabled the submit button by removing the disabled attribute.
Recently, I was working on an assignment, where I had to create Opportunity Team Member records in a trigger on some user action. But when I started to write the code and tried saving it, I got the error “Field is not writeable: OpportunityTeamMember.OpportunityAccessLevel“. Uuuhhh.. I got stuck! According to the documentation this field is writable, then why not for me. Below is the code that I tried, and came to know, that OpportunityAccessLevel field not writable in Apex.
OpportunityTeamMember OppTeamMember = new OpportunityTeamMember();
OppTeamMember.UserId = UserInfo.getUserId();
OppTeamMember.OpportunityId = opp.Id;
OppTeamMember.OpportunityAccessLevel='Edit';
OppTeamMember.TeamMemberRole = 'Opportunity Team Member';
The above code gave me the error:
“Field is not writeable: OpportunityTeamMember.OpportunityAccessLevel“
This error doesn’t occur when you create opportunity team member by going to the related list on the opportunity. You can give any access level from there.
Adding Opportunity Team Member manually
After spending some time, I figured out and came to know, that: If Opportunity sharing settings are set to Private, then you can not write this field OpportunityAccessLevel. This field will be set to Read Only by default.
But my requirement was to give “Edit” access to opportunity team member while creating. So the workaround I opted was:
Create opportunity team member record first, Salesforce will give READ permission by default.
Then, give edit access using the OpportunityShare object because as soon as you create an OpportunityTeamMember record, Salesforce creates an entry in sharing records for that opportunity and user.
Query the sharing record that Salesforce created just now, and update the access level to EDIT.
Here is the code:
OpportunityTeamMember OppTeamMember = new OpportunityTeamMember();
OppTeamMember.UserId = UserInfo.getUserId();
OppTeamMember.OpportunityId = opp.Id;
//OppTeamMember.OpportunityAccessLevel='Edit';
OppTeamMember.TeamMemberRole = 'Opportunity Team Member';
insert OppTeamMember;
//get all of the sharing records which Salesforce created right now. rowCause is Sales Team.
List<OpportunityShare> oppShareRecords = [select Id, OpportunityAccessLevel, RowCause from OpportunityShare where OpportunityId =: opp.Id and RowCause = 'Sales Team'];
// set all team members access to read/write
for (OpportunityShare OppShare : oppShareRecords){
OppShare.OpportunityAccessLevel = 'Edit';
}
update oppShareRecords;
Very often, we need pagination in our visualforce page, and we use wrapper class to show the records with checkboxes in pageBlockTable. We use the standardSetController for pagination, display checkboxes for each record BUT while paginating, the value of the selected checkboxes are gone, it doesn’t retain during paginating.
This is because the list that we use to display records on page, is getting refreshed everytime, and not retaining the values. So, to hold or retain the values during pagination, we will see how we can use Pagination using StandardSetController with wrapper class without losing data during pagination/ paginating (moving next or previous).
Contact pagination – Wrapper Class – With checkboxes
So, to overcome this, we will not use the direct list from standardSetController, instead of that we’ll use a map to show the values on page. This map will always contain the correct values of checkboxes (for retaining purpose), we will use map on visualforce page pageBlockTable. Whenever user clicks on next or previous, first or last, we store the copy of records with checkbox value in map, so that even if the wrapper list is refreshed with next set of records, we can store the checkbox values for previous set of records.
Below is the code snippet you can look at, and we have a demo link as well, just to give you an idea how it works.
public class contactPaginationController{
//variable used in page.
Public Integer size{get;set;}
Public Integer noOfRecords{get; set;}
public List<SelectOption> paginationSizeOptions{get;set;}
public static final Integer QUERY_LIMIT = 10000;
public static final Integer PAGE_SIZE = 5;
public List <WrapperClass> wrapperRecordList{get;set;}
Map<Id, WrapperClass> mapHoldingSelectedRecords{get;set;}
//constructor calling init method.
public contactPaginationController(){
mapHoldingSelectedRecords = new Map<Id, WrapperClass>();
init();
}
//Init method which queries the records from standard set controller.
public void init() {
wrapperRecordList = new List<WrapperClass>();
for (Contact cont : (List<Contact>)setCon.getRecords()) {
if(mapHoldingSelectedRecords != null && mapHoldingSelectedRecords.containsKey(cont.id)){
wrapperRecordList.add(mapHoldingSelectedRecords.get(cont.id));
}
else{
wrapperRecordList.add(new WrapperClass(cont, false));
}
}
}
/** Instantiate the StandardSetController from a query locater*/
public ApexPages.StandardSetController setCon {
get {
if(setCon == null) {
setCon = new ApexPages.StandardSetController(Database.getQueryLocator([SELECT Id,Name, Email, Phone FROM Contact LIMIT : QUERY_LIMIT ]));
// sets the number of records to show in each page view
setCon.setPageSize(PAGE_SIZE);
}
return setCon;
}
set;
}
/** indicates whether there are more records after the current page set.*/
public Boolean hasNext {
get {
return setCon.getHasNext();
}
set;
}
/** indicates whether there are more records before the current page set.*/
public Boolean hasPrevious {
get {
return setCon.getHasPrevious();
}
set;
}
/** returns the page number of the current page set*/
public Integer pageNumber {
get {
return setCon.getPageNumber();
}
set;
}
/** return total number of pages for page set*/
Public Integer getTotalPages(){
Decimal totalSize = setCon.getResultSize();
Decimal pageSize = setCon.getPageSize();
Decimal pages = totalSize/pageSize;
return (Integer)pages.round(System.RoundingMode.CEILING);
}
/** returns the first page of the page set*/
public void first() {
updateSearchItemsMap();
setCon.first();
init();
}
/** returns the last page of the page set*/
public void last() {
updateSearchItemsMap();
setCon.last();
init();
}
/** returns the previous page of the page set*/
public void previous() {
updateSearchItemsMap();
setCon.previous();
init();
}
/** returns the next page of the page set*/
public void next() {
updateSearchItemsMap();
setCon.next();
init();
}
//This is the method which manages to remove the deselected records, and keep the records which are selected in map.
private void updateSearchItemsMap() {
for(WrapperClass wrp : wrapperRecordList){
if(wrp.isSelected){
mapHoldingSelectedRecords.put(wrp.contactRecord.id, wrp);
}
if(wrp.isSelected == false && mapHoldingSelectedRecords.containsKey(wrp.contactRecord.id)){
mapHoldingSelectedRecords.remove(wrp.contactRecord.id);
}
}
}
//wrapper class being used for checkbox showing.
public class WrapperClass {
public Boolean isSelected {get;set;}
public Contact contactRecord {get;set;}
public WrapperClass(Contact contactRecord, Boolean isSelected) {
this.contactRecord = contactRecord;
this.isSelected = isSelected;
}
}
}
This is just an example we are taking here (i.e. display contacts with checkboxes), there can be several other scenarios as well, where you might have some inputField in one column of the pageBlockTable, and you need to retain the values of inputfield during pagination.
There also you can use this concept of Pagination using StandardSetController with wrapper class without losing data during pagination.
This is also very important because this kind of scenario is included for sure in Advanced Developer certification exam exercise, where you have to do pagination with either checkboxes or inputField in pageBlockTable.
Hope this post will give you a better idea about pagination and that too with wrapper classes.
Only Aggregate Expressions Use Field Aliasing – SOQL Error
Out of many other errors we encounter, this is one with the SOQL. Many times, when writing SOQL, we face the error – “Only Aggregate Expressions Use Field Aliasing” and we are stuck that what’s happening, everything seems all right to me.
You must be missing a comma in the SOQL between two fields before FROM keyword.
Aliasing is when you want to give some different name to the column in any SOQL result, but you can only do so in aggregate queries of Salesforce, where you use some aggregate functions like sum(Custom_Field__c), count(Id) or any other similar aggregate function.
Below is a valid SOQL using aggregate function with aliasing. We are trying to give “amountTotal” name to Sum(Amount) column.
[Select Sum(Amount) amountTotal, AccountId from Opportunity group by AccountId];
BUT, because aliasing is not allowed in normal SOQL, that is why below SOQL is considered faulty, and will encounter the error “Only Aggregate Expressions Use Field Aliasing”.
[select id, Name Amount from Opportunity];
You might notice we are missing a comma between Name & Amount field, which is why Salesforce thinks that we are trying to give a different label to Name column in SOQL result but that is not allowed.
If you ever encounter this error in future, look for missing comma between two fields in your SOQL.
Test classes are an important part of overall SDLC in Salesforce. We as a developer have to write the test classes very often, and we need to create the test data as well, to have our test class executed successfully. We’ll cover a new concept introduced in salesforce test classes i.e TestSetUp method in apex test classes.
Initially, we had to create test data in every test method, because every test method is considered a different transaction with its own governor limits. But Salesforce has introduced @TestSetUp annotation for test class method. You can write a method in test class, with @TestSetUp annotation applied, and create all your common test data in this method.
Here are few key points about @TestSetUp methods:
Method marked with @TestSetUp annotation executes before any testMethod.
Data created in this method doesn’t need to be created again and again, and it is by default available for all test methods.
There can be only one setup method per test class.
Test setup methods are supported only with the default data isolation mode for a test class. If the test class or a test method has access to organization data by using the @isTest(SeeAllData=true) annotation, test setup methods aren’t supported in this class.
Test setup methods are available for 24.0 or later versions only.
Every test method will get unchanged version of the test data created in setup method, doesn’t matter if any other test method has modified the data. We will show this in testMethod2 of below example.
@testsetup Example
Below is a sample code, which will show how the test data is available in every test method.
@isTest
private class TestSetupMethodExample {
//Below is a method with @testsetup annotation, the name can be anything like setup(), oneTimeData(), etc.
@testSetup static void setup() {
// Create common test accounts
List<Account> testAccts = new List<Account>();
for(Integer i=0;i<2;i++) {
testAccts.add(new Account(Name = 'TestAcct'+i));
}
insert testAccts;
}
@isTest static void testMethod1() {
// Here, we will see if test data created in setup method is available or not, Get the first test account by using a SOQL query
Account acct = [SELECT Id FROM Account WHERE Name='TestAcct0' LIMIT 1];
// Modify first account
acct.Phone = '555-1212';
// This update is local to this test method only.
update acct;
// Delete second account
Account acct2 = [SELECT Id FROM Account WHERE Name='TestAcct1' LIMIT 1];
// This deletion is local to this test method only.
delete acct2;
// Perform some testing
}
@isTest static void testMethod2() {
// The changes made by testMethod1() are rolled back and
// are not visible to this test method.
// Get the first account by using a SOQL query
Account acct = [SELECT Phone FROM Account WHERE Name='TestAcct0' LIMIT 1];
// Verify that test account created by test setup method is unaltered.
System.assertEquals(null, acct.Phone);
// Get the second account by using a SOQL query
Account acct2 = [SELECT Id FROM Account WHERE Name='TestAcct1' LIMIT 1];
// Verify test account created by test setup method is unaltered.
System.assertNotEquals(null, acct2);
// Perform some testing
}
}
Because, test data created is less in number, that’s why rolling back of records at the end of test class takes less time. This actually ends up in improving the performance and reducing the time take to run the test class.
Compare old and new field values in trigger Salesforce
Sometimes we have requirement that our trigger should run only when some field value is changed on a record. So we need to compare value of that field between old version of record and new version of record to make sure that trigger will not run every time when record is changed/edited. For example, we may have requirement that send an email to VP of company or do some task when an opportunity status is changed to Closed Won. So, we have to compare old and new field values in trigger to make it sure.
Salesforce provides Trigger.OldMap where records with older version (last version of record committed in database) are stored in map with key as their Salesforce record Id’s.
Trigger.OldMap = Map<Id, OldVersionOfRecord>();
I have put an example below to show that how can we use Trigger.OldMap and Trigger.New context variables to compare the field values, because the Id of the record is common in both Trigger.OldMap and Trigger.New, that’s why we can use the record Id to get older and newer version of any record from these maps.
Here in this example, trigger compares the account number field’s old value with the new value. That is, trigger checks if the account number was changed.
If the account number is changed the trigger assigns the Type field value as “prospect” else it assigns it a value as “Other“.
trigger Compare_OldandNewvalues on Account (before update) {
//Here we will iterate on trigger.new list, which already holds the new values of all records.
for (Account acc: Trigger.new) {
//Here we use the account id, to get the older version of record.
Account oldAccount = Trigger.oldMap.get(acc.ID);
//once we get the older version, we can get any field's value from older version to compare.
if(acc.AccountNumber != oldAccount.AccountNumber) {
//Here is some logic being performed on a condition basis.
System.debug('--*Account Number is changed*--');
System.debug('**Old Account Number :'+oldAccount.AccountNumber);
System.debug('**New Account Number :'+acc.AccountNumber);
acc.Type = 'Prospect';
}
else{
System.debug('--**Account Number has not been Updated**--');
acc.Type = 'Other';
}
}
}
Also, please note that the Trigger.oldMap is only available in update and delete events and cannot be accessed in insert event triggers. Please take care of this point when writing your trigger code.
We use cookies to ensure that we give you the best experience on our website. If you continue to use this site we will assume that you are happy with it. AcceptRead More
Privacy & Cookies Policy
Privacy Overview
This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.
http://www.developerforce.com/media/Cheatsheet_Setting_Up_Automated_Data_Loader_9_0.pdf