Friday, July 18, 2014

Copy Attachments From a List Item to a Document Library Using Nintex Workflow

When automating processes in SharePoint, not a lot of love is given to attachments. Your days of working around workflow limitations are over. In this blog, I'll show you how to take attachments from a list item and upload them to a document library using Nintex.

First, you'll need to install this custom action. It'll make your life easier and will allow you to complete what's described in this blog post. Essentially what it does is it enables the ability to copy documents and the content that is in them.

Erik, doesn't this post do the same thing you're describing?

No. Vadim's post covers how to copy attachments from one list item and upload the attachments to another list item. I'll be candid however, in that I'm following most of the same steps until the end.

Why not use the Read Document Action?

Glad you asked. Read Document is best suited for documents that utilize content placeholders. You can read more about it here. In my experience, I haven't seen a heckuva lot of content placeholders in action. So if you're using content placeholders for the body of a document, use the Read Document. If you're not, install the solution.

Now to the workflow. Start with a call web service action.

Call the following: Web_URL/_vti_bin/lists.asmx. Select the GetAttachmentCollection method and populate the list name and item ID from Common and Item Properties respectively.

clip_image001

This will give you a bunch of XML containing the URLs for the attachment.

Add a Query XML action and only return what's in the Attachment node. Store the result in a collection variable.

Add a Loop. This loop will go through the collection of Attachment URLs.

The first action within the loop is a Regular Expression. Within this action, the workflow will strip out everything except the name of the document.

clip_image002

Next, add and configure the custom action. It's pretty straightforward. In case you only downloaded Vadim's custom action and didn't read the entirety of his blog post, the base64 output should be a multiple lines of text variable.

Then, add another web service action. Call the following web service: Web_URL/_vti_bin/copy.asmx.

Select the CopyIntoItems method. Update the web service message with your variables.

The SourceUrl needs to be the variable containing the URL for the current attachment. The DestinationUrls is the document library where the file is going. Be sure that DestinationUrls not only points to the document library, but includes the attachment's file name. Lastly, Stream needs to be set to your base64 output variable.

clip_image003

Through this web service action, you can also tag the file's fields. One issue I ran into is I wanted to tag the document, via a lookup field, to the list item where it was originally attached to. The problem is copy.asmx does not allow you to put information into fields that are "File", "Computed", or "Lookup." Bummer. So if you want to get crazy with metatagging file, computed, or lookup fields, you'll best be suited with using the Update Item action.

We’re done right? Nope. The drawback to using Copy.asmx is that when you crack open the item properties for the doc, you get this lovely prompt:

clip_image004

I want to break this link because users will not be updating the attachment for obvious reasons and I don't want to mislead users with this prompt.

Like everything in SharePoint, there's six ways to address this problem. I'm going to introduce a seventh and final solution - courtesy this obscure post (with props to this post too).

Add a Query List action. Get the ID for the pasted document.

Then add a web service action. Call Web_URL/_vti_bin/lists.asmx and select UpdateListItems as your method.

Click SOAP Editor.

Throw this snippet in between the opening and closing <m:updates> tags:

<Batch OnError='Return'><Method ID='1' Cmd='Update'><Field Name='ID'>PastedDocumentID</Field><Field Name='MetaInfo' Property='_CopySource'></Field></Method></Batch>

First, update ListName to be the library where the documents were copied. Then within Updates, go to the Field Name node and set ID to be the ID of the document which you retrieved in the previous action.

clip_image005

While that seems like a lot of actions, and it is, but that is what it takes to copy attachments in SharePoint. Trust me it sounds and looks more intimidating than it really is. Ultimately you end up with a slick lil’ solution that not only copies attachments but removes the manual burden of unlinking copied documents.