Saturday 12 May 2018

Page Redirection on the basis of Record Type/Field (Classic)


I came across an requirement where I have redirect user to different pages on the basis of Record Type (redirection is possible on the basis of fieldvalue as well).

Lets take an example

Object : Account
Record Types:

  1.       Customer [opens in Standard detail page]
  2.     Partner [opens in Visualforce page]


when user try to access account record of type 'Customer' then Salesforce standard page should get open but accessing any account of type 'Partner', custom visualforce page should be open.

Controlling page-layout on the basis of record type is possible but we cannot open visualforce page on the basis of record type or field value. To achieve this functionality we have write some code and need to override standard view button.

To achieve this requirement we will create a visualforce page and apex class.

after creating page and controller now its time to override Account's View button.



Now when user view account of record type 'Customer' Salesforce standard page will open and for account of record type 'Partner' visualforce page will open.




same functionality can be achieved on the basis of field value.

Sunday 18 February 2018

Improve SOQL Performance


SOQL (Salesforce Object Query Language) used to search Salesforce data for specific information. SOQL allows us to specify source object, a list of fields to retrieve and condition for selecting rows in source object. SOQL returns List<Sobject>

To avoid long execution time, non-selective SOQL queries may be terminated by the system to improve the performance.

A query is selective when one of the query filters is on an indexed field and query filter reduces the resulting number of rows below a system-defined threshold. The performance of the SOQL query improves when two or more filters used in the WHERE clause meet the mentioned conditions.

Following fields are indexed by default and when used in SOQL WHERE clause improved the permormance.
  1. Primary Key (Id, Name and Owner fields)
  2. Foreign Keys ( lookup or master-detail relationship fields).
  3. Audit dates ( systemModStamp).
  4. Custom fields marked as External ID or Unique.

NOTE: You can raise an case with Salesforce Support to custom Indexes fields upon request.

But Custom index cannot be created on following types of fields
  1. Multi-Select Picklists.
  2. Currency fields in a Multicurrency Organization.
  3. Long text fields.
  4. Binary fields (field of type Blob, file, or encrypted text.).

Selective SOQL Queries example:

SELECT Id FROM Account WHERE Id IN (<list of Account IDs>)

SELECT Id FROM Account WHERE Name != ''

SELECT Id FROM Account WHERE Name != '' AND CustomField__c = 'ValueA'

SELECT Id FROM Account WHERE FormulatField__c = 'ValueA'

following rules have to be true in order to index a Formula Field
  • The formula field contains fields from a single object only ( not relationship fields).
  • The formula field doesn't reference any non-deterministic functions ( e.g. SYSDATE).
  • The formula field contains references to Primary Keys(e.g. Id).
  • The formula field doesn't reference any non-supported fields for including in indexes.

Friday 16 February 2018

Difference between query()/ QueryMore()/ QueryAll()


query():  it executes a query against the specific object and returns data that matches the specific criteria.

Syntax: 
QueryResult = connection.query(string queryString);

used in SOAP API, when a client application invokes the query() call, it passes a query string that specifies the object to query, fields to retrieve, and any condition that records need to satisfied. Client application must be logged in with sufficient access rights to query individual objects and specified fields.

The query result object contains upto 500 rows of data by default. If the query results exceed 500 rows, then client application uses the queryMore() call and a server-side cursor to retrieve additional rows in 500-row chunks.

queryMore(): Use this call to process query() calls that retrieve a large number of records( by default, more than 500) in the result set.The query() call retrieves the first 500 records and creates a server-side cursor that is represented in the queryLocator object. The queryMore() call processes subsequent records in up to 500-record chunks, resets the server-side cursor, and returns a newly generated QueryLocator.To iterate through records in the result set, you generally call queryMore()repeatedly until all records in the result set have been processed (the Done flag is true). You can change the maximum number of records returned to up to 2,000.

Syntax:
QueryResult = connection.queryMore(QueryLocator QueryLocator);


Note: A queryMore() call on a parent object invalidates all child cursors in the previous result set. If you need the results from the child, you must use queryMore() on those results before using queryMore() on the parent results.


queryAll(): Retrieves data from specified objects, whether or not they have been deleted.

Syntax:
QueryResult = connection.queryAll(string queryString);

Use queryAll to identify the records that have been deleted because of a merge or delete. queryAll has read-only access to the field isDeleted; otherwise it is same as query().

To find records that have been deleted (in preparation for undeleting them with the undelete() call), specify isDeleted = true in the query string, and for merged records, request the masterRecord.
For example:
SELECT id, isDeleted, masterRecordId FROM Account WHERE masterRecordId = 'recId'


Let me know if the article help.