CAML person or Group field with Multiple values - sharepoint

I have a Field with Name TargetedPeople in a Sharepoint list. This is a Person or User group which can have multiple values.
The CAML I used for Querying is
siteDataQuery.Query = #"<Where><Includes><FieldRef Name='TargetedPeople' LookupId='TRUE'/><Value Type='Integer'>" + webInContext.CurrentUser.ID + "</Value></Includes></Where>";
This works fine if we have set the Allow Multiple Selections for "No" in the field. But this seems like not working for if it set to "Yes".
Please share me how to query a multiple field.

After some changes I was able to figure out this. If the field has multiple values we should define the value Type as LookupMulti. Following is the working code sample
siteDataQuery.Query = #"<Where><Contains><FieldRef Name='TargetedPeople' LookupId='TRUE'/><Value Type='LookupMulti'>" + webInContext.CurrentUser.ID + "</Value></Contains></Where>";

Also works and looks like simpler (tested on SP Online):
<Contains>
<FieldRef Name='TargetedPeople' />
<Value Type="Integer">
<UserID Type="Integer" />
</Value>
</Contains>

Related

SharePoint Online: Get Document Library Children Count Using CSOM

My requirement is to get the children item count of Document Library using CSOM. The count should only be the immediate children count, and should not include the sub-children count. I am trying to use below code to achieve this:
var newObjClientContext = this.GetSharePointClientContext(accessToken, fullUri);
WebCollection collWeb = newObjClientContext.Web.GetSubwebsForCurrentUser(new SubwebQuery());
var documentLibrary = newObjClientContext.Web.Lists.GetById(docID);
ListItemCollection ltitems = null;
string vquery = #"<View >
<Query>
<Where>
<Or>
<Eq>
<FieldRef Name='FSObjType' />
<Value Type='Lookup'>1</Value>
</Eq>
<Eq>
<FieldRef Name='FSObjType' />
<Value Type='Lookup'>0</Value>
</Eq>
</Or>
</Where>
<OrderBy><FieldRef Name='FileLeafRef' Ascending='TRUE'></FieldRef></OrderBy>
</Query>
<RowLimit>" + recCount + #"</RowLimit>
</View>";
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = vquery;
ltitems = documentLibrary.GetItems(camlQuery);
newObjClientContext.Load(documentLibrary);
newObjClientContext.Load(ltitems, lists => lists.IncludeWithDefaultProperties(l => l.ParentList));
newObjClientContext.ExecuteQuery();
int totalcount = documentLibrary.ItemCount; //It includes count of all the items present at all levels.
Can anyone suggest how can I get children count in above step?
If I have interpreted your requirement correctly you want the root level child item count of the document library? This is easily achieved using the ItemCount property of document libraries RootFolder.
var list = web.Lists.GetByTitle("Documents");
cc.Load(list.RootFolder, l => l.ItemCount);
cc.ExecuteQuery();
var rootChildItemCount = list.RootFolder.ItemCount;
Or do you require the child item count of every folder in your document library? This can be achieved with a CamlQuery. Let me know if your require a solution for this.

Create a site-column of type user, multichoice and multiuser using Sharepoint Client Object Model

I'm trying to create site-columns with following types: Text, Note, Number, Choice, User, MultiUser, MultiChoice
I've implemented it for all the types except for User, MultiChoice and MultiUser. Can't seem to find how to achieve it. This is what I've achieved so far.
StringBuilder choiceFieldGenericShema = new StringBuilder();
choiceFieldGenericShema.Append("<Field Type='Choice' Format='Dropdown' Group='{1}' Name='{0}' DisplayName='{2}' Status='{3}' > <CHOICES> ");
choiceFieldGenericShema.Append("</CHOICES> </Field> ");
string choicFieldSchema = string.Format(choiceFieldGenericShema.ToString(), columnItem.Title, columnItem.GroupName, columnItem.Name, columnItem.Status);
var newField = web.Fields.AddFieldAsXml(choicFieldSchema, true, AddFieldOptions.DefaultValue);
clientContext.Load(newField);
clientContext.ExecuteQuery();
Can anyone please suggest a way following the above method to achieve my task? Thanks in advance!
I suggest you take a look at these articles:
List with XML declarations of different field types
Adding columns to a site
In this case, you'll need to tweak with some attributes to toggle multi select for a choice + user field:
Choice:
<Field Type="MultiChoice"
DisplayName="Labels_Selected"
FillInChoice="FALSE"
Group="Sample Site Columns"
ID="{2fdf0ba7-0052-4e9f-80f6-e7669ac4ae4f}"
SourceID="http://schemas.microsoft.com/sharepoint/v3"
StaticName="LabelsSelected" Name="LabelsSelected">
</Field>
User:
<Field ID="{A0372EB5-A947-41CA-A5FA-A34C29D2FB88}"
Name="Employee"
DisplayName="Employee"
Type="UserMulti"
Required="TRUE"
StaticName="Employee"
UserSelectionMode="PeopleOnly"
Group="SampleGroup"/>
You can create site column using csom, below is code
string schemaChoiceField = "<Field ID='<GUID>' Type='Choice' Name='SideDishesChoice' StaticName='SideDishesChoice'
DisplayName='Side dishes' Format='RadioButtons'>"
+ "<Default>Patatoes</Default>"
+ "<CHOICES>"
+ " <CHOICE>Fresh vegetables</CHOICE>"
+ " <CHOICE>Beans</CHOICE>"
+ "</CHOICES>"
+ "</Field>";
For dropdown or radio button follow the link http://projectservercode.com/create-choice-type-site-column-using-csom-sharepoint/

Query on Date Fields using CAML

I am trying to run a query against a sharepoint list (using the client object model), finding an item that matches on a date field.
My query is:
2012-07-24T02:50:28
1
I know that there is an item in the list where the EmDateSent field has the value 2012-07-24T02:50:28 and yet when I run this I get 0 rows back.
Having spent hours researching and experimenting I found that the date formatting I have used works - or so I thought. It seems that now it doesn't.
My code is below.
Can anybody suggest something else I can try?
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = String.Format(
#"<View>
<Query>
<Where>
<Eq>
<FieldRef Name='{0}'/>
<Value Type='DateTime' IncludeTimeValue='True'>{1}</Value>
</Eq>
</Where>
</Query>
</View>", EMAIL_FIELD_DATE_SENT, details.DateSent.HasValue ? details.DateSent.Value.ToString("yyyy-MM-ddTHH:mm:ss") : "");
ListItemCollection listItems = upLoadList.GetItems(camlQuery);
_context.Load(listItems);
_context.ExecuteQuery();
if (listItems.Count > 0) // At this point I expect listItems.Count to be 1, but it is 0
{
....
Your example looks correct, and there is not an issue with using the "T" in the time stamp. However, from what I can find, most of the examples like yours use the SPQuery class instead of the CamlQuery class. I believe this is causing your issue.

Using CAML to compare SharePoint "Person or Group" fields

I have a SharePoint 2007 (MOSS) list with 2 "Person or Group" columns which I would like to compare, essentially:
SELECT * FROM List WHERE (Analyst = Developer)
In my code (C#) I've built this as:
SPQuery itemQuery = new SPQuery();
itemQuery.Query = "<Where><Eq><FieldRef Name='Analyst' /><FieldRef Name='Developer' /></Eq></Where>";
SPListItemCollection queryResults = list.GetItems(itemQuery);
But this is throwing an exception ("Exception from HRESULT: 0x80020009 (DISP_E_EXCEPTION)").
I've seen some information regarding the Type attribute of a Value element when comparing against a "Person or Group" column, but nothing about comparing two of these columns against each other.
I've also tried adding "LookupId='TRUE'" to each FieldRef, with no change.
It is not possible to compare two fields like that using CAML. You have to use a literal value. This means, that you'll likely have two queries:
Retrieve the Analyst/Developer's user ID
Retrieve items where Analyst and Developer are the same
Example of #2:
<Where>
<And>
<Eq><FieldRef Name="Analyst" LookupId="TRUE"/><Value Type="Integer">42</Value></Eq>
<Eq><FieldRef Name="Developer" LookupId="TRUE"/><Value Type="Integer">42</Value></Eq>
</And>
</Where>
FYI, you can also use <UserID/> for the "Current User" instead of user ID (in this example, 42).
The logic you are looking for, I believe, is this:
<Where>
<Eq>
<FieldRef Name='Analyst'/>
<Value Type="Text"><FieldRef Name='Developer'/></Value>
</Eq>
</Where>
I tested and this is not possible so the two options, as I see it, are:
Get all list items , then iterate through with JQuery with a find and compare for the two fields being equal.
Create a calculated column that sets a true or false value if the two columns are equal in the list and then do your select based on that column. This is probably the most expedient and also most effective from a performance perspective.
Try this:
<Where>
<Eq>
<FieldRef Name="Analyst" />
<Value Type="Text">Developer</Value>
</Eq>
</Where>
I have found a list that has two matching values to compare and I got a CAML query to work with the comparison; however, it is a boolean value so I am not sure if this is what you are looking for. It does compare two fields but I think the literal is still getting in the way. This list has about 25 entries in it and this is the only one that matched so I thought this would be a good test.
Here is the code:
private DataTable ExecuteQuery(SPList list)
{
SPQuery qry = new SPQuery();
qry.Query = "<Where><And><Contains><FieldRef Name='Show' /><Value Type='Boolean'>1</Value></Contains><Contains><FieldRef Name='Highlight' /><Value Type='Boolean'>1</Value></Contains></And></Where>";
qry.ViewFields = "<FieldRef Name='Show' /><FieldRef Name='Highlight' />";
qry.IncludeMandatoryColumns = true;
return list.GetItems(qry).GetDataTable();
Sorry if this is not what you are looking for. Good Luck!!

How can I write a SPQuery to filter items based on a LinkFieldValue?

I need to select a single value from a SharePoint list based on a field value. The type of the field is LinkFieldValue. How should I write the CAML query?
When I select the items with an empty query, I receive all the items in the list as expected.
When I add constraints to the query, it returns an empty result. I have tried constructing the query as follows:
string.Format("<Where><Eq><FieldRef Name=\"PollInstancePoll\" /><Value "
+"Type=\"Text\">{0}</Value></Eq></Where>",
new LinkFieldValue { NavigateUrl = "/az/Lists/Polls/DispForm.aspx?ID=1",
Text = "example poll" });
which results in the following query text:
<Where><Eq><FieldRef Name="PollInstancePoll" />
<Value Type="Text">example poll</Value>
</Eq></Where>
I have solved my problem with the following query:
new SPQuery
{
Query =
CAML.Where(
CAML.And(
CAML.Contains(
CAML.FieldRef("PollInstancePoll"),
CAML.Value(pollPath)),
CAML.Contains(
CAML.FieldRef("PollInstancePage"),
CAML.Value(pagePath))))
};
Essentially I am checking only the URL part of the Link field, and providing the value for comparison as Type="Text". It is important to remember that SharePoint stores the values in database always as server-relative URLs.

Resources