Tuesday, May 26, 2015
Thursday, February 12, 2015
Distinct keyword in salesforce
Distinct Records in Salesforce
In a table or a Object(In Salesforce), a column may contain many duplicate values; and sometimes you only want to list the different (distinct) values.
The DISTINCT keyword can be used to return only distinct (different) values.
In SQL we can write a Query to extract distinct records from table by making use of a sample Query like this
SELECT DISTINCT column_name,column_name
FROM table_name;
FROM table_name;
But in SOQL there is no distinct keyword to do the operation and it is really boring to write out own custom logic to pick the distinct values. Please care to drop this idea in App exchange.
Eventhough Salesforce suggests the use of aggregate methods(Partial solution) to solve this I felt it's complex to implement it and it didn't work as expected. So I need to come up with a custom logic to pick distinct records from a custom object and insert it in to a unrelated second object.
/*****
***Description: The unique distinct records are picked from
***sessions aggregate object and inserted as unique records in detail reporting group object
******/
trigger InsertDistinctReportGroudId on Sessions_Aggregate__c (after insert) {
//Collect the whole List of Session Aggregate data
list SAlist = [select id,Reporting_Group_Name__c,SOName__c from Sessions_Aggregate__c where Reporting_Group_Name__c!=null limit 9999];
system.debug('SAlist '+SAlist);
//create a new set to pick the unique records and add the distinct values inside the set
Set s1 = new Set();
for(Sessions_Aggregate__c c:SAlist){
//Iterate thhru the main list and assign the distinct values from a set
s1.add(c.Reporting_Group_Name__c);
}
system.debug('*****'+s1.size());
//Collect the pre-Existing records in the second custom object to compare
list oldRGlist = [select ReportingGroupName__c from Detail_Reporting_Group__c limit 9999];
List distinctRGnames = new List();
//Create sets to compare the existing record values of the second object with the 1st object
Set s2 = new Set();
Set s3 = new Set();
if(oldRGlist.size()>0){
for(Detail_Reporting_Group__c S:oldRGlist){
s2.add(S.ReportingGroupName__c);
}
}
for(string s : s1){
if(s2.contains(s)){
//if 1st object list contains any of the field values from the 2nd object the remove the repeating value from the 2nd object set.
s2.remove(s);
}
else{
//if there is no duplicates the add the 2nd obj value to the 1st object list's value
s3.add(s);
}
}
//Now we got all the distinct values in the set now add these value in to a master list for Insertion.
distinctRGnames.addAll(s3);
system.debug('+distinctRGnames+'+distinctRGnames);
list<Detail_Reporting_Group__c> RGlist= new list<Detail_Reporting_Group__c>();
for (integer i=0;i<distinctRGnames.size();i++){
Detail_Reporting_Group__c DGR=new Detail_Reporting_Group__c();
DGR.ReportingGroupName__c=distinctRGnames[i];
RGlist.add(DGR);
}
//Insert The main List
insert RGlist;
Authored by: Nirmal Christopher,
Technical Consultant,
Global Tech & Resources, Inc. (GTR).
Creating Queues Programatically (Queue is not associated to the S object Type)
How to Create Queues Programatically in Salesforce
There will be a situation where you need to create queues programatically. Before architecting the technical complexity there are few things taken on account
There is two types of objects in Salesforce setup objects and non setup objects. Set up objects doesn't allow DML operation. Please follow the link to check the list of setup and non setup objects which allow the DML operation.
you see the link Q Sobject is added in to the list. So we cannot create the Queues programatically by any direct means. But there is a workaround for this limitation.
The scenario I worked was to create new Queues based on the field value from a custom object when the record in the custom object is getting created.
So I would require a after insert trigger on the custom object to pick the name of the queue from the field value and a @future class to orchestrate the queue creation.
/*****
Description: This trigger creates queue based on the detail reporting group names
*****/
trigger CreateNewQueues on Detail_Reporting_Group__c (after insert) {
List newGroups = new List();
for (Detail_Reporting_Group__c sa: Trigger.new) {
if(sa.ReportingGroupName__c!=null){
newGroups.add(new Group(name='RG-'+sa.ReportingGroupName__c,type='Queue'));
}
}
insert newGroups;
Set groupids= new Map (newGroups).keySet();
// call in future context to avoid MIXED DML conflicts
sessionhandler.createQueue(groupIds);
//Apex Class to handle the session to create Queues Asyncronously
public class SessionHandler{
@future
public static void createQueue(Set groupIds) {
List newQueueSobject = new List();
String clipoff;
for (Id queueId : groupIds) {
newQueueSobject.add(new QueueSObject(SobjectType='Sessions_Aggregate__c',QueueId=queueId));
}
system.debug('NEWRECORD'+newQueueSobject);
try{
insert newQueueSobject;
}
catch(exception e){
system.debug('EEEEEEEEEEEEEEEEEEE'+e);
}
}
}
Authored by: Nirmal Christopher,
Technical Consultant,
Global Tech & Resources, Inc. (GTR).
Wednesday, February 11, 2015
Nested For Loop is Infected
If we have a scenario of comparing two different lists and performing a logic it works like a Odo meter of the car. The Inner loop executes first and outer loop is executed later. Consider the scenario of comparing two different lists and doing a field update based on the comparison.
Lets take two different lists
List<account>accountlist=[select id, name from account limit 9999];
List<customobject>customobjList=[select id, textvalue, lookupaccount from custom object limit 9999];
based on the text value of a field from a custom object the logic should fetch the related account name and update the look up field in the custom object.
This scenario can be achieved as follows
for(customobjList obj:customobjList){
for(Account a:accountlist){
obj.textvalue=a.name;
}
}
In triggers the code needs to be properly bulkifie
The above piece of code will work fine. But the list defined inside the inner for loop will soon hit the governor limits before we can expect.
How to avoid this?
By making proper usage of Salesforce Collections
The below code will also perform the same logic but it handles the governor limits very well
list<account>acc=[select id,name from account limit 9999];
map<string,account>accfinalmap=new map<string,account>();
for(account acc1:acc){
accfinalmap.put(acc1.name,acc1);
}
for(customobject sa3:trigger.new){
if(accfinalmap.containskey(sa3.textvalue)){
sa3.lookupaccount =accfinal.id;
}
}
By making use of the Collection times effectively we can control the governor limits at ease.
Authored by: Nirmal Christopher,
Technical Consultant,
Global Tech & Resources, Inc. (GTR).
Subscribe to:
Posts (Atom)