Next task on my prep – create a list programmatically. Then I want to add some columns to it, and show these on the default view. Actually, it’s mostly pretty easy (apart from that last part).
Well, creating a list is pretty easy.
SPSite siteCol = new SPSite(@"http://vm-moss2007/test/");
SPWeb site = siteCol.OpenWeb();
site.Lists.Add("New Calendar", "This calendar was created programmatically", site.ListTemplates["Calendar"]);
Here you can see me getting an SPWeb object, and then adding to its SPListCollection. You have to supply a template for the list, and this depends on the templates available on the site – hence getting the template from the SPListTemplateCollection.
I wanted a custom list, and I wanted it to appear on the left navigation:
site.Lists.Add("My Custom List", "This list was created programmatically", site.ListTemplates["Custom List"]);
SPList newList = site.Lists["My Custom List"];
newList.OnQuickLaunch = true;
newList.Update();
Great! And now I want to add some columns. First I added a text column:
newList.Fields.Add("NewText", SPFieldType.Text, true);
And then a lookup column (as I figured this would be a hard one):
SPList targetList = site.Lists["My Lookup Target"];
SPField targetField = targetList.Fields["My Target Lookup Column"];
newList.Fields.AddLookup("NewLookup", targetList.ID, false);
SPFieldLookup lkp = (SPFieldLookup)newList.Fields["NewLookup"];
lkp.LookupField = targetField.InternalName;
lkp.Update();
First I get the target list and the target field for the lookup. I add a new lookup column, but for some strange reason none of the SPFieldLookup class’s constructors allow me to create one supplying a target list and column. Also, none of the SPFieldCollection’s methods allow me to add a lookup supplying a target column.
Thus, I end up getting the column I’ve just created and assigning the column that I want use as the value of the lookup. Crazy. I’m sure that there must be a better way of doing this (i.e. in one call) but I don’t see how.
Anyway, it works; my columns are added. Now I want to show them in the default view:
//*** Doesn't work for some obscure reason ***
newList.DefaultView.ViewFields.Add("NewText");
newList.DefaultView.ViewFields.Add("NewLookup");
newList.DefaultView.Update();
As the code subtly hints, this code didn’t work – my columns weren’t shown in the default view. However, the code below does work:
SPView view = newList.DefaultView;
view.ViewFields.Add("NewText");
view.ViewFields.Add("NewLookup");
view.Update();
The observant amongst you might notice that these pieces of code should be functionally equivalent. Well, they’re not! Daniel Pavelescu has investigated this – but it’s all a bit weird. Anyway, it works!
So there we have it – creating a list, adding new columns to it, and altering a view, all through the SharePoint API.
EDIT – Keith Dahlby has also investigated, and looked at why this is happening. Although he let’s the code talk for itself, the essence of it all is that each call to .DefaultView actually creates a new SPView object!
And he’s right, reflector is very useful.
Hi,
nice article. I should have found it a little bit earlier, that would have saved me alot of time *g*
Alex
Thanks! I should’ve made it more of a blog post by itself – it was one of the more interesting bits of that exercise. In fact, I might pit it into it’s own post.
Quite a nifty technique though!
Regarding the usage of DefaultView, and why adding the fields doesn’t work, check out:
http://solutionizing.net/2009/02/21/why-you-need-reflector-splist-defaultview/
Dude! Thanks for he lookup /with/ field specification.
I am surprised that
newList.Fields.AddLookup(“NewLookup”, targetList.ID, targetField.ID, false);
is not a valid call …
Hi,
do you know if it is possible to add fields to a list using Web Services? I need this to add questions to a survey list.
Never done that, but a bit of Googling shows that Lists.asmx web service has an UpdateList method:
http://msdn.microsoft.com/en-us/library/lists.lists.updatelist.aspx
It’s got an example of adding fields to list. I’m not sure if that will work for a survey though – they’ve also got routing logic and stuff to worry about.
If you manage it, let me know – it’d be an interesting one to see.
Hii,
use
SPField targetField = targetList.Fields[SPBuiltInFieldId.Title];
rather
SPField targetField = targetList.Fields[“Title”];
because it gives error to create this column..
Hi,
I used your code below and it worked but there is one problem, it gives me #VALUE!
I have an ‘Employees’ List that has an ‘Employee’ column that is a user/group column.
I want to create a list(projectList) that has a look up column name ‘Manager’ to look up ‘Employee’ column.
I am able to see the look up data but once I create the item, it shows #VALUE!
Here is my code:
// manager look up column to manager (will use employee for now)
SPList lookupList = currentSite.Lists[“Employees”];
SPField lookupField = lookupList.Fields[“Employee”];
projectList.Fields.AddLookup(“Manager”, lookupList.ID, true);
SPFieldLookup lookup = (SPFieldLookup)projectList.Fields[“Manager”];
lookup.LookupField = lookupField.InternalName;
lookup.Update();
I posted a topic on the forum but noone seems to have this problem.
http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/e50b2be9-afce-4d9d-a1e0-4902c6e54d77
can you please help?
Can anyone of you guys enlighten me on how to create calculated field programatically? PLEASE…
as of now what i m doing is
newList.Fields.Add(“Amount At Risk”, SPFieldType.Calculated, false);
SPField newFieldAR = newList.Fields[“Amount At Risk”];
newFieldAR.DefaultFormula = “=[Budget Amount]-[Claimed Amount]”;
newFieldAR.Update();
But somehow though the field is created, the formula remains blank.
Any ideas GURUS? PLS
Hi
nice article can someone help how to create a new list using wsp solution deployment as feature in Sharepoint using VSeWSS 1.2 and how to migrate list data Sharepoint to Sharepoint means from one server to other
thanks
It was very informative.I would also like to add on to this.You can think of a SharePoint List somewhat similar to a table present within a Database. As tables consist of different columns, a SharePoint List also comprises of different columns / fields and these fields can indeed have different attributes associated to it (like “Required field check”, “Max Length”, “Display Formats”, etc).
We can use SharePoint API to create these fields and associate the corresponding attributes programmatically within an existing List.
thanks..these all are working codes !!
Hi,
I know thats a lot of time since your post, but it is still helpful. Currently I’m forced to work with wss 3.0 and I have some questions about Lookup fields and I thought that perhaps you know the answer.
I have a list and in this list there are some lookup fields (3 of them). Is there any possibility to get them without knowing their names? Maybe lookup field have some propertis that clearly said me “yes this is lookup field”?
You know in shor, I would like to iterate through all fields in my list and get only lookup fields to work with them in code without knowing their names.
How about something like:
foreach(SPField f in list.Fields)
{
SPLookupField lkp = f as SPLookupField;
if( lkp != null ) {
//You've found a lookup field, without know its name.
}
}
Yes! I can do it like yuo write above.
However after I write my post and after a couple of nights with WSS 3.0 😦 I found something like that:
foreach(SPField f in list.Fields)
{
if(f.Type == SPFieldType.Lookup)
{
// and I have all lookups for list, now I can even check on which list and field
// he look at
}
}
I don’t know how it’s possible that earlier I didn’t find ‘field.type’ thing
Although you answer is helpful in other situation.
Thx a lot 🙂