Monday, January 6, 2014

Invoke Apex Code on Custom Button Click

Hello Accolades,

Description: Sometimes our requirement is like on custom button click, we want to invoke the Apex Class's method & perform some DML operations. There are different ways, but I think the following will be the best possible way.

Scenario: There will be a custom button on Standard Page, onClick of that CB you have to aggregate the Child fields on Standard/Custom object.

Steps to Follow:


1) Create a Custom Button named "Aggregate Child" on your object, Let's consider Stnadard Account as our object which will execute the JavaScript. In code panel you will import two Javascript files as follows:

{!REQUIRESCRIPT("/soap/ajax/14.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/14.0/apex.js")}


2) Now next step will be create an Apex Class (Web Service) & Method, Call that method on this button Click.
So Let's say my controller Name is AccountController which will be global  & method will be aggregateChilds as Webservice.

global class AccountController1{
           webservice static void aggregateChilds(String accId){
                     Account accObje = new Account();
                     accObje = [SELECT id,(SELECT id FROM ChildObj__r) FROM Account WHERE id=: accID LIMIT 1];
                     System.debug(accObje.ChildObj__r.size());
                     
          /* 1) If you want to return the value. then Set the return type & get it in Javascript

              2) Perform DML Operation Whatever needed. */
              }
}

3) Call this method on Button's Javascript

{!REQUIRESCRIPT("/soap/ajax/14.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/14.0/apex.js")}
var res=sforce.apex.execute("AccountController","aggregateChilds",{accId:"{!Account.Id}"})


4) That's about it. If you can Customize the code as per your requirement. If you face any issues, feel free to mail me at shingavi.a@gmail.com
Happy Coding!!

Thursday, January 2, 2014

Salesforce Batch Apex for Beginners

Hello Accolades,

This post is for the Beginner developer who want to learn & wants to explore with Batch Apex on Force.com Platform.

1) What is Batch Class/Batch Apex?
i) Basically Batch class allows us to define a single job that can be broken up into manageable batches that will be processed separately
ii) To override from the Salesforce's Governor Limit, we need to divide our job into chunks.

2) Components of Batch Apex?
To use batch Apex, you must write an Apex class that implements the Salesforce - provided interface Database.Batchable interface, and then invoke the class programmatically.

The Database.Batchable interface contains three methods that must be implemented: 

2-1) start method
Use the start method to collect the records or objects to be passed to the interface method execute. Use the Database.QueryLocator object when you are using a simple query (SELECT) to generate the scope of objects used in the batch job. If you use a querylocator object, the governor limit for the total number of records retrieved by SOQL queries is  bypassed.
Example - a batch Apex job for the Account object can return a QueryLocator for all account records (up to 50 million records) in an organization.
 

Syntax : global (Database.QueryLocator | Iterable<sObject>) start(Database.BatchableContext bc) {} 

2-2) execute method:
 Use this method to do all required processing for each chunk of data.

Syntax : global void execute(Database.BatchableContext BC, list<sObject> sObject){}

2-3) finish method
The finish method is called after all batches are processed. Use this method to send confirmation emails or execute post-processing operations like update on related object however we need to keep governor limits in mind.

Syntax : global void finish(Database.BatchableContext BC){}
 
Now Let's explore with Syntax:
Scenario : Create a Batch apex which will append the string “New Batch Processed” in all the existing Account Records.

1) Basic Skeleton

global class BatchClassName implements Database.Batchable<sObject>{

    global Database.QueryLocator start(Database.BatchableContext BC){}

    global void execute(Database.BatchableContext BC,List<sObject> scope){}

    global void finish(Database.BatchableContext BC){}
}


2) Fetch the records in start method

 global class BatchClassName implements Database.Batchable<sObject>{

    global Database.QueryLocator start(Database.BatchableContext BC){

            return Database.getQueryLocator('SELECT id,Name FROM Account');
     }

    global void execute(Database.BatchableContext BC,List<sObject> scope){}

    global void finish(Database.BatchableContext BC){}
}


3) Append the “New Batch Processed” to all Account's Name:

global class BatchClassName implements Database.Batchable<sObject>{

    global Database.QueryLocator start(Database.BatchableContext BC){

            return Database.getQueryLocator('SELECT id,Name FROM Account');
     }

    global void execute(Database.BatchableContext BC,List<sObject> scope){

           
           for(sObject sObjItr : scope){
                     sObjItr.put('Name','New Batch Processed'+' '+String.valueof(sObjItr.get('Name')));
           }
           update scope;
   }

    global void finish(Database.BatchableContext BC){}
    }


4) Execute the Batch Class

Id batchJobId = Database.executeBatch(new BatchClassName(),Batch Limit); 
Ex. Id batchJobId = Database.executeBatch(new BatchClassName(),10); 

That's about it, Now check Account Names, the "New Batch Processed " is appended to all account names. 
This is basic about the Batch Class, You can call the batch class in Apex Classes, VF controller, Scheduled Classes or using Developer Console. You can also call the Batch Class in Trigger, but It is not recommended to call Batch Class in Trigger.
Hope this will help, If you have any query, feel free to drop me a mail @ shingavi.a@gmail.com.

Happy Coding!! :)