Apex Bulk Record Cloning Controller Extension

A need came up a few days ago to create a reusable mass sObject cloning controller extension that could be used to clone many objects at once. After a bit of searching around I did not find anything that quite met my requirements:

  • Solution must be reusable on any sObject in a SalesForce organization without any code modifications. (It must be dynamic)
  • Solution must support populating a boolean field on an sObject indicating it has been cloned.
  • Solution must support standard sObject controller functionality.
  • Solution must support cloning of multiple objects at once.

The below code snippets meet all of the above mentioned requirements. To implement this solution do the following:

  • Create a class and name it cloneControllerExtension copy/paste code snippet into new class.
  • Create a VisualForce page and copy/paste markup snippet into page.
  • Create a button for the record type to be mass cloned. Configure the button as shown below:

Controller Extension Code

public class cloneControllerExtension {   

    List<sObject> objs;

    ApexPages.StandardSetController controller;

    public cloneControllerExtension(ApexPages.StandardSetController stdController)
    {
        try
        {
            objs = stdController.getSelected();
            controller = stdController;
        }
        catch(Exception ex)
        {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Please select one or more records to clone.'));
        }

    }

    //Clones selected records.
    public void Duplicate()
    {
        List<sObject> records = new List<sObject>();

        for(sObject obj : objs)
        {
            sObject clonedObj = obj.clone(false, true, true, true);

            //Attempts to populate the isCloned__c field if it is present on the sObject. Adding the isCloned__c field is recommended.
            try
            {
                clonedObj.put('isCloned__c', true); 
            }
            catch(Exception ex)
            {

            }


            records.add(clonedObj);
        }

        insert records;
    }

    //Clones selected records and returns to the previous page.
    Public PageReference DuplicateAndReturn()
    {
        Duplicate();

        PageReference reference = new PageReference(controller.cancel().getUrl());

        return reference;
    }
}

VisualForce Markup

<apex:page standardController="Asset" extensions="cloneControllerExtension"  recordSetVar="unused">  
<apex:form >  
<apex:pageBlock >

<apex:pageMessages />  
<apex:PageBlock >  
Note: Please validate records prior to clicking Clone.  
</apex:PageBlock>  
    <apex:PageblockButtons >
        <apex:commandButton value="Clone" action="{!DuplicateAndReturn}"/>
        <apex:commandButton value="Cancel" action="{!cancel}"/>
    </apex:PageblockButtons>


    <apex:pageBlockTable value="{!selected}" var="a" id="table">
        <apex:column headerValue="Name">
            <apex:outputField value="{!a.name}"/>
        </apex:column>
        <apex:column headerValue="ID">
            <apex:outputField value="{!a.ID}"/>
        </apex:column>
    </apex:pageBlockTable>
</apex:pageBlock>  
</apex:form>


</apex:page>

Example of VisualForce Page