Search
Twitter

Entries in Tutorials (45)

Tuesday
Jan282014

Three Common Apex Coding Topics

If you're an admin of a big Salesforce org, then you probably had some users complain about unfriendly errors. If your Salesforce org is in any way customized then those errors are likely related to performance issues in the custom Apex code. Although custom Apex code can be powerful, it can sometimes hinder the overall performance of your Salesforce org. Today, I'm going to introduce three changes you can make in Apex Code that will improve the performance of your Salesforce:

 

Enhance Validation and Workflow Rules:

One example of the errors your users might get is one that includes FIELD_CUSTOM_VALIDATION_EXCEPTION. This error usually means that you have a scheduled batch that inserts/updates records without fulfilling a Validation Rule(s). Here are a few areas you can improve performance:

  • If you have a batch class, make the class calls a DML operation and that opt_allOrNone is set to False. This will allow the rest of the operation to still succeed even if the record fails.
  • Workflow Rules are most helpful in preventing duplicate records. If you have a lot of Workflow Rules in your org, you can cut down unnecessary processes by deactivating the Workflow and improving the Trigger to do the Workflow Rule'sjob.
  • Review Validation Rules with management and make sure they are necessary to fulfill business logic. Having too many validation rules and required fields can cause unit tests to fail, which will then prevent you from deploying a change set.

Increase Field Length:

If, for example, you have a Trigger that populates values larger than the field length, then you'll most likely get a STRING_TOO_LONG error message. One thing you can do here is to increase the Field Length; it is better to have a large value than getting an error message.

 

Rectify API Limits:

If your org has a lot of integrations with third party apps and that those integrations are used frequently, your users might then see a "REQUEST_LIMIT_EXCEEDED" error. There's no ideal solution to reducing API usage, but one thing you can do is to evaluate the current API usage in your org (SetupAdministration SetupCompany ProfileCompany Information) and figure out a way to reduce and disperse the number of API calls.

 

It is always a good idea to periodically review the current custom Apex Code you have in your org with management and stakeholders. Making these changes will not only cut down the number of errors your users encounter, but will help improve the performance and the overall user-experience in your Salesforce.

Tuesday
Jun252013

Inserting Person Account Records Via API

A common way to insert Person Account records via API (e.g. Data Loader) in your Salesforce org is to define the fields: Last Name and Person Account Record Type ID, which is different from the Record ID in the Business Account. 

But it's interesting to discover that there's rather a smart way for Salesforce to differntiate between Person Account records and Business Account ones; which is by mapping the Last Name.

By mapping the Last Name field, it is acting as the primary field in differentiating between Person Account records and Business Account ones; because if the the record being inserted is a business account, then the company name will have no first or last name. Therefore, remember to always map Last name (along with other related fields) when inserting person account records via api.

Wednesday
Jun192013

Using Aggregate Functions in SOQL

Up until the release of Salesforce API 18.0 (in Spring '10), SOQL aggregate functions weren't available. Like the ones in SQL, these aggregate functions allow the user to count the number of rows for a specific criteria or MAX/SUM the fields of rows.

When coupled with GROUP BY, the aggregate functions can be particularly handy! check out the example below; the query will return the sum of payment amount for an Account:

AggregateResult[] arTotAmount =[Select Account__c, SUM(Payment_Amount__c) TotAmount from Payment group by Account__c];
Note that a query with an aggregate function returns the results in an array of AggregateResult objects. The AggregateResult object is read-only.
Tuesday
May282013

Including Archived and Deleted Records in your SOQL Query

In some instances when performing a SOQL query, some records are omitted from appearing in the results. This includes deleted and archived records. For example, Tasks more than a year old (365 days) are automatically omitted unless the user specifies otherwise and that's where the  "ALL ROWS fuction" comes in handy.

If you add ALL ROWS at the end of a SOQL query, archived and deleted records will be included in the results. Here's an example below of query returning ALL tasks:

SELECT Id FROM Task ALL ROWS

As you can probably imagine, pulling all deleted and archived records into the results could a be hard to manage...so using the "IsDeleted" and "IsArchived" after the "WHERE" clause can help filter the results:

SELECT Id FROM Task ALL ROWS WHERE IsDeleted = false AND IsArchived = false
Wednesday
May222013

Salesforce: Bypass Rules and Triggers

Having Validation Rules in your Salaesforce org is a great way to maintain your data. However, I can think of more than one scenario where Validation Rules, Triggers, and Workflow Rules can get in a way of things. I can tell you there have been times where I wished I could disable the required field validation rule when trying to upload new data into my salesforce.

What comes to our rescue here is the Hierarchical Custom Setting. There, you can basically set values at the User level, Profile level, and the Organization as a whole. When configured, the custom settings will first to look if there had been any values set at the User level, otherwise will move up the hierarchy to Profile, then Organization.

 

In the screenshot above, you can see the Custom Setting I set up (App Setup> Develop> Custom Settings):

  • Checkboxes to disable Workflows, Validation Rules, and Triggers
  • A text-field named "Trigger Objects" with "Lead;Account;Contact:Opportunity" as the value.
  • The Profiles the custom settings should effect

 

After the Custom Setting is set up, it can then be referenced in workflows, triggers, and validation rules:

For Validation and Worflow Rules, use the syntax below on if/when the triggers should fire off:

AND(NOT($Setup.disableReqField__c.Disable_Validation_Rules__c),
//Logic
)
As for triggers, you can retrieve the Custom Setting details then use an IF statement for when it should fire off:
trigger LeadTrigger on Lead (after insert, after update) {
    disableReqField__c profileCustomSetting = disableReqField__c.getInstance(UserInfo.getUserId());
    if(!(profileCustomSetting.Trigger_Objects__c.contains('Account')
            && profileCustomSetting.DisableTriggers__c)){
    }
}

With Hierarchical Custom Setting, Triggers and Validation/Workflow rules can now be overridden without having to temporarily disable them for the entire org.
Friday
Apr262013

Explore Different Messaging Options in VisualForce (Part 1)

VisualForce offers several options when it comes messages such as a warning of an error. Today, I'm going to explain the key differences between the messaging options in VisualForce:

  • apex: pageMessage is used to display a single custom message using the Salesforce formatting. With this one, you have the option to control and specify the "Severity" (the displaying of the message box) and the "Strength" (size of the box). Check out the below code for an example:

 <apex:page>
    <apex:pageMessage summary="This is a pageMessage" severity="error" strength="1"/>
</apex:page>
  • Another option is to use apex: pageMessages; which is used to concurrently display the custom messages entered by the developer and those generated by Salesforce. See the example in the code below and how it renders:
 <apex:page controller= "TestMessageController">
  <apex:pageMessages />
</apex:page>
 
public class TestMessageController{
    public TestMessageController(){
         ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'This is apex:pageMessages'));
         ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'This is apex:pageMessages still'));
         ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, 'This is apex:pageMessages info'));
         ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, 'This is apex:pageMessages warning'));
    }
}
Monday
Apr012013

SOQL: Retrieve Opportunities Between Two Dates

The query below will help you retrieve opportunities created between two dates. Please note that in the below query, the field type is “DateTime”; if you want to use the code for the “Date” field, just remove the time value.

 

Select createdDate, Id, lastModifiedDate

from Opportunity

where createdDate > 2013-03-26T24:00:00Z and createdDate < 2013-04-01T23:00:00Z

 

Click to read more ...

Wednesday
Mar202013

SOQL Date Formats

Coming from an SQL background, I’ve always had issues with SOQL’s date format. So, today, I’m going to share with you some tips on how to utilize SOQL Date queries, specifically using Built in Date Functions:

Before we dig in too deep though, we must know the syntax for Date in Force.com:

YYYY-MM-DD

 

In Force.com, there are two ways of querying Date:

#1 Specify the date in the query

The following query will return all Id’s for all the leads that were created on 2012-12-12 : Select ID, Date from Lead where Date= dateValue (2012-12-12)


#2 Query with a Built in Function

For example, the following query will return all Id’s for the Lead that were created yesterday: Select Id, Date from Lead where Date= YESTERDAY

I hope this helps!

Wednesday
Mar062013

About SQQL Select 

Salesforce’s Apex SOQL uses the following Syntax for the SOQL Select statement:

SELECT someField
FROM someObject
WHERE someCondition


Here's some helpful tips on
SOQL’s SELECT statement:

  • The syntax is not case sensitive, for example: SELECT = select.
  • Currently, SOQL statements cannot exceed 10,000 characters, but the good news is that Salesforce has promised to raise the limit to up to 20,000 characters, soon.
  • The result is stored in a result table, called the result-set.
  • Results are generally not ordered unless you use an ORDER BY clause in the query