How To: Copy Attachments from a list item to a document library

An addition to the functionality of my last blog post, where I created a UDA that allows you to extract the list item attachment URL(s). This might be sufficient in some scenarios, but wouldn’t it be much better to move the attachments into their own library where they can be handled like real files in SharePoint? That’s what this UDA will be doing for you.

A company maintains a SharePoint list for job applications. The list not only stores job applications but also attachments that were submitted alongside the job application. Now they need to extract all attachments accompanying a list item (aka job application) to be able to tag them with metadata and maintain their own document repository. Also, some of the documents might be used to form part of a contract and will be attached as an appendix.

How does it work?
You might notice an action within the workflow that is not an out of the box action coming with Nintex Workflow. This actions was developed as a custom action by my colleague and fellow Nintex TE Vadim Tabakman. For my UDA to work you will have to download his action from his blog. Instructions for the installation and deployment can be found on the blog. Just a note of advice, neither my UDA nor his custom action are official Nintex Workflow actions, hence there will be no support provided by Nintex. They are solely our own work and doing. Any installation and usage in a production environment are done at your very own risk.

Ok, back to the workflow.

We are using a web service, which comes out of the box with SharePoint. The Lists (http://[SITEURL]/_vti_bin/lists.asmx) web service. It lets us interact with lists anywhere in our SharePoint environment. The web method we are interested in is the GetAttachmentCollection one. It returns all attachments assigned to a list item as part of an XML. 

Within the UDA we call the Lists web service first and get all attachments as part of an XML. In case there was an error, the UDA records the error occurrence and spits out an error message, which you can handle appropriately within your workflow. The same for the Query XML action. The next step is to extract all attachment URLs using the Query XML action. The individual results are stored in a collection, which is then returned as part of the UDA.

The next step is to create a variable that will serve as the index for the For Each action. In the For Each action we iterate through the collection of extracted URLs. In order to construct the proper destination file URL we need to extract the filename and file extension using a Regular Expression action. As this action stores all results in a collection, we have to use the Collection Operation action to get the first entry from the collection we used to store the filename. Once we have that, we can pass the information on to Vadim’s action, which returns a base64 encoded string that we store in a multiple line of text variable.

Finally, we build up the destination file URL and use the Copy web service (http://[SITEURL]/_vti_bin/copy.asmx) method CopyIntoItems() to copy the attachment to the specified library. As the other Call Web Service action, we make use of the error handling, which will return a proper error message in case something goes wrong.

That’s it. Simple, isn’t it? Well, not quite as simple as you might have expected, but it works. This time with a bit of code in form of Vadim’s custom action and just using web services which SharePoint already provides.

How do I use the UDA?
Drop the UDA into your workflow where required. The UDA requires a few input parameters: 

  • Item ID – the ID of the item we want to get the attachments from
  • List Name – the name of the list containing the item
  • Site URL – the URL of the site the list sits in. This is required to make the UDA work with ANY list in your environment.
  • Target Library URL – the URL of the library you want the attachments to be moved to

In the event of an error within the UDA (connection issues, etc.) there are 2 output parameters: 

  • Error Message – The message returned by the web service that errored
  • Error Occurrence – Indicates that an error occurred within the UDA

Using the output parameters will help you to handle the exception appropriately within your workflow.

Last but not least, the UDA also contains an output parameter “Attachments URLs” which contains the collection of all attachment URLs for the specified item. Note that the returned URLs in the collection are URLs to the attachments, not the copies in the library!

The following is an example configuration of the UDA. The variable varTargetLibraryURL is a variable I created in the workflow, which is then filled with a value using the build string action. That way the target library URL can be kept dynamic.

The web services in the UDA uses a workflow constant (Site Collection Level) called “SharePoint Web Service Account” of the type credential. You will have to create this constant before you can use the UDA. The account will have to be able to read web services across the site collection, so read only access to all sites for this account will be fine.


Copy List Attachment – UDA and NWF files

Tags: , , ,

2 Responses to “How To: Copy Attachments from a list item to a document library”

  1. Fernando August 29, 2017 at 8:36 PM #

    Hi Patrick, thank you for sharing the UDA. We are trying to make it work but when we execute the workflow (when user modifies a list item with attachments), it says “Error: Index property is greater than the number of items in the collection.”

    We’ve created the workflow constant and configured the initial parameters correctly. Do you know why this is happening?

    Thank you!

    • Patrick Hosch October 17, 2017 at 9:49 AM #

      Hi Fernando, apologies for the delay. Havent kept an eye on my blog. Looks like there is no item being returned in the collection. So the count in the collection is 0 and the count in index might be 1 or greater. I’d investigate how many items are being returned if any

Leave a Reply