Deleting Deeply Entrenched Site Columns - Another Reason for Governance
I was recently called back to a previous client to help with a list of issues and tasks they had accumulated, and I was surprised to find one very difficult one:
The client complained about seeing multiple duplicate columns available for views and filtering in one of their large document libraries. I knew they used InfoPath, so I had assumed that they had run into the problem I blogged about here: Automatic Creation of InfoPath forms - not as easy as I thought regarding InfoPath re-creating duplicate site columns when in certain cases of re-publishing forms.
This client had not done anything like this with InfoPath, instead they had created approval workflows (out of the box) at the web/site level and applied them Content Types, so far so good. Each of the multiple Content Type had their own approval workflows, and the columns appearing multiple times all happened to be the name of the column created as the WorkflowStatus type used by SharePoint to maintain the state/status of the workflow. I'm not exactly sure what happened, but I'm assuming they created, deleted, re-created, etc. these workflows using the same name a bunch of times, possibly at different levels within the sites, since some of the Content Types lived at the Site Collection level. This caused this column to keep showing up (same Display Name, unique Internal Name) multiple times.
Although normally not a big deal, this was a real bugger to get rid of. The UI won't let you drop the field because it is read only on the list, and it's also attached to the Content Type.
Here is how I solved it:
1. Gather up all the data to make sure you know which field is current and legitimate by looking at the data contained within it. Keep at note of the internal name by sorting on it in a list view and looking for the SortField querystring parameter.
2. Delete it from the Content Type first by going to list settings and clicking on a your Content Type link. Then click on any of the columns in this list to get to the "Change List Content Type Column" screen. We need to replace some variables in the querystring to locate our hidden field/column.
First, replace the Field parameter with the *Internal Name* of your field. You have that from #1 above.
Second, you need to replace the Fid (FieldID) parameter with the correct GUID of the field you want to delete from the Content Type. The easiest way for me to do this is to use SharePoint Manager 2007, an invaluable tool that is free from CodePlex. Here is a screenshot where I can see and verify the Internal Name and ID. You can see the duplicate field names under the "Customer Specification" Content Type in the left tree view.
Once you have replaced both of these values MAKE SURE YOU FORCE A BROWSER RELOAD. The best way to do this is copy the new url and load it in a new browser window. You should see your column details in the page. If you just swap variables and hit "Delete" the data in the page may still be pointing at the legitimate column you clicked on to get here.
3. Delete the Field from the actual list.
I was not able to find a way to delete the field from the list through the UI no matter how much trickery or querystring replacement I tried. Fields need to have their Hidden and ReadOnlyField status set false before they can be deleted, and SharePoint Manager 2007 wouldn't let me do this for some reason. I had to resort to a console application. Quick and dirty code pasted below.
SPList isoDocs = web.Lists["Documents"];
SPField field = isoDocs.Fields[new Guid("3e68ae11-e4a7-4bfe-aca9-d1cac96c14d1")];
Console.WriteLine(field.InternalName);
LogMessageToFile(field.InternalName);
field.Hidden = false;
field.ReadOnlyField = false;
field.Update();
isoDocs.Fields.Delete(field.InternalName);
After tediously looking at each column to figure out what was the correct one and determine which ones to delete through the above process, I was able to clean up the environment.
This brings up an important issue I try to stress with all clients: Governance. In most modern organizations there is enough spare hardware to set up a development/test environment for SharePoint and to restore a copy of your production content DB to test changes against a safe, but duplicate environment. Having these options in place will definitely save you time and money over the long run. I almost never make changes to a production environment, even simple ones, without first testing it against a copy of that environment and evaluating the effects. Some planning up front about having the infrastructure in place and a set of change rules to follow could avert disasters.
****UPDATE****
I wanted to let everyone know that the column duplication and inability to delete them issue was easy to reproduce, and in my opinion should be a bug in SharePoint. If you create an approval workflow and attach it to a content type, it creates a field in the content type and a field and column in the list where the content type resides. If you delete the workflow the field and column remains, unable to be deleted because of the read-only status. Be careful of this in the future.
I hope this helps,
-Ryan Thomas