Below I am accessing a SharePoint list and feeding it into a ListItemCollection which is working, but what I would like to do is feed two fields from the list into a DataTable (so the dt would have two columns), but I couldn't find anything that meets my requirements online. I'm also new to this. What would be the best way to do this?
static void Main(string[] args)
{
string siteUrl = ConfigurationManager.AppSettings["SiteUrl"];
string clientID = ConfigurationManager.AppSettings["ClientId"];
string clientSecret = ConfigurationManager.AppSettings["ClientSecret"];
using (ClientContext cc = new AuthenticationManager().GetACSAppOnlyContext(siteUrl, clientID, clientSecret))
{
Web site = cc.Web;
List targetList = site.Lists.GetByTitle("Companies");
CamlQuery query = new CamlQuery();
query.ViewXml = "<View><Query><Where><Contains><FieldRef Name='CompanyID'/><Value Type='Text'>Cumbria</Value></Contains></Where></Query></View>";
ListItemCollection collListItem = targetList.GetItems(query);
cc.Load(collListItem);
cc.ExecuteQuery();
if (collListItem.Count == 0)
{
Console.WriteLine("No items found.");
}
else
{
Console.WriteLine("Items found:\n");
foreach (ListItem targetListItem in collListItem)
Console.WriteLine(targetListItem["Reference"]);
Console.ReadLine();
}
}
}
Related
I need to update a large SharePoint List, about 10,000 items or more. Each ListItem has 4 columns to be updated. I don't know what the best approach for this scenario is:
Use 1 ClientContext, fetch ListItemCollection in batch of n rows,
loop through each ListItem and update its columns before the next
batch. Or
Fetch a list of ListItemCollectionPosition in batch of n rows, loop through each ListItemCollectionPosition, create a new ClientContext, fetch ListItemCollection and then update.
Method 1
using (ClientContext ctx = new ClientContext(url))
{
ctx.Credentials = new SharePointOnlineCredentials(username,password);
List list = ctx.Web.Lists.GetByTitle("mylist");
ctx.Load(list);
ctx.ExecuteQuery();
ListItemCollectionPosition pos = null;
CamlQuery camlQuery = new CamlQuery
{
ViewXml = "<View Scope='Recursive'><RowLimit>100</RowLimit></View>"
};
do
{
if (pos != null)
{
camlQuery.ListItemCollectionPosition = pos;
}
ListItemCollection listItemCollection = list.GetItems(camlQuery);
ctx.Load(listItemCollection);
ctx.ExecuteQuery();
pos = listItemCollection.ListItemCollectionPosition;
foreach(ListItem item in listItemCollection)
{
item["col1"] = "abc";
item["col2"] = "def";
item["col3"] = "ghi";
item["col4"] = "jkl";
item.Update();
}
ctx.ExecuteQuery();
} while (pos != null);
}
Method 2
private void UpdateList()
{
using (ClientContext ctx = new ClientContext(url))
{
ctx.Credentials = new SharePointOnlineCredentials(username,password);
List list = ctx.Web.Lists.GetByTitle("mylist");
ctx.Load(list);
ctx.ExecuteQuery();
ListItemCollectionPosition pos = null;
CamlQuery camlQuery = new CamlQuery
{
ViewXml = "<View Scope='Recursive'><RowLimit>100</RowLimit></View>"
};
List<ListItemCollectionPosition> positions = new List<ListItemCollectionPosition>();
do
{
if (pos != null)
{
camlQuery.ListItemCollectionPosition = pos;
}
ListItemCollection listItemCollection = list.GetItems(camlQuery);
ctx.Load(listItemCollection);
ctx.ExecuteQuery();
pos = listItemCollection.ListItemCollectionPosition;
positions.Add(pos);
} while (pos != null);
List<Task> tasks = new List<Task>();
foreach(var position in positions)
{
tasks.Add(UpdateItem(position));
}
Task.WaitAll(tasks.ToArray());
}
}
private Task UpdateItem(ListItemCollectionPosition pos)
{
using (ClientContext ctx = new ClientContext(url))
{
ctx.Credentials = new SharePointOnlineCredentials(username,password);
List list = ctx.Web.Lists.GetByTitle("mylist");
ctx.Load(list);
ctx.ExecuteQuery();
CamlQuery camlQuery = new CamlQuery
{
ViewXml = "<View Scope='Recursive'><RowLimit>100</RowLimit></View>"
};
camlQuery.ListItemCollectionPosition = pos;
ListItemCollection listItemCollection = list.GetItems(camlQuery);
ctx.Load(listItemCollection);
ctx.ExecuteQuery();
foreach(ListItem item in listItemCollection)
{
item["col1"] = "abc";
item["col2"] = "def";
item["col3"] = "ghi";
item["col4"] = "jkl";
item.Update();
}
return ctx.ExecuteQueryAsync();
}
}
In method 1 and 2 I would set ViewFields to limit amount of data that is transfered.
In method 2 UpdateItem method is executed after positions collection is full. Why not updating list items while positions collection is being populated - You could implement enumerator with yield attribute.
public static IEnumerable<ListItemCollectionPosition> GetPositions()
{
do
{
...
yield return pos;
...
} while (pos != null);
}
I need to get list items which is older than say 7 days and delete them. I tried using caml query and it worked well in sharepoint 2010 but when I tried to use the same in Sharepoint Online, its getting all list items and deleting it regardless of the condition.
public static bool removeOldEntries(string listName, int offset)
{
bool successFlag = true;
try
{
using (var context = new ClientContext(siteURL))
{
SecureString password = ToSecureString(pwd);
context.Credentials = new SharePointOnlineCredentials(userName, password);
Web web = context.Web;
var list = context.Web.Lists.GetByTitle(listName);
if (list != null)
{
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = "<Where><Leq><FieldRef Name='Modified'/><Value Type='DateTime'><Today OffsetDays='-" + offset + "'/></Value></Leq></Where>";
ListItemCollection collListItem = list.GetItems(camlQuery);
context.Load(collListItem, items => items.Include(
item => item["ID"]));
context.ExecuteQuery();
if (collListItem.Count > 0)
{
foreach (ListItem oListItem in collListItem)
{
ListItem itemToDelete = list.GetItemById(int.Parse(oListItem["ID"].ToString()));
itemToDelete.DeleteObject();
context.ExecuteQuery();
}
}
}
}
}
catch (Exception ex)
{
successFlag = false;
}
return successFlag;
}
Thanks in advance for any help.
First try adding a Tag in your view xml
So it should look like
camlQuery.ViewXml = "<Query><Where><Leq><FieldRef Name='Modified'/><Value Type='DateTime'><Today OffsetDays='-" + offset + "'/></Value></Leq></Where></Query>";
If it doesn't help try adding a view tag
camlQuery.ViewXml = "<View><Query><Where><Leq><FieldRef Name='Modified'/><Value Type='DateTime'><Today OffsetDays='-" + offset + "'/></Value></Leq></Where></Query></View>";
you can make use of the PNP.PowerShell Module.
$CreationDate = Get-Date "16.06.2021 20:04" -Format s
Get-PnPListItem -List "Opportunities" -Query "<View><Query><Where><Eq><FieldRef Name='Created'/><Value Type='DateTime' IncludeTimeValue='FALSE'>$CreationDate</Value></Eq></Where></Query></View>"
For more check out the reference:
https://sposcripts.com/sharepoint/sharepointonline/filtering-for-sharepoint-items-with-caml-queries/#If_DateTime_should_exactly_match_a_specific_date
At work we had to move from SharePoint 2010 to 2013 and my code for retrieving list items doesn't work anymore. Here is my code for SP 2010:
com.mycompany.intranet.Lists listService = new com.mycompany.intranet.Lists();
listService.Credentials = System.Net.CredentialCache.DefaultCredentials;
listService.Url = "url";
System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
string listName = cbxMailDistributionList.SelectedValue.ToString();
string viewName = "";
string rowLimit = "0";
System.Xml.XmlElement query = xmlDoc.CreateElement("Query");
System.Xml.XmlElement viewFields = xmlDoc.CreateElement("ViewFields");
System.Xml.XmlElement queryOptions = xmlDoc.CreateElement("QueryOptions");
viewFields.InnerXml = "<FieldRef Name='Title' />";
System.Xml.XmlNode nodeListItems =
listService.GetListItems(listName, viewName, query, viewFields, rowLimit, queryOptions, null);
xmlDoc.LoadXml(nodeListItems.InnerXml);
xlNodeList rows = xmlDoc.GetElementsByTagName("z:row");
List<string> recipients = new List<string>();
foreach (XmlNode attribute in rows)
{
if(attribute.Attributes["ows_Title"].Value == null){}
else {
if (recipients.Contains(attribute.Attributes["ows_Title"].Value)){}
else {
recipients.Add(attribute.Attributes["ows_Title"].Value);
}
}
}
recipients.Sort();
distributionList = recipients;
Can you please help me to get it working with a SharePoint 2013 list again?
URL has already been updated but i get the following error: https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=DE-DE&k=k(EHNullReference);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.0);k(DevLang-csharp)&rd=true
But the list has no empty fields.
listName
is the ID of the list element.
Please help.
Thanks in advance!
Finally it works again with this code:
List<string> recipients = new List<string>();
string siteURL = #"myurl/";
ClientContext cc = new ClientContext(siteURL);
cc.Credentials = System.Net.CredentialCache.DefaultCredentials;
Web web = cc.Web;
List list = web.Lists.GetById(new Guid(cbxMailDistributionList.SelectedValue.ToString()));
CamlQuery caml = new CamlQuery();
ListItemCollection items = list.GetItems(caml);
cc.Load<List>(list);
cc.Load<ListItemCollection>(items);
cc.ExecuteQuery();
foreach (Microsoft.SharePoint.Client.ListItem item in items)
{
if(item.FieldValues["Title"] == null) { }
else
{
if (recipients.Contains(item.FieldValues["Title"].ToString())) { }
else
{
recipients.Add(item.FieldValues["Title"].ToString());
}
}
}
recipients.Sort();
distributionList = recipients;
}
else
{
distributionList = null;
}
New day, new luck. Sorry for the prematurely posting of this question. I should have slept on it for a night. ;)
BR
I have the following code for load a list from sharepoint site.
ALl is working well exept a SPList item to SPListItemCollection.
private void Data_load()
{
DataTable dt = new DataTable();
string currentName = SPContext.Current.Web.CurrentUser.Name;
SPQuery query = new SPQuery();
query.Query = "<Where><Eq><FieldRef Name='Editor'/><Value Type='Person or Group'>" + currentName + "</Value></Eq></Where>";
using (SPSite site = new SPSite("http://spdev-6/"))
{
using (SPWeb web = site.OpenWeb())
{
SPList lists = web.GetList("Lists/Advertisements");
SPListItemCollection items = lists.GetItems(query);
if (items.Count > 0)
{
DataRow dr=null;
SPListItemCollection ITEM = null;
foreach(SPListItem item in items)
{
string A = item["Approval Status"].ToString();
if(A== "2")
{
ITEM.Add(item);
}
}
if(dt.Rows.Count==0)
lbldata.Text = "No data to show";
// dt = items.GetDataTable();
}
else
lbldata.Text = "No data to show";
GridViewD.DataSource = dt;
GridViewD.DataBind();
HttpContext.Current.Session["Advertisement"] = dt;
}
}
}
Now in if(A== "2"){ ITEM.Add(item); }
I want to add SPListItem to a SPListItemCollection. Please help.
You are trying to add an item into null because your ITEM is null. I don't know what error you are getting ( your don't write it) but you must initialize your collection:
if (items.Count > 0)
{
DataRow dr=null;
SPListItemCollection ITEM = ... //
foreach(SPListItem item in items)
{
string A = item["Approval Status"].ToString();
if(A== "2")
{
SPListItem myItem = ITEM.Add();
// set your item's fields here
// Use indexers on this object for each field to assign specific values, and then call the Update method on the item to effect changes in the database.
myItem["Approval Status"] = item["Approval Status"];
...
myItem.Update();
}
}
if(dt.Rows.Count==0)
lbldata.Text = "No data to show";
// dt = items.GetDataTable();
}
How to get fields values from a particular list item.In my case i want to get all form fileds of Workplan list.Actually i want to get Workplan all list item and insert to sharepoint 2013 associated database.
I try the following code.
string strUrl = "http://example.com/default.aspx";
using (SPSite site = new SPSite(strUrl))
{
using (SPWeb web = site.OpenWeb())
{
SPList list = web.Lists[52];
SPQuery myquery = new SPQuery();
myquery.Query = "";
SPListItemCollection items = list.GetItems(myquery);
foreach (SPListItem item in items)
{
if (item != null)
{
var Name = item.ListItems.Fields.List;
Console.WriteLine("Name is :" + Name);
}
}
}
}
This is the easiest way I can think of using Server Object Model:
string strUrl = "http://example.com";
using(SPSite oSite = new SPSite(strUrl))
{
using(SPWeb oWeb = oSite.OpenWeb())
{
SPList list = oWeb.Lists["Workplan"];
foreach(SPField field in list.Fields)
{
Console.WriteLine(field.Title);
}
}
}
Btw, as for your site-URL "http://example.com/default.aspx" it is enough to do it like "http://example.com".
For more information on Sharepoint I recommend using this site in the future.
using (SPSite site = new SPSite("URL")
{
using (SPWeb web = site.OpenWeb("sitecollection/subsite"))
{
//to get specific list type
string listUrl = "/sites/sitecollection/subsite/Lists/Announcements";
SPList list = web.GetList(listUrl);
Console.WriteLine("List URL: {0}", list.RootFolder.ServerRelativeUrl);
}
}
//To get all lists from spweb use this:
SPSite oSiteCollection = SPContext.Current.Site;
using(SPWebCollection collWebs = oSiteCollection.AllWebs)
{
foreach (SPWeb oWebsite in collWebs)
{
SPListCollection collSiteLists = oWebsite.Lists;
foreach (SPList oList in collSiteLists)
{
//get your each list here
}
oWebsite.Dispose();
}
}