I am new to CAML. CAML seems like a great way to filter lists, but I am struggling to write nested and/or statements.
I am trying to start out small and write one CAML query with only two conditions so I can get the hang of it. Below is my failed attempt.
<View>
<Query>
<Where>
<and>
<Contains>
<FieldRef Name='PracticeArea_x0028_s_x0029_' />
<Value Type='Text'>Lean</Value>
</Contains>
<NotInclude>
<FieldRef Name='PracticeArea_x0028_s_x0029_' />
<Value Type='Text'>,</Value>
</NotInclude>
</and>
</Where>
</Query>
</View>
Any help, support, and/or insight this community can provide is greatly appreciated.
NotInclude used for Lookup field that allows multiple values, so won't work if you filter against a text field.
https://learn.microsoft.com/en-us/sharepoint/dev/schema/notincludes-element-query
You could filter by Contains first and then filter by Linq or similar approach.
SPList list = web.Lists.TryGetList("TestFilter");
SPQuery spQuery = new SPQuery();
spQuery.Query = #"<Where>
<Contains>
<FieldRef Name='PracticeArea' />
<Value Type='Text'>Lean</Value>
</Contains>
</Where>";
var items = list.GetItems(spQuery);
var filterItems=items.Cast<SPListItem>().Where(item => string.Format("{0}",item["PracticeArea"]).IndexOf(',') <0);
Console.WriteLine(filterItems.Count());
Related
I just use Sharepoint for few days and I know this question have asked many times but I've tried all of them and none of them work.
These are my design
Document as a Document Library type have a Id
Id | DocumentName
---+-------------
1 | Document A
2 | Document B
Activities list, have a foreign key 'DocId' that reference to the Document Id
Id | DocId | Name
---+-------+-----------
1 | 1 | Activity A
2 | 1 | Activity B
3 | 1 | Activity C
4 | 2 | Activity D
The Problem is I need to get all the Activities that included the document name on the Document.
In SQL I can use Join query to get the additional information from another table. But I have try some Join statement in CAML query and none of them work.
Here is the result that I need to get.
Id | DocId | Name | DocumentName
---+-------+--------------------------
1 | 1 | Activity A | Document A
2 | 1 | Activity B | Document A
3 | 1 | Activity C | Document A
4 | 2 | Activity D | Document B
Could any one please suggest me the query?
Here is my query:
<View>
<ViewFields>
<FieldRef Name = 'DocLeafRef'/>
<FieldRef Name = 'ID'/>
<FieldRef Name = 'e8_document'/>
<FieldRef Name = 'Title'/>
<FieldRef Name = 'Author'/>
<FieldRef Name = 'Created'/>
</ViewFields>
<Joins>
<Join Type = 'INNER' ListAlias = 'Documents'>
<Eq>
<FieldRef Name ='e8_document' RefType = 'Id'/>
<FieldRef Name ='ID' List ='Documents'/>
</Eq>
</Join>
</Joins>
<ProjectedFields>
<Field ShowField ='FileLeafRef' Type ='Lookup' Name ='DocLeafRef' List ='Documents'/>
</ProjectedFields>
<Query>
<Where>
<Eq>
<FieldRef Name='e8_caseId'></FieldRef>
<Value Type = 'Number'>23</Value>
</Eq>
</Where>
</Query>
</View>
I'm query on the Activities list and the e8_document is the lookup field that reference to the Id in the Document. As I understand we need the projection and I've added the projection but the query throws an error.
It seems the Query element is invalid in your case, basically Query element could not contain Joins as a child element.
Server-Side Object Model
For SPQuery Class Joins element needs to be specified via SPQuery.Joins Property:
var qry = new SPQuery();
qry.Joins = #"<Join Type="LEFT" ListAlias="Documents">
<Eq>
<FieldRef Name="DocId" RefType="ID" />
<FieldRef Name="ID" List="Documents" />
</Eq>
</Join>";
Client-Side Object Model
Here is the complete CAML query for CSOM API:
<View>
<ViewFields>
<FieldRef Name="ID" />
<FieldRef Name="DocId" />
<FieldRef Name="Name" />
<FieldRef Name="Documents" />
</ViewFields>
<Joins>
<Join Type="LEFT" ListAlias="Documents">
<Eq>
<FieldRef Name="DocId" RefType="ID" />
<FieldRef Name="ID" List="Documents" />
</Eq>
</Join>
</Joins>
<ProjectedFields>
<Field ShowField="DocumentName" Type="Lookup" Name="Documents" List="Documents" />
</ProjectedFields>
<Query />
</View>
I am new to CAML query and as much as I have expected it to be simple like SQL I have found it quite frustrating to deal with. I have a simple query SQL query I am trying to translate into CAML but do not receive the expected result.
Sql: select * from exchangeRates where (date='2016-12-01' and currency<>'DKK')
Or
(date='2016-11-25' and currency_Type = 'Manual')
Any help is appreciated. Thanks.
Equals and Not Equals
Use the <Eq> element to find items where a field equals a specified value and the <Neq> element to find items where a field is not equal to a specified value.
<Eq>
<FieldRef Name="Internal_Name_Of_Date_Field" />
<Value Type="DateTime">2016-12-01</Value>
</Eq>
Joining Conditions to build Complex Conditionals
CAML uses <And> and <Or> elements to join conditions together within a <Where> clause.
<And>
<Eq>
...
</Eq>
<Neq>
...
</Neq>
</And>
Each <And> or <Or> element expects exactly two child nodes, which are the conditions being joined together.
A child node can be another <And> or <Or> element, allowing you to join nested conditions together for arbitrarily complex conditions.
<Or>
<And>
...
</And>
<And>
...
</And>
<Or>
Using Excel Formulas as Conceptual Guidelines
Sometimes it helps to think in terms of an Excel formula. The Excel functions OR() and AND() can take two parameters (conditions) to return a boolean value. CAML syntax and Excel syntax are thus pretty similar: CAML just uses XML elements instead of parentheses.
English: (A and B) or (C and D)
Excel: OR( AND(A, B), AND(C, D) )
CAML: <Or> <And> A B </And> <And> C D </And> </Or>
Example CAML
Without knowing what the internal names of your columns are, the <Where> element of your CAML query might look something like this:
<Where>
<Or>
<And>
<Eq>
<FieldRef Name="Internal_Name_Of_Date_Field" />
<Value Type="DateTime">2016-12-01</Value>
</Eq>
<Neq>
<FieldRef Name="Internal_Name_Of_Currency_Field" />
<Value Type="Text">DKK</Value>
</Neq>
</And>
<And>
<Eq>
<FieldRef Name="Internal_Name_Of_Date_Field" />
<Value Type="DateTime">2016-11-25</Value>
</Eq>
<Eq>
<FieldRef Name="Internal_Name_Of_Currency_Type_Field" />
<Value Type="Text">Manual</Value>
</Eq>
</And>
<Or>
</Where>
I am fairly experienced with CAML Queries, but this one has me stuck. I need some help in structuring the query's logic.
What I need is to return every record that that contains two words across two columns.
Example (return these):
Column1: word1, Column2: word2. //Return this record
Column1: word2, Column2: word1. //Return this record
Column1: word2 word1, Column2: (empty). //Return this record
Column1: (empty), Column2: word2 word1. //Return this record
Example (do not return these):
Column1: (empty), Column2: word1. // Do not return this record
Column1: word1, Column2: (empty). // Do not return this record
Column1: (empty), Column2: word2. // Do not return this record
Column1: word2, Column2: (empty). // Do not return this record
Column1: (empty), Column2: (empty). // Do not return this record
To put the logic in sudo-code:
if( ("word1" appears in 'Column1' OR "word1" appears in 'Column2') AND ("word2" appears in 'Column1' OR "word2" appears in 'Column2') )
I have tried different variations of queries, but they do not return desirable results. For example, the one below will always return a record if word1 appears in Column1 even if word2 does not appear anywhere.
<Query>
<Where>
<Or>
<Contains>
<FieldRef Name="Column1"/><Value Type="Text">word1</Value>
</Contains>
<And>
<Contains>
<FieldRef Name="Column2"/><Value Type="Text">word1</Value>
</Contains>
<Or>
<Contains>
<FieldRef Name="Column1"/><Value Type="Text">word2</Value>
</Contains>
<Contains>
<FieldRef Name="Column2"/><Value Type="Text">word2</Value>
</Contains>
</Or>
</And>
</Or>
</Where>
P.S. I am in SharePoint 2007 using SPServices
Thanks to spevilgenius on spservices.codeplex.com, here is what worked for me:
<And>
<Or>
<Contains>
<FieldRef Name="Column1"/><Value Type="Text">word1</Value>
</Contains>
<Contains>
<FieldRef Name="Column2"/><Value Type="Text">word1</Value>
</Contains>
</Or>
<Or>
<Contains>
<FieldRef Name="Column1"/><Value Type="Text">word2</Value>
</Contains>
<Contains>
<FieldRef Name="Column2"/><Value Type="Text">word2</Value>
</Contains>
</Or>
</And>
Link to discussion:
https://spservices.codeplex.com/discussions/637384
In SharePoint 2010, I need to get items from a list based on a condition. Considering one of the fields to be 'Date' of type DateTime, the condition is:
Get Current Month Data.
How do I filter the list items based on this condition using CAML query?
By,
Raji
Use SPUtility.CreateISO8601DateTimeFromSystemDateTime to create relevant dateTime string
DateTime firstDay = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
Sting stringQuery =
String.Format(#"<And>
<Geq>
<FieldRef Name='Date' />
<Value Type='DateTime'>{0}</Value>
</Geq>
<Leq>
<FieldRef Name='Date' />
<Value Type='DateTime'>{1}</Value>
</Leq>
</And>",
SPUtility.CreateISO8601DateTimeFromSystemDateTime(firstDay),
SPUtility.CreateISO8601DateTimeFromSystemDateTime(firstDay .AddMonths(1)));
SPQuery query = new SPQuery(stringQuery);
In the following CAML query I reference 0 in the the line below.
<Value Type='Text'>0</Value>
This doesn't work even when the value is 0 bu twhen it is A it does work (I have entries in for both A and 0). I am unsure why numeric values are not getting picked up.
Any help would be appreciated.
<Query>
<Where>
<And>
<Eq>
<FieldRef Name='TCategories' />
<Value Type='Text'>Abbreviations</Value>
</Eq>
<BeginsWith>
<FieldRef Name='FirstCharacter' />
<Value Type='Text'>0</Value>
</BeginsWith>
</And>
</Where>
</Query>
i do have a similar query like this
which is actually working fine for me.
Make sure that the columns in your query "TCategories" and "FirstCharacter" are of Text type.
Thanks,
-Codename "Santosh"