Know Your Roots: Capture “Cloned From”

FacebookTwitterGoogleLinkedInEmail this page

I recently had a little back and forth on twitter with @abs6c about cloning. As promised to her I gave the whole cloning thing some thought and I realized there is a simple recipe you can deploy which can become the foundation for a lot of fancy customization you might want to do to the cloning process of any object.

The idea is that you can keep track of what record a clone was cloned from. This is stored in a lookup field called “Cloned From”. You can also choose to display a related list using this relationship to see all the clones created from a specific record.


1 Custom Field
1 Custom Button


The example code I will share is for the Opportunity object, but this can be accomplished with any object that has a standard Clone button. First, go to your desired object and create a new field. It should be a Lookup Relationship field type which looks up to the same object you are working on (sometimes called a hierarchical relationship). I recommend calling it “Cloned From” but you could call it something else if you want… “Ancestral Papa”, “Original Gansta”, whatever you please. Make sure that you add this field to your layouts and give your users access to edit (more on this later).

Now we create the Custom Button. For whatever object you’re applying this recipe, find the “Buttons, Links, and Actions” section and click “New Button or Link”. Label it “Clone”, and pick the “Detail Page Button” option. Behavior should be “Display in existing window without sidebar or header”. Content Source is “URL”. Now in the formula text area, copy and paste in the code below.

OPTIONAL: If you are not cooking this recipe for the Opportunity object, in the code you’ve just pasted, change the text “Opportunity” to whatever your desired object is, don’t forget to use the API Name (so use “My_Custom_Object__c” not “My Custom Object”).

REQUIRED: There are two Ids in the formula. These are both the Id of the “Cloned From” field. You should click on your “Cloned From” field in the list of custom fields in your setup and the Id of this new field is then in the URL between the “/” and the “?”. Copy these 15 characters and replace the 15 characters in the formula in both places. Note that the “CF” must remain there! Replace the 15 characters just after the “CF” with your field Id, again, in both places.

Save your Button. Now go and add it to your Page Layout(s) and remove the standard “Clone” button… unless you want to confuse the hell out of your users.

Now go try it out… clicking “Clone” now brings you to the standard Clone page but populates the “Cloned From” lookup with the record you are cloning. You can extend this is a variety of ways. Report on how often records are being cloned versus manually created or imported, run workflow when records are cloned, populate hidden fields on clones based on hidden fields from their originals… get creative!

The most obvious consideration for this solution is that the field is editable by the users who are doing the cloning. So if you have any reason to believe that your users would go populating this or meddling with the values, then this solution isn’t for you. I think for most organizations, if you put it at the bottom of the page, maybe in its own section titled “System Use Only: Do Not Modify” this would be enough. You could also put a validation rule in place to make sure this field is never edited (i.e. can only be changed on creation) if you were nervous.

The second consideration is that applying this recipe to the Opportunity object eliminates the option to Clone “with Products”. Your users would always be cloning without Products. However… you can switch that with a small addition, so that your users would always be cloning WITH products… again, no option, just always clones with the products. This can be done by adding ,”cloneli”=true just before the right square bracket.

{!URLFOR( $Action.Opportunity.Clone , Opportunity.Id , [“CF00NU0000003z92S_lkid”=Opportunity.Id,”CF00NU0000003z92S”=Opportunity.Name,”retURL”= URLFOR( $Action.Opportunity.View , Opportunity.Id) ], true)}

Be the first to comment

Leave a Reply

Your email address will not be published.