Search This Blog

Wednesday, January 30, 2013

SPFieldLookupValue class

Remarks





Instances of this class represent a single field value for a lookup field. Lookup fields can have multiple values or just one. You can determine which is the case by checking the value of the lookup field's AllowMultipleValues property. If the property returns true, the field can have multiple values; if it returns false, it cannot.
If a lookup field does not allow multiple values, the field value is an object of type String that contains the ID of the item in the list that the lookup field points to plus the value of the field in the item that the lookup field points to. You can pass this string as an argument to the SPFieldLookupValue(String) constructor to create an SPFieldLookupValue object. Then you can get the list item ID from the LookupId property and the value of the field in the list item from the LookupValue property.
If a lookup field allows multiple values, then the field value is an object of type SPFieldLookupValueCollection that is boxed as type Object. The SPFieldLookupValueCollection object is a collection of SPFieldLookupValue objects. You can extract the field values by enumerating the collection and accessing each object's LookupValue property.


The following example demonstrates how to set the value of a lookup field.
The example code is a console application that gets references to two related lists, Customers and Orders. Each item in the Customers list represents a customer record, and the ID field in the item is used to identify a customer. Each item in the Orders list represents an order placed by a customer. The Orders list has a lookup field named Customer ID that points to the ID field in the Customers list, identifying the customer who placed the order.
Code in a foreach loop iterates through the list of customers, adding a new item to the Orders list for each customer on the Customers list. In each case, the code sets the value of the lookup field, Customer ID, to link the order to the customer.


using System;
using Microsoft.SharePoint;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            using (SPSite site = new SPSite("http://localhost"))
            {
                using (SPWeb web = site.RootWeb)
                {
                    SPList customerList = web.Lists.TryGetList("Contoso Customers");
                    SPList orderList = web.Lists.TryGetList("Contoso Orders");

                    if (customerList != null && orderList != null)
                    {
                        SPListItemCollection customers = customerList.Items;
                        SPListItemCollection orders = orderList.Items;

                        string fieldName = "CustIDLookup";
                        if (!orderList.Fields.ContainsField(fieldName))
                            return;
                        
                        SPField lookupFld = orderList.Fields.GetField(fieldName);

                        foreach (SPListItem customer in customers)
                        {
                            SPListItem order = orders.Add();
                            order[SPBuiltInFieldId.Title] = "Thank you!";
                            order.Update();

                            SPFieldLookupValue value = new SPFieldLookupValue(customer.ID, customer.ID.ToString());
                            order[lookupFld.Id] = value.ToString();
                            order.Update();
                        }
                    }
                }
            }
        }
    }
}


Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.



Setting the value of LookUp Fields in C#


LookUp Fields are a common sight in SharePoint environments, but working with them is not as straightforward as one might expect. Setting a LookUp Field Value (object type SPFieldLookupValue) on a list item offers several options:

 

1. Setting the value to a SPFieldLookupValue

This one is obvious. The SPFieldLookup value property is – as with all field values – of type object in the SharePoint object model, but is internally used as a SPFieldLookupValue.

2. Setting the value to a formatted String

LookUp Field Values have a string representation of “(ID);#(VALUE)”, i.e. “2;#Second Entry”. Setting the value to a String in the before mentioned format works as well as it is converted to a SPFieldLookupValue.

3. Setting the value to an ID only (which is an Integer)

To my surprise, the value can be set to the ID only without raising any errors.

4. Not working: Setting the value to the String value only

Unfortunately, just setting the value to the desired value and skipping the ID part does not work and will throw an “Index Out Of Range” Exception. But the GUID of the LookUp List is conveniently stored in the SPFieldLookup object. In some situations it is useful to set the value using Strings and I wonder why that is not a build-in option. The following code achieves this goal:

 
public static SPFieldLookupValue getLookUpValue(string lookupValue, SPList myList, String fieldname)
        {
            SPFieldLookup lookUpField = (SPFieldLookup)myList.Fields[fieldname];
            SPList lookupSourceList = myList.ParentWeb.Lists[lookUpField.LookupList];

            SPQuery query = new Microsoft.SharePoint.SPQuery();
            query.Query = String.Format("{0}", lookupValue);
            SPListItemCollection listItems = lookupSourceList.GetItems(query);

            return new SPFieldLookupValue(listItems[0].ID.ToString());
        }

        // use like this:
        item["myLookUpField"] = getLookUpValue("the new value", item.ParentList, "myLookUpField");

 

 

Properly Populating and Retrieving SharePoint Field Data 

 

http://sharepointcodeblock.blogspot.in/2008/07/properly-populating-and-retrieving.html

 

 SharePoint uses a lot of field types that have different underlying schemas, delimiters and formats. I see a lot of people reverse engineer the field information and "hack" the data into the list using a string such as "1;#Title" for a lookup field. Well this isn't exactly best practice so I've put together a reference table below to assist in using the correct data types for populating or retrieving information from a SharePoint list.

Lookup Field

Field Class: SPFieldLookup Field Value Class: SPFieldLookupValue Populating Information: item["FieldName"] = new SPFieldLookupValue("Title"); // SharePoint will do the lookup as long as the LookupValue's are uniqueitem.Update();oritem["FieldName"] = new SPFieldLookupValue(1, "Title");item.Update(); Retrieving Information: SPFieldLookupValue itemValue = item["FieldName"] as SPFieldLookupValue;int id = itemValue.LookupId;string value = itemValue.LookupValue;

Multiple Lookup Field

Field Class: SPFieldLookup Field Value Class: SPFieldLookupValueCollection Populating Information: SPFieldLookupValueCollection itemValues = SPFieldLookupValueCollection();itemValues.Add(new SPFieldLookupValue(1, "Title"));item["FieldName"] = itemValues;item.Update(); Retrieving Information: SPFieldLookupValueCollection itemValues = item["FieldName"] as SPFieldLookupValueCollection;foreach (SPFieldLookupValue itemValue in itemValues){int id = itemValue.LookupId;string value = itemValue.LookupValue;}

User Field

Field Class: SPFieldUser Field Value Class: SPFieldUserValue Populating Information: web.EnsureUser(@"domain\username");SPUser user = web.AllUsers[@"domain\username"];item["FieldName"] = user;item.Update(); Retrieving Information: string currentValue = item["FieldName"].ToString();SPFieldUser userField = list.Fields.GetFieldByInternalName("FieldName");SPFieldUserValue itemValue = (SPFieldUserValue)userField.GetFieldValue(currentValue);SPUser user = itemValue.User;

URL Field

Field Class: SPFieldUrl Field Value Class: SPFieldUrlValue Populating Information: SPFieldUrlValue urlValue = new SPFieldUrlValue();urlValue.Url = "http://www.google.com";urlValue.Description = "Google";item["FieldName"] = urlValue;item.Update(); Retrieving Information: SPFieldUrlValue urlValue = new SPFieldUrlValue(item["FieldName"].ToString());string url = urlValue.Url;string description = urlValue.Description;

Multiple Choice Field

Field Class: SPFieldMultiChoice Field Value Class: SPFieldMultiChoiceValue Populating Information: SPFieldMultiChoiceValue itemValue = new SPFieldMultiChoiceValue();itemValue.Add("Choice 1");itemValue.Add("Choice 2");itemValue.Add("Choice 3");item["FieldName"] = itemValue;item.Update(); Retrieving Information: SPFieldMultiChoiceValue itemValue = new SPFieldMultiChoiceValue(item["FieldName"].ToString());foreach (string choice in itemValue){// value is in choice}

 

For "multiple lookup Fields", the below code is used:
SPFieldLookupValueCollection itemValues = SPFieldLookupValueCollection(); 
itemValues.Add(new SPFieldLookupValue(1, "Title")); 
item["FieldName"] = itemValues; 
item.Update(); 

 

 

 

using (SPSite site = new SPSite("http://servername"))
{
using(SPWeb web = site.OpenWeb())
{
SPList list = web.Lists["My Skills"]; //List which has lookupfield TechSkills
SPListItemCollection itemCollection;
itemCollection = list.Items;
foreach (SPListItem item in itemCollection)
{
SPFieldLookupValue lookupField = new SPFieldLookupValue(item["TechSkills"].ToString());
string lookUpValue = lookupField.LookupValue;
Console.WriteLine("List item actual value:" + item["TechSkills"].ToString());
Console.WriteLine("List item lookfield value:" + lookUpValue);
}
SPListItem listItem = itemCollection[0];
listItem["Skill Name"] = new SPFieldLookupValue(1, "ASP.Net"); //ID field of ASP.Net is 1
listItem.Update();
}
}

Tuesday, January 29, 2013

Sharepoint set user or group to SPListItem

http://blog.bugrapostaci.com/tag/spfielduservalue/


We are going to use a sharepoint web control to get user or groups  named “PeopleEditor” .For using these please fallow the instructions below.
Add fallowing code to top of your page:
<%@ Register Tagprefix="SharePointWebControls" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
Add fallowing control to your page front for get users or groups:
Note: If  you want to set or retrieve the account types that are associated with the control use attribute “SelectionSet”
and enums are:

  • User = single user
  • DL = AD distribution list
  • SecGroup = AD security group
  • SPGroup = Sharepoint group
<SharePointWebControls:PeopleEditor runat=”server” ID=”txtScope” MultiSelect=”false” MaximumEntities=”1″ ValidatorEnabled=”true” SelectionSet=”User” Width=”300px”></SharePointWebControls:PeopleEditor>



using Microsoft.SharePoint.WebControls;
public SPFieldUserValueCollection GetSelectedUsers(PeopleEditor editor)
{
       string selectedUsers = editor.CommaSeparatedAccounts;
       // commaseparatedaccounts returns entries that are comma separated. we want to split those up
       char[] splitter = { ',' };
       string[] splitPPData = selectedUsers.Split(splitter);
       // this collection will store the user values from the people editor which we'll eventually use
       // to populate the field in the list
       SPFieldUserValueCollection values = new SPFieldUserValueCollection();
       // for each item in our array, create a new sp user object given the loginname and add to our collection
       for (int i = 0; i < splitPPData.Length; i++)
            {
                string loginName = splitPPData[i];
                if (!string.IsNullOrEmpty(loginName))
                {
                    SPUser user = SPContext.Current.Web.SiteUsers[loginName];
                    SPFieldUserValue fuv = new SPFieldUserValue(SPContext.Current.Web, user.ID, user.LoginName);
                    values.Add(fuv);
                }
            }
            return values;
        }
}
 
 
SPList list = SPContext.Current.Web.Lists[APPLIB];
SPListItem item = list.Items.Add();
item["ProgramAdmin"] = GetSelectedUsers(txtScope);
item.Update();

Friday, January 25, 2013

What is the difference between sequential and state machine workflows


What could a state machine (workflow) be? Here’s the definition from Wikipedia:

State machine is a model of behavior composed of a finite number of states, transitions between those states, and actions. (from http://wikipedia/wiki/State_machine).
  
Let's explain that definition in a practical, easier to understand and to remember way.  When you wake up in the morning you are hungry (or you just want some coffee very badly). We could call this state a "Hungry" state. Then, after you had something to eat you transition from the "Hungry" state to another state called "Full". And that's the whole 'science' of state machines. If you think about it, every one of us is always in either one of those states :). You could also add some more states like "Half-full", "A little hungry", etc.

So, what can you use state machine workflows for? You can use them for basically every business process that consists of states. Take for example a simple Word document and its lifecycle. You upload the document to SharePoint document library and the 'state' of the document at that point could be "Submitted". After document is submitted you can assign it to a user to approve or reject it and you get two more states: "Approved"/"Rejected”.

Norm Estabrook mentions an even better example of state machine workflows in his podcast about VSTO SharePoint workflow. Here is except from the recording:

"On the other hand, the steps in your solution may be random in nature and never really have a clear ending.  For example, the participants in an HR workflow might move an employment resume from state to state. The resume might be in a state of being considered, interviewing, or archiving for future.  The resume might be re-activated or updated at any time. Because there is no linear path of steps for the resume, it would be excessively hard to produce conditional rules to capture all possible paths.  In these situations, you would want to manage your workflow as a series of states and transitions.  Use the state machine workflow template to get started there."

When should you use state machine workflows? This is kind of a hard question to answer. You could use state machine workflow when for example a document requires multiple reviewers (legal, marketing, etc.) that may sign off on the document in any order. More complex state machines may open up different workflow paths depending on intermediate state.

How about sequential workflow? Sequential workflows are definitely much easier to design and maintain than state machine workflows. The only difference between a state machine workflow and sequential workflow is that in sequential workflow the flow goes from first activity to the next until end of the workflow is reached. In between you can branch the workflow, for example use IfElse or While activity, etc.

What type of workflows are you using more frequently - state or sequential? Are there any rules on when to use specific type of workflows?

List All SharePoint 2010 PowerShell Commands

List All SharePoint 2010 PowerShell Commands

Get-Command –PSSnapin “Microsoft.SharePoint.PowerShell” | format-table name > C:\SP2010_PowerShell_Commands.txt

 
If you would like a little more detail, then try this one:

Get-Command –PSSnapin “Microsoft.SharePoint.PowerShell” | select name, definition | format-list > C:\SP2010_PowerShell_Commands.txt

List All SharePoint 2010 PowerShell Commands

Note: You may also type gcm as the alias for Get-Command