Copy Files from One Object Record to Another.

Copy Files from One Object Record to Another | Automate This!

By

Welcome to another “Automate This!” In this live-streamed video series, we cover all things automation, from use cases and best practices to showcasing solutions built by Awesome Admin Trailblazers like you. With automation, you can remove manual tasks, drive efficiency, and eliminate friction and redundancy. In this episode, see how Eric Smith created a subflow to copy files from one object record to another.

The business need: Copy all files automatically from one record to another

There are times when you may want to automate the copying of all the files attached to one record to another record. An example of this might be when closing an opportunity, copy all the files attached to the opportunity record to another record such as a newly created quote or contract.

Salesforce uses a junction object called ContentDocumentLink that includes a lookup to the file (ContentDocument) as well as the record ID of the object record it’s attached to. This subflow references and creates those records to handle the copying of the files.

Subflows are a way to create a separate flow with a series of actions that can be shared and reused by other flows. Values can be passed into the subflow, and other values can be passed back to the calling flow.

The solution #1: A simple subflow to copy files

To handle the steps needed to copy files from one record to another, this subflow gets all of the ContentDocumentLink records pointing to the source record and loops through those to build new ContentDocumentLink records that reference the target record.

Simple subflow to copy files.

The only input attributes needed for the subflow are the record IDs of both the source record and the target record.

Input Attribute

Type

Notes

vSourceObjectId

Text

Record ID of the source record

vTargetObjectId

Text

Record ID of the target record

Because this subflow is designed to be reusable in a number of different ways, it’s important to build in some error checking and processing. To let the calling flow know if there were any errors, the subflow passes back two output attributes. One is a boolean value that’s set to True if there was an error, and the other is a text value with the corresponding error message.

Output Attribute

Type

Notes

vIsError

Boolean

(Optional) True if there was an error in the sub flow

vErrorMessage

Text

• Either or both of the source or target record IDs are blank.

• There are no files attached to the source record.

• There was an error creating the Target Document Links.

Let’s break down the flow to see how this is done.

The first Decision checks for errors by determining if either of the input attributes are null or empty.

Edit Decision page for Have Record Ids?

If both record IDs are provided, the Get Records element gets all of the ContentDocumentLink records for the source record. The LinkedEntityId field stores the record ID of the Salesforce record that the file is attached to.

Edit Get Records page for Get Source Files.

The next Decision element checks to make sure that at least one file was attached to the source record by seeing if the result of the Get Records element isn’t empty.

Edit Decision page for Found Source Files?

Now we can attach the files to the target record by looping through each of the ContentDocumentLink records from the source record.

Edit Loop page for Content Document Links.The first Assignment element in the Loop changes the value of the Linked Entity Id field from the source record ID to the target record ID and clears the existing record ID from the ContentDocumentLink record. Note: The Create Records element that we use later requires that each of the records does not have a value for the record ID, as that will be inserted automatically when the records are created.

Edit Assignment page for Set Target Link & Clear Record Id.

Since we don’t want to create individual records inside of a Loop, we add this new record to a collection variable for ContentDocumentLink records (colContentDocumentLinksNew) using an Assignment element.

Edit Assignment page to add the ContentDocumentLink to the collection variable.

After the Loop, we use a Create Records element to create all the records stored in the colContentDocumentLinksNew collection variable.

Edit Create Records page to Create Target Content Document Links.

We do one last error check by adding a Fault path to the Create Records element in case something goes wrong with the record creation.

Fault path from the Create Records element in the event there is a failure.

Each of the three Assignment elements in the error paths in the flow sets the vIsError variable to True and sets the appropriate vErrorMessage text value.

Edit Assignment page to Set Create Target Error.

How to call the subflow

To call this process from your primary flow, add a Subflow element and handle any required error processing.

Subflow element in the calling flow.

Specify the source and target record IDs in the subflow attributes.

Edit Subflow page for Copy Files From Opportunity to Contract.

Next, add a Decision element to check if the subflow returned any errors.

Edit Decision page for Was there an error?

This example uses a Screen element to display the error.

Edit Screen page showing Screen element properties.

The solution #2: An advanced subflow to copy files

The flow outlined above works great when you’re copying files to the target record for the first time. If your needs require that you copy files from one object to another multiple times, you want to make sure you’re not duplicating files that are already attached to the target record.

This advanced version of the copy files subflow adds the additional steps to check the target record first to make sure no files are duplicated.

Advanced subflow to copy files with nested Loops.

Advanced subflow to copy files (without nested Loops)

One of the performance drawbacks of the advanced flow shown above is that it requires nested Loops to check each file in the source file collection against every file in the target file collection to see if the source file already exists in the target collection.

The performance of the advanced flow can be improved by calling an invocable Apex action that handles the comparison for you and returns a collection of just the source files that are not already attached to the target record.

Advanced subflow to copy files with an invocable action.

Installation links

You can use these links to install the referenced flows in your own orgs. You should always install into a dev or sandbox org and test before you install anything into a production org. Once you click on the link, you’ll be asked to sign in to your dev or sandbox org, and then the flow(s) will be created in that org.

Standard and advanced (Loops) versions

Dev org
Sandbox org

Advanced version with invocable action

Dev org
Sandbox org

Note: This third-party Apex code has not gone through a Salesforce security review and should be reviewed by a developer to make sure it meets your organization’s coding standards prior to installing in a production org.

Collection Processors for Flow (required for the advanced version with invocable action)

Resources

Want to see more good stuff? Subscribe to our channel!

SUBSCRIBE TODAY
Use Flows and Experience Cloud to Access Salesforce Scheduler.

Use Flows and Experience Cloud to Access Salesforce Scheduler | Automate This!

Welcome to another “Automate This!” In this live-streamed video series, we cover all things automation, from use cases and best practices to showcasing solutions built by Awesome Admin Trailblazers like you. With automation, you can remove manual tasks, drive efficiency, and eliminate friction and redundancy. In this episode, learn how Lynn Guyer requests support from […]

READ MORE