APEX

How to bundle multiple actions as a transaction using Salesforce API?

October 19, 2012


How to bundle multiple actions as a transaction using Salesforce API?

At present, the only way to bundle multiple actions as a transaction in SFDC is to put all of them in an APEX method and make it a web service.  But, the problem one may encounter is with the arguments. The arguments tend to get misinterpreted or overlapped at Salesforce end. For example in the following definition webService static String upsertData(string s,Id v, Id[] str)if we pass v as null one of the str values is pushed into v variable. This situation is undesirable and results in unwanted results. So we should define a class defining all the argument we want to pass in a method. And use the class as an argument. This worked perfectly for me.

Solution:
global class xxxxxx{  
  global class yyyyyyy{
        webService Attachment qAttach;        
        webService ABCD[] dsLineItems;
        webService  string[]  deleteIds;
    }

    webService static String upsertData(yyyyyyy dInfo) {
 }

APEX

Sample SF Questions

July 26, 2012


1.       Can we bypass governor limits using time based workflows?
No. Time-dependent actions aren't executed independently. They're processed several times every hour, where they're grouped together and executed as a single batch. Therefore, any triggers that fire as a result of those grouped actions are also executed in a single batch. This behavior can cause you to exceed your Apex governor limits if you design your time-based workflow in conjunction with Apex triggers.

2.       What is JavaScript remoting? 
The RemoteAction annotation provides support for Apex methods used in Visualforce to be called via Javascript. This process is often referred to as Javascript remoting.

3.       What does RemoteAction annotation used for? 
The RemoteAction annotation provides support for Apex methods used in Visualforce to be called via Javascript. This
process is often referred to as Javascript remoting.

4.     What datatype is used to store currency fields in Salesforce?
Decimal

5.       What is the difference between Apex Scheduler and Apex Batch?
Apex scheduler would be used when you need something to happen at a particular point in time. 
Batch apex would be used when you need to process a large number of records that would otherwise break governor limits.

6.       What is the difference between roles and profiles in Salesforce?
Profiles control object- and field-level access whereas roles influence record-level access.

7.       A developer wants to ensure that when a parent record is deleted, child records are not deleted. Which relationship should the developer choose? A. Lookup. B. Master-detail C. Many-to-many D. Master-to-master
Answer (A)


List of List in VisualForce

June 05, 2012

    // VF Page 
<apex:repeat value="{!MyTrows}" var="rows">
        <apex:repeat value="{!MyTcols}" var="cols">
            <apex:outputText value="{!MyT[rows][cols]}" />
        </apex:repeat>
     </apex:repeat>



//Controller

public List> MyT{
get{
List a=new List{'a','b','c'};
List b=new List{'d','e','f'};
List> ab=new List>{a,b};
return ab;
}
set;

}

public List MyTcols{
get{
return new List{0, 1, 2};
}
set;
}

public List MyTrows{
get{
return new List{0, 1};
}
set;
}

Batch Apex and Scheduled Apex

March 29, 2012



This is one of the blog posts I found for interesting with respect to using both Batch Apex and Scheduled apex.


Database.executeBatch (part of apex batch) takes a parameter called scope which specifies the number of
records that should be passed into the execute method.
More info:

“Each execution of a batch Apex job is considered a discrete transaction. For example, a batch Apex job that contains 1,000
records and is executed without the optional scope parameter from Database.executeBatch is considered five transactions
of 200 records each. The Apex governor limits are reset for each transaction.”

Also, we can use Database.Stateful in the class definition to make the batch remember the static variables.

“If you specify Database.Stateful in the class definition, you can maintain state across these transactions. This is useful
for counting or summarizing records as they're processed. For example, suppose your job processed opportunity records. You
could define a method in execute to aggregate totals of the opportunity amounts as they were processed.”

I think by using them together, we can achieve what we need without hitting governor limits.

API

Uploading a document or file to Salesforce

March 02, 2012

I have done a small POC for uploading a file through Salesforce API. 
C#
binding = new SforceService();
 binding.Timeout = 60000;
 LoginResult lr;

            try
            {
                Console.WriteLine("LOGGING IN NOW...");
                lr = binding.login(username, password);
            }
            catch (SoapException e)
            {

            }


 private void uploadFile()
        {

            QueryResult qr = null;
            binding.QueryOptionsValue = new QueryOptions();
            binding.QueryOptionsValue.batchSize = 250;
            binding.QueryOptionsValue.batchSizeSpecified = true;
                        
            Folder rF=null;           
            try
            {

                qr = binding.query("SELECT AccessType, Id, DeveloperName, Name, NamespacePrefix, IsReadonly, Type FROM Folder where DeveloperName='WSDLUpload'");
                if (qr.size > 0)
                {
                    Console.WriteLine("Number of folders fetched::" + qr.records.Length);
                    rF=(Folder)qr.records[0];
                }
                Document d = new Document();
                d.Description = "Test WSDL";
                d.ContentType = ".csv";
                //REQUIRED FIELD
                d.DeveloperName = "DOC" +                                       DateTime.Now.ToString("ddMMMyyyyHHmmss");

                d.FolderId = rF.Id;
                d.IsBodySearchable = true;
                d.IsInternalUseOnly = true;
                d.IsPublic = false;
//REQUIRED
                d.Name = "Doc" + DateTime.Now.ToString("ddMMMyyyyHHmmss");
                Console.WriteLine(d.DeveloperName);
                d.Type = "csv";

                UnicodeEncoding unic = new UnicodeEncoding();

                // content of the file -REQUIRED FIELD
                d.Body = unic.GetBytes("TESTTEST");

                sObject[] docs = new Document[1];
                docs[0] = d;

                SaveResult[] sResults=binding.create(docs);

                for (int i = 0; i < sResults.Length; i++)
                {
                    if (sResults[i].success)
                    {
                        // No errors, so retrieve the Id created for this record 

                        Console.WriteLine("A Document was created with Id: {0}",
                            sResults[i].id);
                    }
                    else
                    {
                        Console.WriteLine("Item {0} had an error updating", i);

                        // Handle the errors 

                        foreach (Error error in sResults[i].errors)
                        {
                            Console.WriteLine("Error code is: {0}",
                                error.statusCode.ToString());
                            Console.WriteLine("Error message: {0}", error.message);
                        }
                    }

                }
            }
            catch (Exception ex)
            {

                Console.WriteLine("\nFailed to execute query succesfully," +

                    "error message was: \n{0}", ex.Message);

            }
            
            Console.WriteLine("\n\nHit enter to continue...");

            Console.ReadLine();
        }

T-SQL

UNPIVOT: Columns to rows

January 26, 2012

Q : Write a query to format the columns of a table to rows?
A : Lets say there is a table 

DECLARE @t TABLE (
    SquadID INT, 
    Date DATETIME, 
    Q01 VARCHAR(10), 
    Q02 VARCHAR(10), 
    Q03 VARCHAR(10), 
    A01 VARCHAR(10), 
    A02 VARCHAR(10),     
    A03 VARCHAR(10))


INSERT INTO @t(SquadID, Date,  Q01, Q02, Q03, A01, A02, A03) SELECT 123,'2008-09-19','5.1','2.1','3.0','DEG','ABC','CDE'
I want a query to display results as below
Q1 A1
Q2 A2
Q3 A3


This is not straight forward we can use UNPIVOT to achieve this to some extend.  And, where clause does the trick. I found this on Internet. 


select ROW_NUMBER() OVER(ORDER BY Question_ID), Question, Answer FROM 
(SELECT Q01,Q02,Q03,A01,A02,A03 FROM @t) p
UNPIVOT
   (Question FOR Question_ID IN 
      (Q01,Q02,Q03) 
)AS up
UNPIVOT
   ( Answer FOR Answer_ID IN 
      (A01,A02,A03)
)AS an
where RIGHT(Answer_ID,1)=RIGHT(Question_ID,1);

ANT

How to package a single workflow using Force.com Migration tool?

January 26, 2012

Extracting a single workflow out of force.com can be a little tricky. I am using ANT/JAVA migration tool to extract force.com metadata. From the documentation it is clear that 'Workflow' tag should be used to extract workflow.


<types><members>*</members><name>Workflow</name></types>

The above component in project manifest - package.xml will fetch all the workflows related to Opportunity. How to fetch a specific workflow? dot operator will not work in this case. One way to get around this limitation is specifying the following components related to a workflow as appropriate.
  • WorkflowAlert
  • WorkflowFieldUpdate
  • WorkflowOutboundMessage
  • WorkflowRule
  • WorkflowTask
For example, a workflow sends an email and does a field update upon meeting a certain criterion. In package.xml, the following components should be included. 

<types>
<members>Opportunity.Set_Date</members><name>WorkflowFieldUpdate</name></types><types><members>Opportunity.Request Email</members><name>WorkflowRule</name>
</types> <types> 
<members>Opportunity.Send_Email</members<name>WorkflowAlert</name></types>

Make sure we don't miss any alert, field update, task or outbound message coupled with a rule. Upon packaging, we get the right metadata. And, upon deployment we see the workflow in the target environment. 

Email Templates

Accessing cross object merge fields in Salesforce

January 10, 2012

At present accessing cross object merge fields in email templates is not possible. You need to create a formula field pointing to the related object's custom field. Also if the related object's field's type is of "Long Text", it won't show up in advanced formula editor while creating the field. We should choose alternative type Text Area. 


Reference: 
http://success.salesforce.com/ideaView?id=08730000000Brk7AAC

APEX

Prominent limitation of time based workflow for batch processing

January 09, 2012


I was going through the following link about time based workflows. My aim was to avoid governor limits encountered for a class implementing Apex Schedulable interface. For a while time based workflow seems to be an alternative. 

Time based workflow queues its tasks. If the tasks are above the limit, it executes the left over tasks in the current run in the next hourly run. But, the following limitation may make the time based workflow unpredictable.

Time-dependent actions aren't executed independently. They're processed several times every hour, where they're grouped together and executed as a single batch. Therefore, any triggers that fire as a result of those grouped actions are also executed in a single batch. This behavior can cause you to exceed your Apex governor limits if you design your time-based workflow in conjunction with Apex triggers.

Finally, Salesforce will run all the queued jobs as a batch job on an hourly basis. Below is another blog post on the same issue.


At this point in time Schedulable interface appears to be better than time based workflow. We can use Limits Apex method to gracefully exit the batch job. As promised in the above blog if time based workflow is made to run for every 5 minutes, it may have edge over Schedulable interface. 

Popular Posts

Twitter