How to find item count in a SPFolder? - sharepoint

I have a List that stores items in a folder hierarchy.
I notice that SPFolder.Files.Count is always zero.
Is there a way to find out how many list items are there in a folder?

I presume you are looking for direct children and not descendants (like items within a sub-folder).
Do you also want to include sub-folders in the count? In which case you can use: SPFolder.ItemCount.
If you just want only the direct child listItems which are not subfolders then you can do something like the following:
using (SPSite site = new SPSite(mySPSite))
{
SPWeb web = site.OpenWeb();
SPList list = web.Lists[myList];
SPFolder folderInstance = list.RootFolder.SubFolders[folderUrl];
SPQuery query = new SPQuery() ;
query.Folder = folderInstance;
SPListItemCollection items = list.GetItems(query) ;
Console.WriteLine(items.Count);
}
I haven't tried it. You might have to add a where clause to eliminate folders, if the query is returning that.
If you want to include all list-items, even within subfolders, set the SPQuery.ViewAttributes field as query.ViewAttributes = "Scope=\"Recursive\"";

Did you try to get the SPListItem from the SPFolder and check the values from the SPBuiltInFieldId.ItemChildCount and SPBuiltInFieldId.FolderChildCount fields?
Something like this:
SPFolder folder = ...;
int? noOfItems = folder.Item[SPBuiltInFieldId.ItemChildCount] as int?;
int? noOfFolders = folder.Item[SPBuiltInFieldId.FolderChildCount] as int?;
See
SPBuiltInFieldId.ItemChildCount Field
SPBuiltInFieldId.FolderChildCount Field
for more info.

From Microsoft
Using the SPList.ItemCount property is
the recommended way to retrieve the
number of items in a list. As a side
effect of tuning this property for
performance, however, the property can
occasionally return unexpected
results. For example, if you require
the exact number of items, you should
use ...
I wonder if the same applies to SPFolder.ItemCount ?

Related

Sharepoint 2013 Community site: Get values from discussion board

I have to get values programmatically from the discussions list. When I tried this code it is giving the values of replies.
SPList oSpListPost = oSPWeb.Lists["Discussions List"];
SPListItemCollection oSpListItemClnPost = oSpListPost.Items;
foreach (SPListItem post in oSpListItemClnPost)
{
SPField field = post.Fields.GetField("Body");
}
The "parent" discussion is a folder with attached metadata, not a list item. You will probably want to get the associated folders in the list instead of the individual list items.

SharePoint's List.GetItems(view) returns ALL items instead of filtered view items

I'm trying to get a count of items in a list, based on a view. Every method I've tried so far only returns the grand total of the list. I've tried just about every method I've run across while searching, and everything ends up with the same results.
Here's one of the methods I've tried:
SPWeb web = SPContext.Current.Web;
SPView view = web.GetViewFromUrl("url to my view");
int count = view.ParentList.GetItems(view).Count;
My list has 28 items, but the view I'm referencing filters it and shows four items. I expect my count to be 4, not 28 - but 28 is what I always get.
Here's another method I've tried:
SPSite site = SPContext.Current.Site;
SPWeb web = site.OpenWeb();
SPQuery MyQuery = new SPQuery();
MyQuery.Query = "<Query><Where><Eq><FieldRef Name='strStatus' /><Value Type='Text'>submitted</Value></Eq></Where></Query>";
IEnumerable<SPListItem> results = web.Lists["Requests"].GetItems(MyQuery).Cast<SPListItem>();
// results.Count() is 28... should be 4
So in this method I'm skipping the view and just trying to pass in a CAML query. When testing my query in U2U, four results are returned as expected...
The larger picture is that I'm doing this inside of my custom menu control's OnMenuItemDataBound event handler. I don't know if that makes a difference at all, but the idea I'm heading towards is that each item that links to a view in a specific list, will show the count of items in that view next to the link.
Any ideas why I'm getting a list total instead of the filtered totals? Thanks!
If I remind correctly, you need to remove the <Query> from your SPQuery. The CAML Builders use it but its unnecessary in the actual SPQuery. Of course you need to make sure the fields exist.
MyQuery.Query = "<Where><Eq><FieldRef Name='strStatus' /><Value Type='Text'>submitted</Value></Eq></Where>";

SPList Item get value - ArgumentException

I have an SPListItem and I have an array of column names.
When I try to access the SPListItem values using the code below:
for(int i=0;i<arrColName.length;i++)
{
string tempValue = item[arrColName[i]].ToString();
// Works fine in case the the specific column in the list item is not null
// Argument exception - Values does not fall witing expected range
// exception in case the value //is null
}
I think that you used an SPQuery to get the list items and forgot to add the field into the viewfields property of SPQuery.
query.ViewFields = string.Format("<FieldRef Name=\"{0}\" Nullable=\"True\" />", mFieldName);
Usually when you test your program with the farm account the code will work, with normal users you get an ArgumentException.
Another problem/feature which causes ArgumentException is the new ListView Threshold. If th elist you try to access has too many items, this Exception is raised. A way to handle this is to increase the threshold with powershell for the list.
Not only check if item != null but also item["FieldName"] != null. Because if you will try to call .ToString() on null, you will get exception.
And if that field with internal name "FieldName" name does not exist, you will also get an exception. So you would probably try
SPFieldCollection fields = list.Fields;
foreach (SPListItem item in list.Items) {
if (fields.Contains("FieldName") && item["FieldName"] != null) {
string fieldValue = item["FieldName"].ToString();
}
}
I had a similar situation with custom cascade field (or column). I did it following way and it seemed to work for the custom field types.
item.Properties["Country"] = "Mexico"; // custom field
item.Properties["nCity"] = "Cancun"; // custom field
item["Document Descriptions"] = "Test document description.";
Note: I added item.Properties for the custom columns. No need to add properties for built in field type (else they don't work).
Does your array contain the internal names or the display names of the columns? If it's the latter you might try item[item.Fields[arrColName[i]].InternalName].ToStrinng(); instead.
Sharepoint Lists aren't stored as a array with a static size.
You have to use the built in sharepoint iterator to go through each element
For example:
SPList checklist = //Some initiliaztion
foreach (SPListItem item in checklist.Items){
//work
}
This will do work on each item in your SPlist
Edit:
Wrong advice, I didn't see the code until after the edit.
Maybe try a cast?
(String)item[colname]

Accessing SPLIstItem properties in SharePoint

I'm trying something very simple - accessing my SharePoint list's items and their properties.
However, SPListItem.Properties count is zero for all normal lists. Everything works as expected for document and pages libraries. So, if the list items are based on document type, all is good. If they are based on item, properties are not returned.
I've tried in two environments, with new sites created from OOTB publishing templates, with new lists which are based on OOTB content types etc. Always the same thing.
Right amount of SPListItems is always returned. Title and Name are fine. It's just that the .Properties hashtable is totally empty.
In desperation, I wrote a web part that outputs the following (ugly!) diagnostics.
foreach (SPList list in SPContext.Current.Web.Lists)
{
foreach (SPListItem item in list.Items)
{
Label label = new Label();
label.Text = "Name: " + item.Name + "Property count: " + item.Properties.Count;
this.Controls.Add(label);
}
}
The only observation is that it works exactly as I described earlier. I just share the code to show that this is the most basic operation imaginable.
Here is sample output - I've added the line breaks for readability ;-)
Name: Test Property count: 0
Name: default.aspx Property count: 21
Obviously item "Test" is an item based list item and default.aspx is a page.
Has anyone ever encountered anything like this? Any ideas?
item["FieldName"] is the canonical way to get a value of a metadata column in a SharePoint list. If you need to get the list of available fields for a SharePoint list, check the parent SPList object's Fields property which is a collection of the fields in this list. Each of those field objects will have a property called InternalName and that is what you should use to access its value when you are working with an instance of SPListItem.
Are you trying to get the field Values? Sadly, they are not strongly typed:
string ModifiedBy = (string)item["Author"];
To get the proper names of the fields (they have to be the internal names), go to the List and then List Settings. You will find the List of Columns there. Click on any Column Name to go to the Edit Page, and then look at the URL in the Address Bar of your Browser. At the very end, there should be a parameter "Field=Editor" or similar - that's your internal field name.
If you wonder why a field like "Test Field" looks strange, that is because Sharepoint encodes certain characters. A Space would be encoded to x0020 hence the Internal Name for "Test Field" is "Test_x0020_Field".
In order to get the proper field type to cast to:
string FieldType = item["Author"].GetType().FullName;
(The Intermediate Window in Visual Studio is tremendously helpful for this!)
I have found the following extension to the SPListItem class to be very helpful.
internal static class SharePointExtensions
{
internal static Dictionary<string, object> PropertiesToDictionary(this SPListItem item)
{
// NOTE: This code might be temping - but don't do it! ...itdoes not work as there are often multiple field definitions with the same Title!
// return item.Fields.Cast<SPField>().ToDictionary(fld => fld.Title, fld => item[fld.Title]);
Dictionary<string, object> dict = new Dictionary<string, object>();
var fieldNames = item.Fields.Cast<SPField>().Select(fld => fld.Title).Distinct().OrderBy(sz => sz).ToArray();
foreach (fieldName in fieldNames)
dict.Add(sz, item[fieldName]);
return dict;
}
}
with it you can simply do:
item.PropertiesToDictionary()
...and you will have a nice Linq dictionary object that will work just the way you'd expect. Is it a little heavy-weight / low-performance? Sure. Are most people willing to make that trade-off? I think so...
Do you run SPListItem.Update() or .SystemUpdate() after setting the properties?
If you want to get an object out of a SPField of a SPListItem you've got to do like this:
SPField field = ((SPList)list).Fields.GetField("FieldName");
object fieldValue = field.GetFieldValue(((SPListItem)item)[field.Title].ToString());
The ListItem.Properties hashtable will be empty unless you assign to it.
SPListItem item = properties.ListItem;
item.Properties["Key"] = "value";
int total = item.Properties.Count;
Answer:
"total == 1"
SPList yourList = web.Lists["Your list name"];
string sColumnValue = oSPListItem[yourList.Fields["yourSiteColumn display
name"].InternalName].ToString();

SharePoint List Item Not Returning Fields

Hi I have a question about SPListItem and how to retrieve values from it. In the view I am in I can access the "Article" no problem but when I try to access the "Link" I can an error saying object not initalized. I don't understand whats going on? Why can I not get the Link when I can get the Article field. Here is the code I am using:
SPList myList = eachWeb.Lists["Listings"];
SPListItemCollection myItemCollection = myList.GetItems(myList.Views["Active Announcements"]);
for (int i = 0; i < myItemCollection.Count; i++)
{
SPListItem realitem = myItemCollection[i];
writer.Write(realitem["Article"].ToString()+"<BR>"); // Works without the bottom line
writer.Write(realitem["Link"].ToString()+"<BR>"); // Causes error
My view contains a column for both Article and Link. Thank you.
The internal name of a field may not match the display name; especially if you've changed the name after creating the list. Try debugging and taking a look at the names of the fields in the SPListItemCollection and see if you can figure out which one it is there.

Resources