Using the Data Loader for Migration of Objects (Master-Detail relationship)

November 3, 2011 § Leave a comment

Using a Data Loader to migrate data from one Org to another is not that quite simple when there is a Master-detail relationship to be taken care of and maintaining the same relationship in the destination Org. I could not for the life of me remember the steps to follow whenever I am required to use Data Loader is such scenarios. And so I happen to write it down somewhere in a scrap paper and now as I have a running blog to share, I can post this and get a look every time I am going to use it in future and hopefully many will find it useful coming across this post.

Pre-requirement before following the below steps:

  1. You should have one csv file exported from the source Org which has all field values of the Master Object to be migrated to the destination Org.
  2. You should have a second csv file exported from the source Org which has all field values of the Detail Object along with the lookup ID field to the Master Object.

So here are the steps:

  • Create an External ID field in the Master Object of destination Org
  • Import the Master Object into destination Org with the ID field values(Source Org) inserted into the External ID field of destination org.
  • Export the Master Object from the destination Org along with the new ID field and the External ID field values as a CSV file.
  • Convert the ID values of both the master Object (in the csv file exported from Destination Org) and the detail Object (already exported from the source org) into a string of length 15 and then convert them with Tim’s formula to get the last 6 values of the each string in digits.
    • converting into string of 15 : =LEFT(A2,15)
    • Tim’s Formula : A3&CODE(MID(A3,13,1))&CODE(MID(A3,14,1))&CODE(MID(A3,15,1))
  • Convert any DATE fields with this formula before inserting into the destination Org
    • TEXT(A2,”yyyy-mm-ddThh:mm:ss”)&”.000Z” or select the date column and select ‘format’->’custom’ and type = yyyy-mm-ddThh:MM:ss:sssZ and press OK
  • Use VLOOKUP on the detail Object CSV file to match with the values in the Master Object CSV file
    • vlookup formula : VLOOKUP(value, table_array, match_value, case_sensitive or not(Boolean))
    • where value is the column in detail Object csv file to be searched or matched in Master Object csv file
    • and table_array is the fields(e.g. A1 to D1 till the last row) to be selected for matching in the Master Object csv file
    • and match_value is the no of the column next(usually 2) to the matched column(usually 1) in the Master Object csv file.
    • case_sensitive is the value to be given in VLOOKUP as a Boolean value either TRUE or FALSE to match for case-sensitivity.

In order to give these steps a graphical view, I have also created a diagram that can well explain what I am trying to convey in a simple way.

Data_Loader_flowOfSteps

A simple graphical view of steps to use Data Loader

In the diagram above, I have taken a simple example of an Account (Master Object) and Contact Object (Detail Object).

Feel free to comment and make this post more useful. I might not be clear in some of the steps above and it can be simplified more for beginners to understand.

Using the Inbound Email Service of Salesforce.com

November 2, 2011 § Leave a comment

If anybody has not come across this feature of Salesforce, then feel free to grok here as it is an out of the box functionality. This can help someone who needs to receive an email from outside of Salesforce and do something within Salesforce using an Apex class.

Just go to: Setup -> Develop -> Email Services.

Rest of the things are pretty straight forward. Click on “New Email Service” to create one. And then you can look up on Defining Email Services to fill in the details without much of an issue.

You would require an Apex Class to select for the field labeled as “Apex Class”. So, lets look at what you can do here:

global class ProcessEmail implements Messaging.InboundEmailHandler {
 
  global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, Messaging.InboundEnvelope envelope) 
  {
 
    Messaging.InboundEmailResult result = new Messaging.InboundEmailresult();
 
    String str = email.plainTextbody;
    List parts = str.split('\n');
    String obj_name = parts[0];
    Id obj_Id = null;
    try{
        obj_Id = [Select id from Object__c where Name =: obj_name].Id;
        
        Attachment attachment = new Attachment();
        attachment.ParentId = obj_Id;
        attachment.Name = email.subject;
        attachment.Body = Blob.valueOf(email.htmlbody);
        attachment.ContentType = 'html';
        insert attachment;
    }catch(Exception qe){
  
        Messaging.reserveSingleEmailCapacity(2);
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

        String[] toAddresses = new String[1];
        toAddresses[0] = email.fromAddress;
        
        System.debug('====> to addresse '+toAddresses[0]); 

        mail.setToAddresses(toAddresses);
        mail.setReplyTo('mandeep.deka@mycompany.com');
        mail.setSenderDisplayName('App Support Administrator');
        mail.setSubject('App Support');
        mail.setBccSender(false);
        mail.setUseSignature(false);
        mail.setPlainTextBody('The Object: ' + obj_name  +' did not match with our app.');
        mail.setHtmlBody('Your Request to add your email as an attachment to the Object_Name:<b> ' + obj_name +' </b>has not been created.'+
             'A matching record could not be found in the app');

        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
    }
       
    // Return the result for the Force.com Email Service
    return result;
 }
}

Here in the above class what we are doing is that we are reading the email sent from an anonymous address and trying to match the first line of the email with one of our Object record Name in Salesforce.com and based on that we attach the email body as an attachment to the respective Object record.

We also used a try and catch block to see if the Object record name matches with our record in Salesforce.com and if it doesn’t then we shoot back an email to the anonymous user based on the email address used to send the email to Salesforce.com.

Next, what we need to do is just add an Email address to publicize to those potential users who are going to send email to Salesforce.com i.e. to our app here.

If you have closed the Email Service window, better to open it and when you scroll down you will see a button to add “New Email Address”. Click on it and fill in the form using the help from this link Defining Email Service Addresses.

You just need to fill in the local part of the email address. Salesforce generates a unique domain-part for each email service address to ensure that no two email service addresses are identical. The generated domain-part appears to the right of the Email Address field.

One last thing that I would like to add here is that there might be a scenario when you might want to use the Email templates in Salesforce.com to use while reverting back to the anonymous user. In that case, take a look into this post Salesforce: Using basic email templates from Apex code.

One drawback of using Email Template is that the user sending the email cannot be anonymous anymore as he/she will have to be from either the Account, Contact or User because Email templates uses merge fields and there has be some access rights linked to the user who can view these fields if there are restricted sharing settings.

A few other links that might be helpful in using these service:

Where Am I?

You are currently viewing the archives for November, 2011 at Mandeep Deka.