Organizing A SharePoint Document Library

Let's say that you have a document library in SharePoint where you programmatically upload log files or daily reports.  After a few weeks the document library might contain multiple pages of documents, making finding the document that you are looking for annoying.  You have to sort by date or title and then page though the results to find what you are looking for.  Wouldn't it be nice if you could automatically organize the document library into folders representing the year/month/day that the document was uploaded.  Here is a way to do just that.

In this example, I am using a workflow to organize the documents that are uploaded to the SharePoint document library.  This workflow is activated when a new item is added to the library.  You could also use an event receiver (ItemAdded or ItemAdding), but the basic code would be the same.

Here is a graphical view of the workflow.  It is a simple sequential workflow with a single code activity.


Below is the code that is contained in the OrganizeDocuments ExecuteCode event that performs the organization of the library.

    1: private void OrganizeDocuments_ExecuteCode(object sender, EventArgs e)
    2: {
    3:     SPListItem currentItem = workflowProperties.Item;
    4:     if (currentItem == null) return;
    6:     // Get the datetime from the item
    7:     DateTime addedDateTime = currentItem.File.TimeCreated;
    9:     // Get the folder path (year)/(month)/(day) for the item.
   10:     string folderYearValue = addedDateTime.Year.ToString();
   11:     string folderMonthValue = String.Format(addedDateTime.ToString("MM-MMMM"));
   12:     string folderDayValue = addedDateTime.Day.ToString();
   14:     // Get or create the folders
   15:     SPFolder yearFolder = GetSubfolder(folderYearValue, workflowProperties.List.RootFolder);
   16:     SPFolder monthFolder = GetSubfolder(folderMonthValue, yearFolder);
   17:     SPFolder dayFolder = GetSubfolder(folderDayValue, monthFolder);
   19:     // Get the filename
   20:     string fileName = currentItem.File.Name;
   22:     // Move the list item to the new folder
   23:     string newPath = String.Format("{0}/{1}/{2}", workflowProperties.SiteUrl, dayFolder, fileName);
   24:     currentItem.File.MoveTo(newPath, SPMoveOperations.Overwrite);
   25: }

And here is the GetSubfolder helper method that either gets a reference to an existing folder or creates a new folder if it does not already exist:

    1: private SPFolder GetSubfolder(string folderName, SPFolder parentFolder)
    2: {
    3:     SPFolder returnFolder = null;
    5:     // Try to find the folder
    6:     foreach (SPFolder folder in parentFolder.SubFolders)
    7:     {
    8:         if (folder.Name == folderName)
    9:         {
   10:             returnFolder = folder;
   11:             return returnFolder;
   12:         }
   13:     }
   15:     // If the folder could not be found, create the folder
   16:     if (returnFolder == null)
   17:     {
   18:         // Add the folder
   19:         returnFolder = parentFolder.SubFolders.Add(folderName);
   20:         parentFolder.ParentFolder.Update();
   21:     }
   23:     return returnFolder;
   24: }


This will move the uploaded document to a folder in the form of year/month/day that corresponds to the date that the document was uploaded.