How to Clone records in Modern Commanding

How to Clone records in Modern Commanding

In this post, I will demonstrate how to Clone a record using Modern Commanding. This will include Cloning of the primary record in addition to the ability to Clone child records.

The first step when cloning a record is to open the Model-driven app in App Designer, clicking on the More Items next to the table that we want to add the command to, and selecting the Edit Command Bar option. This will ask which command bar we would like to edit. In our case, as the Clone functionality is based on a single record, we will choose the form.

Once the Main form is open, click on the New button under the commands search box on the left panel, and select Command from the drop down menu. Enter the new Clone details, which will include the Label, Icon, Action and Visibility and click on Save and Publish. The image below shows the new Clone command that was created.

Although you can enter the code for the OnSelect function of the new Clone button in the Command Bar Designer, if you have a substantial amount of code, it is easier to do this by opening the Component Library. The Open Component Liibrary command bar item is shown on the top right of the screen. The Component Library is basically a Canvas app where we can add code to it, but with additional flexibility.

In the next few steps we will be cloning the account record, and including the associated contacts. In the first step we will use the Patch function to create the new record. The only issue with this approach is that when creating a new record the Patch function will return the record that was created. Normally I would store that record in a variable, but since Power Fx in modern commanding does not have the capability, we are unable to store the variable. The code example below will create the new record, but will not provide us with the Id of the record, which will prevent us from creating the additional child records.

Patch(Accounts,
    Defaults(Accounts),
    {
        'Account Name': Self.Selected.Item.'Account Name' & " - Clone",
        'Account Number': Self.Selected.Item.'Account Number',
        'Main Phone': Self.Selected.Item.'Main Phone',
        Website: Self.Selected.Item.Website,
        'Address 1: Name': Self.Selected.Item.'Address 1: Name',
        'Address 1: Street 1': Self.Selected.Item.'Address 1: Street 1',
        'Address 1: Street 2': Self.Selected.Item.'Address 1: Street 2',
        'Address 1: City': Self.Selected.Item.'Address 1: City',
        'Address 1: State/Province': Self.Selected.Item.'Address 1: State/Province',
        'Address 1: ZIP/Postal Code': Self.Selected.Item.'Address 1: ZIP/Postal Code',
        'Primary Contact': Self.Selected.Item.'Primary Contact'
    }
)

In order to resolve this issue, we will need to use to use the with command as part of the Patch statement. The With command will allow us to have a return value for the Patch statement. The code example below shows us the same including the With statement

With({
    AccountId:
        Patch(Accounts,
        Defaults(Accounts),
        {
            'Account Name': Self.Selected.Item.'Account Name' & " - Clone",
            'Account Number': Self.Selected.Item.'Account Number',
            'Main Phone': Self.Selected.Item.'Main Phone',
            Website: Self.Selected.Item.Website,
            'Address 1: Name': Self.Selected.Item.'Address 1: Name',
            'Address 1: Street 1': Self.Selected.Item.'Address 1: Street 1',
            'Address 1: Street 2': Self.Selected.Item.'Address 1: Street 2',
            'Address 1: City': Self.Selected.Item.'Address 1: City',
            'Address 1: State/Province': Self.Selected.Item.'Address 1: State/Province',
            'Address 1: ZIP/Postal Code': Self.Selected.Item.'Address 1: ZIP/Postal Code',
            'Primary Contact': Self.Selected.Item.'Primary Contact'
        }
    )
},

    // Clone Child records
    Notify("Account Cloned");
);

We can add additional code above the notify button to clone child records. In our case, we have a child table called Account Stakeholders. If required, we can use the following code to clone the child records as well.

    Patch('Account Stakeholders',
        ForAll(Self.Selected.Item.'Account Stakeholders' As Stakeholder,
            Patch(
                Defaults('Account Stakeholders'),
                {
                    AccountId: accountId,
                    Role: Stakeholder.Role,
                    Name: Stakeholder.Name
                }
            )
        )
    );
    Notify("Account Cloned");

Although this is not a simple logic that can be used globally, this can be customized for any table where you want to clone individual records. The screenshot below shows the successful Cloned message along with the Cloned record.