Showing posts with label Apex Code. Show all posts
Showing posts with label Apex Code. Show all posts

Get the Best Out of Apex Describe Methods

After a long absence from the blogging and community, I have finally gotten the chance to write again!
Working very hard on various exciting projects (that I will be sharing with you in the upcoming posts), had brought me to a point where I felt there was no time do anything remotely personal!

Anyhow, now that I am back at it again, let's see if I still got it...
Today I like to show you how you can use Apex describe methods in Database Queries to write less code  and take advantage of the platform's API.

First off, how many times have you thought of being able to use the following in Apex?

 SELECT * FROM Account WHERE Name LIKE 'Test%' 

Well as you know when writing SOQL queries you always have to know what fields the Object has and if a field is added or removed your query is impacted!
While there are always pros and cons in using different methods of programming, you may find the below useful in certain scenarios:

Initially we need to build a utility method and then use it later on to dynamically build our query, let's call our utility Apex class: "Util".

public class Util
{
   public static string FormatFieldsForQuery(Map<String, Schema.SObjectField> M, string prefix)
   {
       Set<string> fieldSet = M.keySet();  
       string fields = '';
       for(string f : fieldSet) fields += prefix + f +',';
       if(fields.endsWith(',')) fields= fields.substring(0,fields.length()-1);
       return fields;
   }

}

Using the above class I can receive a Map of fields and generate a comma separated string of fields.
Very useful piece of code, now we can get to the actual work: constructing the SOQL Query!

Let's being with putting the escalation of the query together:

 string query = 'SELECT '+ ? + ' FROM Account WHERE Name LIKE \'Test%\''

Where we can replace the "?" with the actual list of fields.
That brings us to the last step, accessing the Schema information in Apex.
Apex Schema class is very useful to be able to quickly access the object's meta-data without the need to perform any additional database queries (SOQL).

Schema class provides access to property called sObjectType, this property allows you to gain access to all Objects within salesforce.com and further more all of their fields:

//to access type of an object:
Account acc = new Account();
System.assert(acc.getsObjectType() == Account.sObjectType);

//to get the describe result for an object:
Schema.DescribeSObjectResult r = Account.sObjectType.getDescribe();

//To describe a field of an object:
Schema.DescribeFieldResult f = Schema.sObjectType.Account.fields.Name;

//To get a map of all fields an object:
Map<String, Schema.SObjectField> map;
map = Schema.SObjectType.Account.fields.getMap();


Using the last statement (from above) it seems like I can get a list of all fields an object and then pass to it my Util class to get a comma-separated list of fields!
Now I guess all the pieces of the puzzle are coming together, let's add them all up and see how it goes:

//get the fields Map:
Map<String, Schema.SObjectField> map;
map = Schema.SObjectType.Account.fields.getMap();

//get the field list:
string fields = Util.FormatFieldsForQuery(map);

//perform the query:
string q = 'SELECT '+ fields +' FROM Account WHERE Name LIKE \'Test%\''
List<Account> accounts = Database.Query(q);

There is definitely more to learn about Schema class and what it offers, in future posts I will try to cover some of usages that you might find it useful or intriguing!
Ciao for now.


Utilizing the Power of Batch Apex and Async Operations

If you have tried before to remove custom object records in bulk from your org, you know the hassle you need to go through to export the records into an excel file and then have the DataLoader delete those records. Not only that, what if you need to perform further data integrity tasks before removing the records? Mass updating, inserting and other similar scenarios like this can be more conveniently handled with force.com's Batch Apex. With Batch Apex you can now build complex, long-running processes on the platform. This feature is very useful for time to time data cleansing, archiving or data quality improvement operations. One thing that you need to consider is that you should trigger the batch job using Apex code only and force.com by default does not provide scheduling feature your batchable Apex classes. In order to do that you need to write Apex class that implements a "Schedulable" interface. The following example shows how you can utilize the model to mass delete records of any object in force.com platform. In order to develop your Batch Apex, you need to create a new Apex class which extends "Database.Batchable" interface. This interface demands for three methods to be implemented:
  • start
  • execute
  • finish
"start" method is called at the beginning of a batch Apex job. Use this method to collect the records (of objects) to be passed to the "execute" method for processing. The Apex engine, automatically breaks the massive numbers of records you selected into smaller batches and repeatedly calls the "execute" method until all records are processed. The "finish" method is called once all the batches are processed. You can use this method to carry out any post-processing operation such as sending out an email confirmation on the status of the batch operation. Let's take a closer look at each of these methods:
global Database.QueryLocator start(Database.BatchableContext BC) {
//passing the query string to the Database object.      
return Database.getQueryLocator(query);
}
Use the Database.getQueryLocator in the "start" method to dynamically load data into the Batch Apex class. Using a Querylocator object, the governor limit for the total number of records retrieved from the database is bypassed. Alternatively you can use the iterable when you need to create a complex scope for your batch job. Execute method:
global void execute(Database.BatchableContext BC, List<sObject> scope) {

// in this sample, we simply delete all the records in scope    
delete scope;
}
This method provides two parameters Database.BatchableContext and a list of records (referred to as "scope"). BatchableContext is generally used for tracking the progress of the batch job by all Batchable interface methods. We will use this class more in our "finish" method. Finish method:
global void finish(Database.BatchableContext BC){
// Get the ID of the AsyncApexJob representing this batch job  
// from Database.BatchableContext.  
// Query the AsyncApexJob object to retrieve the current job's information.  

AsyncApexJob a = [Select Id, Status, NumberOfErrors, JobItemsProcessed,
  TotalJobItems, CreatedBy.Email
  from AsyncApexJob where Id =:BC.getJobId()];
// Send an email to the Apex job's submitter notifying of job completion.  

Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
String[] toAddresses = new String[] {a.CreatedBy.Email};
mail.setToAddresses(toAddresses);
mail.setSubject('Apex Sharing Recalculation ' + a.Status);
mail.setPlainTextBody
('The batch Apex job processed ' + a.TotalJobItems +
' batches with '+ a.NumberOfErrors + ' failures.');
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}
By using the BatchableContext we are able to retrieve the jobId of our batch job. AsyncApexJob object in force.com allows you to gain access to the status of the async jobs as shown in the above example. In this method I have utilized the Apex email library to send a notification to the owner of the batch job (whoever triggered the job in the first place). Now, let's put it all together:
global class MassDeleteRecords implements  Database.Batchable<sObject> {

global final string query;

global MassDeleteRecords (String q)
{
   query = q;
}

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

   return Database.getQueryLocator(query);
}

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

  delete scope;
}


global void finish(Database.BatchableContext BC){
  // Get the ID of the AsyncApexJob representing this batch job  
  // from Database.BatchableContext.    
  // Query the AsyncApexJob object to retrieve the current job's information.  

 AsyncApexJob a = [Select Id, Status, NumberOfErrors, JobItemsProcessed,
   TotalJobItems, CreatedBy.Email
   from AsyncApexJob where Id =:BC.getJobId()];

  // Send an email to the Apex job's submitter notifying of job completion.  
  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
  String[] toAddresses = new String[] {a.CreatedBy.Email};
  mail.setToAddresses(toAddresses);
  mail.setSubject('Apex Sharing Recalculation ' + a.Status);
  mail.setPlainTextBody('The batch Apex job processed ' + a.TotalJobItems +
    ' batches with '+ a.NumberOfErrors + ' failures.');

  Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}

}

 Ok, that's as far as we go for the Batchable Apex class in this article. Now let's write the code in Apex to run the class and test it:
String query = 'SELECT id, name FROM Account WHERE OwnerId = \'00520000000h57J\'';
MassDeleteRecords batchApex = new MassDeleteRecords(query );
ID batchprocessid = Database.executeBatch(batchApex);

The above code removes all accounts that the user id= 00520000000h57J owns them. As it is apparent, now you can run the batch job from within your Visualforce pages, triggers (with caution), etc. For governing limit and best practices documentation you can refer to the Apex Developer Guide.

Utilizing Apex Pattern and Matcher Classes

In many projects I am involved with I need to validate a string of data or transform the string into a new one with a specific format. Processing the text by the means of String primitive type methods or your custom handling could a big undertaking and time consuming task.

Sometimes, one needs to write hundreds of lines of code, to process a string and make sure it’s valid (formatted as expected) or transform it into proper format. Some examples of this are validating a string to see if it’s a correct email address, postal code, phone number or URL. Some other examples are grabbing html tags or striping down the XML or HTML tag to get a clear text, trimming the whitespaces, removing duplicate lines or items and many more.

Apex in Force.com platform has just the right set of classes to help you carry out such operations pretty much the same way Java does it.

“A regular expression is a string that is used to match another string, using a specific syntax. Apex supports the use of the regular expression through its Pattern and Matcher classes.” Quoted right from the holly guide. Any regular expression that is written for Java can be used with Apex as well.

In order to utilize these classes we first need to know what each of them does.

Pattern class is designed to contain the regular expression string and you compile the expression into an object of this class. You only need to use this class once. Using this class you will be able to create a Matcher object by passing your string (on which you want to carry out surgery or validation).


pattern myPattern = pattern.compile('(a(b)?)+');




Matcher in turn allows you to do further actions such as checking to see if the string matched the pattern or allows you to manipulate the original string in various ways and produce a new desired one.



matcher myMatcher = myPattern.matcher('aba');



Let’s explore some samples of using regular expressions in Apex and see how we can benefit from them:

My first example will be how to validate an email address. I personally had some struggles with this since the email addresses can get pretty ugly at times. Imagine this email address:

name.lastname_23@ca.gov.on.com



String InputString = 'email@email.com';
String emailRegex = '([a-zA-Z0-9_\\-\\.]+)@((\\[a-z]{1,3}\\.[a-z]{1,3}\\.[a-z]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})';
Pattern MyPattern = Pattern.compile(emailRegex);

// Then instantiate a new Matcher object "MyMatcher"
Matcher MyMatcher = MyPattern.matcher(InputString);

if (!MyMatcher.matches()) {
// invalid, do something
}



Some more examples on validations:



// to validate a password
String RegualrExpression_Password = '((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%]).{6,20})';

//image file extention
String RegualrExpression_ImgFileExt = '([^\s]+(\.(?i)(jpg|png|gif|bmp))$)';

//to validate an IP Address
String RE_IP = '^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$';

//date format (dd/mm/yyyy)
String RE_date = '(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\\d\\d)';

//to match links tag "A" in HTML
String RE_ATags = '(?i)<a([^>]+)>(.+?)</a>';






Another way that you can benefit from the Matcher class to to reformat the string.

Below is an example that shows you, how you can strip the HTML tags from a string and extract the plain text. This is very useful when you want to record email contents into Salesforce or covert the HTML version of an email into it's plain text counterpart.



string html = 'your html code';
//first replace all <BR> tags with \n to support new lines

string result = html.replaceAll('<br/>', '\n');
result = result.replaceAll('<br />', '\n');

//regular expression to match all HTML/XML tags
string HTML_TAG_PATTERN = '<.*?>';

// compile the pattern
pattern myPattern = pattern.compile(HTML_TAG_PATTERN);

// get your matcher instance
matcher myMatcher = myPattern.matcher(result);

//remove the tags
result = myMatcher.replaceAll('');





For complete reference of Java regular expressions please refer to: here

Flex Rich Clients and Complex Logics!

Nowadays many developers are driven or forced toward using richer UIs such as Adobe Flex by their customers. Using Adobe Flex and AIR technologies you can create fancy user interfaces with drag and drop functionality, applications that easily integrates with force.com Webservice APIs, takes the data offline and syncs it back to the source once connected to internet again.

All that is very interesting and cool, however one should bear in mind that all the operations, Web Service calls, etc are running in the user's browser (client machine) not on force.com servers.

For this very specific reason, one has to consider how to best design the applications to utilize the cloud computing power of force.com technology and leave the chunk of heavy operations (program logic) out of the client's machine.

The following example which is proven to be useless in the real world, shows you how to host your main operations (chunk of code) in the force.com platform and then share them in form of Web Service methods with your flex applications.

I first start with creating a new Apex class which is pretty much the same as any other Apex class you have seen before but with a few minor changes.

The Apex class is where I intend to do my main operation. I'd rather use my Flex application to utilize such Apex classes and merely view the data in proper form to the user (where possible).

Points:
  • Any Apex class which wants to share a method over the web needs to be marked as "global"
  • Any method of this class that must be reachable by our Flex app should be mark as "WebService"
  • Any internal variable or class that are used in the parameter or as output of the WebService methods also needs to be marked as "WebService".
Below is the implementation of a sample Apex class which shares a method as "WebService".



global class MyWebService
{
global class CompositeData
{
WebService String CompanyName;
WebService String FullName;
WebService String Id;
}

Webservice static MyWebService.CompositeData[] SearchContacts(String keywords)
{
List<CompositeData> results = new List<CompositeData>();

//search logic.
List<List<SObject>> data = [Find :keywords IN ALL FIELDS
RETURNING Contact (id, Name, Account.Name)];

List<SObject> contacts = data[0];

for(SObject contact : contacts)
{
CompositeData cd = new CompositeData();

cd.Id = contact.Id;
cd.FullName = ((Contact)contact).Name;
cd.CompanyName = ((Contact)contact).Account.Name;


results.add(cd);
}

return results;
}
}



The above example demonstrates how you can share a such class as structure other than Apex's SObject class.

This allows you to run multiple queries and aggregate data from various objects in force.com platform and then return them back to the Flex application using the new structure ("CompositeData" in this example).

Now let's see how we can use the above method in our Flex application. Let's say that we use a Flex wrapper class to call this Apex method and then expose this class (Flex class) to our Flex application.

I believe the comments in the code should guide you through the steps.



package com
{
import com.salesforce.AsyncResponder;
import com.salesforce.Connection;
import com.salesforce.objects.Parameter;
import com.salesforce.results.Fault;

import mx.collections.ArrayCollection;
import mx.controls.Alert;



public class MyFlexWebServiceClient
{

//a public property to provide access to the final results
public var results : ArrayCollection;

//force.com connection object
private var binding : Connection;

//the class constructor
public function MyFlexWebServiceClient()
{
results = new ArrayCollection();
}

// this method will be called from the Flex application script
// section once it is instantiated
public function init(Connection sfdcConnection)
{
//the class receive the SFDC connection object from the parent application
this.binding = sfdcConnection;

if (!this.binding.IsLoggedIn)
throw new Error("Connection to the server is not available.");
}

//this method is the wrapper method that calls the force.com webservice
public function execute(keywords: String): void
{
//validation
if (keywords == null || keywords.length <= 0)
{
//handle the invalid data
return;
}

//preparing the parameters of the web service method
var params : Array = new Array(1);

var param1 : com.salesforce.objects.Parameter = new Parameter("keywords", keywords);
params[0] = param1;

// using SFDC Aysync Responder to get the results in flex
var tempCallBack: AsyncResponder = new AsyncResponder(
function(result:Object):void {

if (result != null)
this.results = result as ArrayCollection;
else
Alert.show("Result is empty.", "Info");
},
function(result: Fault):void { Alert.show("Operation failed", "Error"); }
);

// call the execute method of the SFDC connection object to reach out the web service
binding.execute("MyWebService", "SearchContacts", params, tempCallBack);

}

}
}



Happy holidays and new year!

Triggering an Apex method with a Custom Button

Most often Salesforce.com developers want to write a custom logic such as sending a notification email, changing the status of a record (picklist), etc once a button is clicked on, in a standard layout.

The effort is minimized this way since you do not want to recreate the layout using a Visualforce page, all you need is to be able to launch a method once the button is clicked on.

In order to do so, you need to write your logic into an Apex class with following conditions:
  1. Firstly, your class should be marked as "Global"
  2. Secondly, the logic goes to a static method of this class which is marked as "WebService"
If an Apex class has the above characteristics, the method marked as web service can be called via javascript when the button is clicked on. Neat!

I think by now you have a good idea of where I am going with this, so let's dive into code and examine everything more closely.

Below I have created a Apex Class called "OutboundEmails" and added a method that has a keyword as "WebService".


global class OutboundEmails {

WebService static void SendEmailNotification(string id) {

//create a mail object to send a single email.
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

//set the email properties
mail.setToAddresses(new string[] {'myemail@domain.com'});
mail.setSenderDisplayName('SF.com Email Agent');
mail.setSubject('A new reminder');
mail.setHtmlBody('an object with ID='+ id + ' is just clicked on.');

//send the email
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail } );

}
}




This method receives an object Id (this is just to demo purposes, so you can identify any parameters that you need) and sends an email notification subsequently once the method is called.

Now let's concentrate on the button that will actually call our WebService method.

Firstly, I create a detail page button let's say on Account object and name it "Send Me ID".
This button's behavior will be "Execute Javascript".
If you need more information about how you can add a custom button to Account object please click here. Then I add the following code to the body of the button edit page:



{!REQUIRESCRIPT("/soap/ajax/10.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/10.0/apex.js")}
sforce.apex.execute("OutboundEmails","SendEmailNotification", {id:"{!Account.Id}"});
window.alert("Account Id is sent." );



Now It all works together!
Once you click on the button, in case you have not forgotten to change the sample email address with your own in the code, you should receive the email.

URLFOR function finally explained!

While developing your Visualforce pages you may need to be able to obtain the URL of certain actions, s-controls or your static resources.

I found it personally a challenge since the documentation for "URLFOR" function is not included in "Visualforce Developer Guide" itself and instead included in the general help area of Salesforce.

Generally you can use the "URLFOR" function for three purposes:
  1. Obtain URL of a s-control
  2. Obtain URL of a static resource
  3. Obtain URL of an object's action
In this article I will demonstrate usages of the three above.

Generally, URLFOR function returns a relative URL for an action, s-control, or a file in a static resource archive in a Visualforce page. Following the syntax of the function:

{!URLFOR(target, id, [inputs], [no override])}

Parameters shown in brackets ([]) are optional.

  • target: You can replace target with a URL or action, s-control or static resource.
  • id: This is id of the object or resource name (string type) in support of the provided target.
  • inputs: Any additional URL parameters you need to pass you can use this parameter.
    you will to put the URL parameters in brackets and separate them with commas
    ex: [param1="value1", param2="value2"]
  • no override: A Boolean value which defaults to false, it applies to targets for standard Salesforce pages. Replace "no override" with "true" when you want to display a standard Salesforce page regardless of whether you have defined an override for it elsewhere.

Obtaining URL of a s-control:

<!-- Use $SControl global veriable to reference your s-control and pass it to the URLFOR function -->
<apex:outputLink value="{!URLFOR($SControl.MySControlName)}">Link to my S-Control</apex:outputLink>



Obtaining URL of a Static Resource

<!-- Use $Resource global veriable to reference your resource file -->
<apex:image url="{!URLFOR($Resource.LogoImg)}" width="50" height="50" />

<!-- If your file is in another ZIP file, then pass the path of the file as id to URLFOR -->
<apex:image url="{!URLFOR($Resource.CorpZip, 'images/logo.gif')}" width="50" height="50" />




Obtaining URLs of an Object's Actions:
In order to get URL of the an object's actions you need to know what actions that object supports. Below are some of the common actions most Objects support:
  • View: Shows the detail page of an object
  • Edit: Shows the object in Edit mode
  • Delete: URL for deleting an object
  • New: URL to create a new record of an object
  • Tab: URL to the home page of an object
However, each object may support additional actions for example Contact also supports "Clone" action and Case supports "CloseCase" action.

<!-- Use $Action global varialble to access the New action reference -->
<apex:outputLink value="{!URLFOR($Action.Account.New)}">New</apex:outputLink>
<br/>
<!-- View action requires the id parameter, a standard controller can be used to obtain the id -->
<apex:outputLink value="{!URLFOR($Action.Account.view, account.id)}">View</apex:outputLink>
<br/>
<!-- Edit action requires the id parameter, id is taken from standard controller in this example -->
<apex:outputLink value="{!URLFOR($Action.Account.Edit, account.id)}">Edit</apex:outputLink>
<br/>
<!-- Delete action requires the id parameter, also a confirm message is added to prevent deleting the record when clicked by mistake -->
<apex:outputLink value="{!URLFOR($Action.Account.delete, account.id)}" onclick="return window.confirm('Are you sure?');">Delete</apex:outputLink>
<br/>
<!-- From all custom buttons, links, s-controls and visualforce pages you can use the following to get the link of the object's homepage -->
<apex:outputLink value="{!URLFOR($Action.Account.Tab, $ObjectType.Account)}">Home</apex:outputLink>



A Utility Apex Class to Convert All Types Into String

If you have been in the programming world long enough, you already know that casting types from one to another specially string representation of the variables is always part the job.

Whether you want to show the data to user or form the variables in different formats, incorporate them in messages, etc.

In this article I will present you one of the Apex classes I have written to help me faster develop Salesforce Applications.

This class helps me in number of ways, for example I do not need to worry about the underlying Apex code to convert a primitive type to string anymore, for all types I just need to call one method "ToString" and it will take care of for me.
Also the methods provide me with formatting capabilities, so I can not only convert to string but also format the string in many ways I need.

Look at the below code and see how the results are:



ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO,'Integer: '+ zConvert.ToString(13434)));
 ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO,'Double: '+ zConvert.ToString(1.23)));
 ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO,'Boolean: '+ zConvert.ToString(true)));
 ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO,'Date: ' + zConvert.ToString(date.newinstance(1960, 2, 17))));
 ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO,'Date time: ' + zConvert.ToString(Datetime.now(),'MMM, dd yyyy')));
 ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO,'File Size: '+ zConvert.FileSizeToString(6766767)));
 ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO,'Money: '+ zConvert.CurrencyToString(Decimal.valueOf(34.99),'$'))




This is the result of running the above code:



Well, very nice, now let's see how the actual class is developed:
Because I would like to directly call my Coverter's class methods without creating a new instance of the class, I have defined all the methods as "static".

The methods for this class are:
  • ToString(Integer)
  • ToString(Double)
  • ToString(Long)
  • ToString(Boolean)
  • ToString(Date)
  • ToString(Date,format)
    sample: zConvert.ToString(mydate,'MM-dd-yy')
  • ToString(Time)
  • ToString(Time,format)
    sample: zConvert.ToString(myTime,'hh:mm:ss')
  • ToString(Datetime)
  • ToString(Datetime,format)
  • ToString(Decimal)
  • ToString(Decimal, ScientificNotaion)
    ScientificNotaion is a Boolean value and if false is passed then the string will not have scientific notations.
  • FileSizeToString(Long)
    Returns values such as "5.5 KB", "8 MB", etc. Parameter passed is in bytes.
  • CurrencyToString(Decimal, CurrencyChar)
    CurrencyChar can be "$", "£", etc




public class zConvert
{
 /* The Initial Developer of the Original Code is Sam Arjmandi.
 * Portions created by the Initial Developer are Copyright (C) 2008
 * the Initial Developer. All Rights Reserved. 
 * 
 * This Code is provided "As Is" without warranty of any kind.
 */
 
  public static String ToString(integer Value)
  {
      /* string representation if an Integer value */
      return Value.format();
  }
 
  public static String ToString(Double Value)
  {
    /* string representation if a Double value */
     return Value.format();
  }
 
  public static String ToString(Boolean Value)
  {
     /* string representation if a Boolean value */
     if (Value)
       return 'true';
     else
       return 'false';
  }
 
  public static String ToString(Long Value)
  {
    /* string representation if a Long value */
    return Value.format();
  }
 
  public static String ToString(Date Value)
  {
     /* string representation if a Date value */
     return Value.format();
  }
 
  public static String ToString(Date Value,String format)
  {
    /* string representation if a Date value with formatting */
    Datetime temp = Datetime.newInstance(Value.year(), Value.month(), Value.day());
    return temp.format(format);
  }
 
  public static String ToString(Datetime Value)
  {
     /* string representation if a Datetime value */
     return Value.format();
  }
 
  public static String ToString(Datetime Value,String format)
  {
     /* string representation if a Datetime value with formatting */
     return Value.format(format);
  }
 
  public static String ToString(Time Value)
  {
    /* string representation if a Time value */
    return String.valueOf(Value);
  }
 
  public static String ToString(Time Value, String format)
  {
    /* string representation if a Time value with formating */
    Datetime temp = Datetime.newInstance(1970, 1, 1, Value.hour(), Value.minute(), Value.second());
    return temp.format(format);
  }

  public static String ToString(Decimal Value)
  {
    /* string representation if a Decimal value */
    return Value.format();
  }
 
  public static String ToString(Decimal Value, Boolean ScientificNotation)
  {
    /* string representation if a Decimal value with or without Scientific Notation */
    if (ScientificNotation)
     return Value.format();
    else
     return Value.toPlainString();
  }
 
  public static String FileSizeToString(Long Value)
  {
     /* string representation if a file's size, such as 2 KB, 4.1 MB, etc */
     if (Value < 1024)
       return ToString(Value) + ' Bytes';
     else
     if (Value >= 1024 && Value < (1024*1024))
     {
       //KB
       Decimal kb = Decimal.valueOf(Value);
       kb = kb.divide(1024,2);
       return ToString(kb) + ' KB';
     }
     else
     if (Value >= (1024*1024) && Value < (1024*1024*1024))
     {
       //MB
       Decimal mb = Decimal.valueOf(Value);
       mb = mb.divide((1024*1024),2);
       return ToString(mb) + ' MB';
     }
     else
     {
       //GB
       Decimal gb = Decimal.valueOf(Value);
       gb = gb.divide((1024*1024*1024),2);
      
       return ToString(gb) + ' GB';
     }
    
  }
 
  public static String CurrencyToString(Decimal Value, String CurrencyChar)
  {
     return CurrencyChar + ToString(Value);
  }
 
}



How add a detail button to your Objects?

Let's imagine that we have a VF page which receive two address URL parameters (From and T0) and show us the driving direction from the "from" address to the "to" address.

Using the page we want to add a detail button to Sales Force Account object called "Driving Direction" and once the Sales Rep click on this button can actually view the driving directions from his office to the client's (Account's) location.

Neat, ha?

So, this is how we go about and do this:

  1. Go to "Setup" page (link located on the top right corner of the page)
  2. Under the "App Setup" expand the "Customize" item
  3. Find Account object and expand it
  4. Click on "Buttons and Links"
  5. On the "Custom Links and Buttons" section click on "New"
  6. Enter Label, Name, Description and Select "Detail Page Button" as type
  7. Behavior="Display in new Window" and Content source="URL"
  8. Let's imagine that your VF page name is "MapDirections". Then enter the following code into content of the button:



/apex/MapDirections?to={!Account.BillingPostalCode},{!Account.BillingState},{!Account.BillingCountry}&from={!$User.PostalCode},{!$User.State},{!$User.Country}

The above text includes a combination of a URL text and a few tags which later on will be replaced with actual data.

Generally tags follow this format: {!field-name} . You can easily see what field types and field names are available to you using the two dropdown lists provided by Sales Force.

And with this we are done with creating the Detail button however we won't be able to see it on the Account's detail page before we add it into the Account's Layout.

In order to add the button to the Account's layout:
  1. Go to: Customize -> Accounts --> Page Layouts
  2. Edit any or all page layout on which the Custom Button should be visible
  3. Once you click on "Edit" layout button you can view the Account's layout page
  4. On the "Button Section" double click on "Detail Buttons"
  5. A new window opens up, look at the "Custom Buttons" section your button must be listed there.
  6. Add the button to the "Selected Buttons" list and click on.
  7. Save the Layout and now you will be able to see your button as it is depicted below:

How to get your SalesForce instance URL address

Often I see programmers has a challenge to problematically find what their SalesForce instance address is.

Whatever, your instance might be:
- cs2
- emea
- na5
- na4

One way of tackling this issue that you might find it useful:

You can always use the following javascript code to get the URL:






Code:
// getDomain() is called to obtain the domain portion of web app
function getDomain()
{
var url = window.location.toString();
var domain = url.match( /:\/\/(www\.)—([^\/]+)/ );
domain = domain[2]?domain[2]:'';

return domain;
}