Showing posts with label Content Types. Show all posts
Showing posts with label Content Types. Show all posts

Thursday, 7 March 2013

Submitting an InfoPath 2010 form in a document library saving the form as a file and the data as particular Content Type in Sharepoint 2010

The other day one of our clients requested a massive form, I think I count 500 controls. I have never been a huge fan of InfoPath, mainly because every time I use it, becomes a little bit tricky. The client always wants to go to the extra mille, so you end building a web part and leaving the InfoPath form away.

In this case, I knew that a 500 controls form will take me months to build, so I decided the only way, was InfoPath. The requirements were simple, keep the form, and keep the data, so the client could attach a Business Intelligence process behind the results.

The tricky part for me was to create the connection and the content type for it, but as soon as you know how to do it, it is a piece of cake. Right here we go… a step by step:

  1. Open InfoPath 2010.
  2. Select “SharePoint Form Library->Design Form”.
  3. Design your form.
  4. Publish your form to be sure it is ok.
  5. Go to “File->Publish->Sharepoint Server”.
  6. A Wizard like this will be opened:

    image
  7. Enter the site and the Document Library where the form is kept.
  8. Leave this form as it is and click next.

    image
  9. Now, select “Update the form template in an existing form library”, and select the library where you are keeping the forms.

    image
  10. Now! the funny thing… click on Add and select the fields you want, and click “Next”.image

  11. Click on Finish!

Job done!, now, everytime you submit a new form it will be saved in the “Document Library” as a file (with all the data inside) and it will save the data in the columns, so you can interrogate them from any source.

Friday, 6 January 2012

Adding a Custom Content Type to a document library with Powershell in Sharepoint 2010

Sometimes you will want to add your own Content Types (custom content types) to your list or document libraries (a list basically…). You can do it with the web interface, it is pretty easy, but what about if you need to perform this for 30,000 sites… you don’t want to spend the rest of the year clicking everywhere.

I have created a function , AddContentTypeToDocumentLibraryRemovingOtherContentType, which allows you to Add a Content Type (“DMSDocument”) and remove the default one (“Documents”). Be aware I will remove “Documents” from my list and add the content type from the site. Whart I am doing here is replacing the default “Document” content type with sophisticated Document content type I developed before called “DMSDocument”

You only need to pass:

  1. Name of the site URL
  2. Name of the Document Library
  3. Name of the Content Type to be added
  4. Name of the Content Type you want to remove from your Document Library.
 $_CurrentURL =  "http://sp_server"
 $_DocumentLibraryName = "Document Centre"
 $_ContentTypeToBeRemoved = "Document"
 $_ContentTypeToBeAdded = "DMSDocument"
 
 Function AddContentTypeToDocumentLibraryRemovingOtherContentType($_sCurrentURL,$_sDocumentLibraryName,$_sContentTypeToBeRemoved, $_sContentTypeToBeAdded)
 { 
 		## Getting the website...
  		$SPWeb = Get-SPWeb -Identity $_sCurrentURL		
		
		## Getting the Document Library (list) and enable Content Types
		$List = $SPWeb.Lists[$_sDocumentLibraryName]
		$List.ContentTypesEnabled = $true
		$List.update()
		
		## Getting the content types to be removed
		## NOTE: This particular one, "Document" lives in our list,
		##       so we remove it from there
		$DocumentCT = $List.ContentTypes[$_sContentTypeToBeRemoved]		
		## This Content type lives in the site, so we get it from there
    	         $CustomCT = $SPWeb.ContentTypes[$_sContentTypeToBeAdded]
    	         $List.ContentTypes.Delete($DocumentCT.Id)
		$List.ContentTypes.Add($CustomCT) 		
		$List.update()	
		
		## Disposing SPWEB object to avoid memory leaks.
		$SPWeb.Dispose()
}
AddContentTypeToDocumentLibraryRemovingOtherContentType $_CurrentURL $_DocumentLibraryName $_ContentTypeToBeRemoved $_ContentTypeToBeAdded

Conclusion: Powershell will bring you a high rate of productivity, but don’t forget to dispose the objects, otherwise you could cause memory leaks in your farm.

Tuesday, 20 December 2011

Listing all the Content Types and Fields with PowerShell in Sharepoint 2010

For many reasons at some point you will need to know how many content types you have and all the fields in a particular content type. I wrote a nice script few weeks ago you can run very easily.

Use PowerGui to run it or just copy/paste this code in a file, save it and run it with the native PowerShell.

	write-host ("...Listing Content Types")
	
	$url=  "http://sp_foundation_g/sites/Documents"
	$site = get-spsite $url 
	
	$web = $site.OpenWeb() 
	
	foreach ($contenttype in $web.ContentTypes)
	{	write-host("##################")
		write-host("Content Type Name:" + $contenttype.Name)
		write-host("Fields:")
		foreach ($field in $contenttype.Fields)
		{
			write-host($field.get_InternalName())
		}
	}
	

Enjoy!

Thursday, 13 October 2011

Building a Document Management System with SharePoint 2010 - Part 11–Creating Content Types from the Client Model

This post is more about how to improve the performance of your DMS to the extreme using the client model:
Microsoft.SharePoint.Client.Runtime.dll
Microsoft.SharePoint.Client.dll
Well, what I mean with best performance is to be able to not just create Content Types with the Client Model (I don’t cover this part here because I assume you already have the content types), it is the fact we can assign Content Types, something that is not allowed in the client model unless you use some tricks.

What I am going to do is to assign two different Content Types (Client Folder, Matter Folder) so we can have a client/matter structure in our DMS. Both Content Types are already created and inherits from the native folder Content Type. So we will have something like this:


+Client1----+Matter1
                   |
                   +Matter2
                   |
                   +Matter3

Before going ahead wit the chunk of code, I will explain you how it works.
1- You create your folder.
2- You get the id from your content type.
3- You apply the id into this field: “ContentTypeId”. I update the client number and client description.

ListItem item = items[0];
item["ContentTypeId"] = _ctClientFolder.Id;
item["client"] = _sClientNumber;
item["clientdescription"] = _sClientDescription;
item.Update();
clientContext.ExecuteQuery();



I am going to add the code below, to use it, be sure you add:
Microsoft.SharePoint.Client.Runtime.dll
Microsoft.SharePoint.Client.dll
Into your references and :

using Microsoft.SharePoint.Client;
To call the method just try this:
CreateClientMatter(@"http://mysharepointserver", "Documents", "00000272", "my client", "00000018", "my matter");
Just copy and paste this code into your project, if the client/matter is not there it will created and add the properties:
        private List ListCheck(ClientContext clientContext, Web _wListWeb, string _sListName)
        {
            List _lExistingList = null;
            try
            {
                //###############################
                //## We check if the file exists
                //###############################
                _wListWeb = clientContext.Web;
                ListCollection _lCollectionOfLists = _wListWeb.Lists;
                IEnumerable<List> existingLists = clientContext.LoadQuery(
                        _lCollectionOfLists.Where(
                        list => list.Title == _sListName)
                        );
                clientContext.ExecuteQuery(); 
                _lExistingList = existingLists.FirstOrDefault();
                //############################### 
            }
            catch (Exception ex)
            {
                throw new ArgumentNullException();
            }
            return _lExistingList;
        }
        private void CreateClientFolder(string _sServerURL, ClientContext clientContext, Web _wListWeb, List _lList, string _sListName, string _sClientNumber, string _sClientDescription)
        {
            //## Variables.
            Folder _fExistingFolder = null;
            ContentType _ctClientFolder = null; 
            //## We get all the folders
            FolderCollection _afolders = _lList.RootFolder.Folders; 
            //## Building the URL (folder)
            String _sClientfolderUrl = String.Format("/{0}/{1}", _sListName, _sClientNumber);
            //## We check if the URL exists
            IEnumerable<Folder> _iClientExistingFolders = clientContext.LoadQuery<Folder>(
                _afolders.Where(
                folder => folder.ServerRelativeUrl == _sClientfolderUrl)
                );
            clientContext.ExecuteQuery();
            //## Getting the result
            _fExistingFolder = _iClientExistingFolders.FirstOrDefault();
            if (_fExistingFolder == null)                       
            {
                //## Adding the folder
                _wListWeb.Folders.Add(_sServerURL + @"/" + _sListName + @"/" + _sClientNumber);
                clientContext.ExecuteQuery();
                //## Quering our folder
                CamlQuery query = new CamlQuery();
                query.ViewXml = @"       <View>
                                             <Query>
                                                <Where>
                                                   <Eq>
                                                      <FieldRef Name='FileLeafRef'/>
                                                      <Value Type='Text'>"+_sClientNumber+@"</Value>
                                                   </Eq>
                                                </Where>
                                             </Query>
                                             <RowLimit>1</RowLimit>
                                          </View>"; 
                ListItemCollection items = _lList.GetItems(query);
                clientContext.Load(items);
                //## Getting the content types
                ContentTypeCollection _ctListOfContentTypes = clientContext.Web.AvailableContentTypes;
                clientContext.Load(_ctListOfContentTypes);
                clientContext.ExecuteQuery();
                //## Getting the Content Type Id
                foreach (ContentType _ctItem in _ctListOfContentTypes)
                {
                    if (_ctItem.Name == "Client Folder")
                    {
                        _ctClientFolder = _ctItem;
                        break;
                    }
                }
                //## This is the tricky part, where we convert our folder
                //## Into a content type. We add some metadata as well               
                if (items.Count > 0)
                {
                    ListItem item = items[0];
                    item["ContentTypeId"] = _ctClientFolder.Id;
                    item["client"] = _sClientNumber;
                    item["clientdescription"] = _sClientDescription;
                    item.Update();
                    clientContext.ExecuteQuery();
                }
            }
        }
 
        private void CreateMatterFolder(string _sServerURL, ClientContext clientContext, Web _wListWeb, List _lList, string _sListName,string _sClientNumber, string _sMatterNumber,string _sMatterDescription)
        {
            Folder _fExistingFolder = null;
            ContentType _ctMatterFolder = null; 
            FolderCollection _afolders = _lList.RootFolder.Folders; 
            String _sMatterfolderUrl = String.Format("/{0}/{1}/{2}", _sListName, _sClientNumber, _sMatterNumber); 
            IEnumerable<Folder> _iMatterExistingFolders = clientContext.LoadQuery<Folder>(
                _afolders.Where(
                folder => folder.ServerRelativeUrl == _sMatterfolderUrl)
                );
            clientContext.ExecuteQuery();
            _fExistingFolder = _iMatterExistingFolders.FirstOrDefault(); 
            if (_fExistingFolder == null)
            {
                _wListWeb.Folders.Add(_sServerURL + @"/" + _sListName + @"/" + _sClientNumber + @"/" + _sMatterNumber);
                clientContext.ExecuteQuery();
                //## Quering our folder
                CamlQuery query = new CamlQuery();
                query.ViewXml = @"       <View Scope='RecursiveAll'>
                                             <Query>
                                                <Where>
                                                   <Eq>
                                                      <FieldRef Name='FileLeafRef'/>
                                                      <Value Type='Text'>" + _sMatterNumber + @"</Value>
                                                   </Eq>
                                                </Where>
                                             </Query>
                                             <RowLimit>1</RowLimit>
                                          </View>";
 
                ListItemCollection items = _lList.GetItems(query);
                clientContext.Load(items); 
                //## Getting the content types
                ContentTypeCollection _ctListOfContentTypes = clientContext.Web.AvailableContentTypes;
                clientContext.Load(_ctListOfContentTypes);
                clientContext.ExecuteQuery(); 
                //## Getting the Content Type Id
                foreach (ContentType _ctItem in _ctListOfContentTypes)
                {
                    if (_ctItem.Name == "Matter Folder")
                    {
                        _ctMatterFolder = _ctItem;
                        break;
                    }
                }
                //## This is the tricky part, where we convert our folder
                //## Into a content type. We add some metadata as well               
                if (items.Count > 0)
                {
                    //## This is just in case the client number
                    //## has the same name than the new matter
                    ListItem item = items.Count == 2 ? items[1] : items[0];
                    item["ContentTypeId"] = _ctMatterFolder.Id;
                    item["matter"] = _sMatterNumber;
                    item["matterdescription"] = _sMatterDescription;
                    item.Update();
                    clientContext.ExecuteQuery();
                }
            }
        }
 
        public bool CreateClientMatter(string _sServerURL, string _sListName, string _sClientNumber, string _sClientName, string _sMatterNumber, string _sMatterName)
        {
            bool _bResult = false;
            List _lList = null;           
            try
            {
                using (var clientContext = new ClientContext(_sServerURL))
                {
                    Web _wListWeb = clientContext.Web;
                    //###############################
                    //## We check if the list exists
                    //###############################                   
                    _lList = ListCheck(clientContext, _wListWeb, _sListName);
                    //###############################                  
                    if (_lList != null)
                    {                       
                        //#################################
                        //## CREATE FOLDER CONTENT TYPES
                        //## IF THEY DON'T EXIST
                        //##################################
                        CreateClientFolder(_sServerURL, clientContext, _wListWeb, _lList, _sListName, _sClientNumber, _sClientName);
                        CreateMatterFolder(_sServerURL, clientContext, _wListWeb, _lList, _sListName, _sClientNumber,_sMatterNumber,_sMatterName);                    
                        //##################################
                        _bResult = true;
                    }
                }
            }
            catch (Exception ex)
            {
                string _sError = ex.ToString();               
            }
            return _bResult;
        }


Conclusion: In order to create a decent DMS be always sure you keep your server clean of web services and workflows, anything it can be done in the client side, it will leave the server free to do what it has to do, SERVE!

Friday, 15 October 2010

Building a Document Management System with Sharepoint 2010 - Part 1

Sharepoint 2010 has become a very stable platform these days, because of this, many firms have decided to transform Sharepoint into a Document Management System (DMS). As we know, Sharepoint is so flexible we can achieve anything we want with it, but in this case we have to focus in usability and performance. We can not forget that at the end of the day, a DMS is a very sophisticated virtual hard drive full of virtual files.

I am going to publish a step by step guide of how to setup a complete DMS for a medium size company reaching high performance levels of interaction with documents.

Tools we will need (assuming you already have an architecture setup in place):
- Sharepoint 2010
- SQL Server 2008
- Windows Server 2008
- Office 2010 (Word, Execel, PowerPoint and Access)

Fisrt of all I think we need to understand what a  Document Management System means. This paragraph is a very good description of a DMS.

 A document management system (DMS) is a computer system (or set of computer programs) used to track and store electronic documents and/or images of paper documents. The term has some overlap with the concepts of content management systems. It is often viewed as a component of enterprise content management (ECM) systems and related to digital asset management, document imaging, workflow systems and records management systems.

A little bit of history. Beginning in the 1980s, a number of vendors began developing software systems to manage paper-based documents. These systems dealt with paper documents, which included not only printed and published documents, but also photographs, prints, etc.

Later developers began to write a second type of system which could manage electronic documents, i.e., all those documents, or files, created on computers, and often stored on users' local file-systems. The earliest electronic document management (EDM) systems managed either proprietary file types, or a limited number of file formats. Many of these systems later[when?] became known as document imaging systems, because they focused on the capture, storage, indexing and retrieval of image file formats. These systems enabled an organization to capture faxes and forms, to save copies of the documents as images, and to store the image files in the repository for security and quick retrieval (retrieval made possible because the system handled the extraction of the text from the document in the process of capture, and the text-indexer function provided text-retrieval capabilities).

EDM systems evolved to a point where systems could manage any type of file format that could be stored on the network. The applications grew to encompass electronic documents, collaboration tools, security, workflow, and auditing capabilities.

The first thing we have to focus is the availability of developing our own library with our own content types. Microsoft has a very good description about what a content type in Sharepoint means:

A content type is a reusable collection of metadata (columns), workflow, behavior, and other settings for a category of items or documents in a Microsoft SharePoint Foundation 2010 list or document library. Content types enable you to manage the settings for a category of information in a centralized, reusable way.

For example, imagine a business situation in which you have three different types of documents: expense reports, purchase orders, and invoices. All three types of documents have some characteristics in common; for one thing, they are all financial documents and contain data with values in currency. Yet each type of document has its own data requirements, its own document template, and its own workflow. One solution to this business problem is to create four content types. The first content type, Financial Document, could encapsulate data requirements common to all financial documents in the organization. The remaining three, Expense Report, Purchase Order, and Invoice, could inherit common elements from Financial Document and also define characteristics unique to each type, such as a particular set of metadata, a document template to be used in creating a new item, and a specific workflow for processing an item.

Each of the content types in this example could be used on any document library in the site hierarchy, and all of them could be used together on the same document library. When business requirements change, the content types can be modified to meet the new requirements and updates can be pushed down to any document library where the content type is used.

So from here we are going to create our own content type, it is based in our bills, so it will be called "Bill"

1- Go to your site, and on Site Actions menu click on "Site Settings"


2- Under "Galleries" you will find an option called "Site Content Types", click on that link.

3- Click on "Create" and a new page will pop up.

4- Under "New Site Content Type", on the name text box type Bill.

5- On "Document Content Types" select "parent content type" and select Document, click Ok.

6- Go to the library where you want to use the content type, "Share Documents" in this case and select the ribbon Library, on there select "Library Settings".

7- From here, click on the name of your content type "Bill", select "Advance Settings" , select Upload a new document template, and then click Browse  to browse to and select the document template you want to assign to the site content type. A document template can be any file such as an Excel spreadsheet, a Word document or template, a PowerPoint slide presentation, etc.

8- Navigate to the document library to which you want to add the content type.

9- On the Settings menu, click Document Library Settings.


10- On the Customize page under General Settings, click Advanced settings.



12- Back on the Customize page under Content Types, click Add from existing site content types.


13- On the Add Content Types page, select Custom Content Types from the Select site content types from drop-down list box, select the content type you created (here: Bill) from the Available Site Content Types drop-down list box, click Add to add the content type to the list of Content types to add, and then click OK.
 
 14- Go to your library, select the Ribbon Document and select "New Document" you should be able to see the new document, "Bill".


Conclusion
As you can see we can be quite flexible adding content types, but this is just the beginning , in the next part I will extend more options available.