The Article entity in MS Dynamics CRM 4.0 doesn't appear to be customizable. Is there any way to add some columns to the view that shows the list of article (without doing an Advanced Find)? I'd like to see the Created By and Created On attributes in there.
R – Add columns in Article view in MS Dynamics CRM 4.0
dynamics-crmdynamics-crm-4
Related Solutions
Searching and filtering via the CRM SDK does take some time to get used to. In order to simulate full text search, you need to use nested FilterExpressions as your QueryExpression.Criteria. SDK page for nested filters The hardest part is figuring out how to build the parent child relationships. There's so much boolean logic going on that it's easy to get lost.
I had a requirement to build a "search engine" for one of our custom entities. Using this method for a complex search string ("one AND two OR three") with multiple searchable attributes was ugly. If you're interested though, I can dig it up. While it's not really supported, if you can access the database directly, I would suggest using SQL's full text search capabilities.
-- ok, here you go. I don't think you'll be able to copy paste this and fulfill your needs. my customer was only doing two to three key word searches and they were happy with the results from this. You can see what a pain it is to just do this in a simple search scenario. I basically puked out code until it was 'working'.
private FilterExpression BuildFilterV2(string[] words, string[] seachAttributes)
{
FilterExpression filter = new FilterExpression();
List<FilterExpression> allchildfilters = new List<FilterExpression>();
List<string> andbucket = new List<string>();
List<string> orBucket = new List<string>();
// clean up commas, quotes, etc
words = ScrubWords(words);
int index = 0;
while (index < words.Length)
{
// if current word is 'and' then add the next wrod to the ad bucket
if (words[index].ToLower() == "and")
{
andbucket.Add(words[index + 1]);
index += 2;
}
else
{
if (andbucket.Count > 0)
{
List<FilterExpression> filters = new List<FilterExpression>();
foreach (string s in andbucket)
{
filters.Add(BuildSingleWordFilter(s, seachAttributes));
}
// send existing and bucket to condition builder
FilterExpression childFilter = new FilterExpression();
childFilter.FilterOperator = LogicalOperator.And;
childFilter.Filters = filters.ToArray();
// add to child filter list
allchildfilters.Add(childFilter);
//new 'and' bucket
andbucket = new List<string>();
}
if (index + 1 < words.Length && words[index + 1].ToLower() == "and")
{
andbucket.Add(words[index]);
if (index + 2 <= words.Length)
{
andbucket.Add(words[index + 2]);
}
index += 3;
}
else
{
orBucket.Add(words[index]);
index++;
}
}
}
if (andbucket.Count > 0)
{
List<FilterExpression> filters = new List<FilterExpression>();
foreach (string s in andbucket)
{
filters.Add(BuildSingleWordFilter(s, seachAttributes));
}
// send existing and bucket to condition builder
FilterExpression childFilter = new FilterExpression();
childFilter.FilterOperator = LogicalOperator.And;
childFilter.Filters = filters.ToArray();
// add to child filter list
allchildfilters.Add(childFilter);
//new 'and' bucket
andbucket = new List<string>();
}
if (orBucket.Count > 0)
{
filter.Conditions = BuildConditions(orBucket.ToArray(), seachAttributes);
}
filter.FilterOperator = LogicalOperator.Or;
filter.Filters = allchildfilters.ToArray();
return filter;
}
private FilterExpression BuildSingleWordFilter(string word, string[] seachAttributes)
{
List<ConditionExpression> conditions = new List<ConditionExpression>();
foreach (string attr in seachAttributes)
{
ConditionExpression expr = new ConditionExpression();
expr.AttributeName = attr;
expr.Operator = ConditionOperator.Like;
expr.Values = new string[] { "%" + word + "%" };
conditions.Add(expr);
}
FilterExpression filter = new FilterExpression();
filter.FilterOperator = LogicalOperator.Or;
filter.Conditions = conditions.ToArray();
return filter;
}
private ConditionExpression[] BuildConditions(string[] words, string[] seachAttributes)
{
List<ConditionExpression> conditions = new List<ConditionExpression>();
foreach (string s in words)
{
foreach (string attr in seachAttributes)
{
ConditionExpression expr = new ConditionExpression();
expr.AttributeName = attr;
expr.Operator = ConditionOperator.Like;
expr.Values = new string[] { "%" + s + "%" };
conditions.Add(expr);
}
}
return conditions.ToArray();
}
When using the CRM web service in a custom workflow, you'll need to use DynamicEntity objects. The workflow context webservice is just an ICrmService so it doesn't know about your specific customizations. There's a pretty sample here: http://www.stunnware.com/crm2/topic.aspx?id=CustomWorkflowActivity
I imagine you could also add the CRM web services as a web reference to your workflow project. Then you'd have strongly types objects for your custom entities. I've never done this for my custom workflows, but it works for other custom apps accessing CRM.
Best Answer
As far as my understanding of the SDK's page on "Unsupported Customizations" goes, this is a supported change....although I can't say for certain.
Go to the following URL (making the necessary replacements):
http://YOURCRMSERVER/YOURORGNAME/tools/viewEditor/viewManager.aspx?id=00000000-0000-0000-00AA-000010001204
and modify the view to suit your needs. Save. From the Customize Entities grid, click Publish All. Alternatively, you should also be able to change the View dropdown to show All Entities, select the Article entity, and click Publish.
To change some other system views, replace the id from the url above with one of the ids below:
00000000-0000-0000-00AA-000010001899 My Activities
00000000-0000-0000-00AA-000010001900 Open Activities
00000000-0000-0000-00AA-000010001901 Closed Activities
00000000-0000-0000-00AA-000010001902 All Activities
00000000-0000-0000-00AA-000010001903 Activities Associated View
00000000-0000-0000-00AA-000010001911 Homepage
00000000-0000-0000-00AA-000010001951 Sales Process Activities Subgrid
00000000-0000-0000-00AA-000000666100 Activities Advanced Find View
00000000-0000-0000-00AA-000010002000 Associated View: Notes
00000000-0000-0000-00AA-000010001203 Associated View Opportunities
00000000-0000-0000-00AA-000010001204 Articles
00000000-0000-0000-00AA-000010001205 Associated View: Teams
00000000-0000-0000-00AA-000010001206 Associated View: Competitors
00000000-0000-0000-00AA-000010001207 Associated View: Business Units
00000000-0000-0000-00AA-000010001208 Associated View: Roles
00000000-0000-0000-00AA-000010001209 Articles - Manage KB Search
00000000-0000-0000-00AA-000010001210 Associated View: Contacts
I came across most of this helpful at icu-mscrm.blogspot.com/2005/07/customizing-activity-views.html.