While working with the CRM Rollup messages this morning, I found either a bug or a documentation error in the activitypointer.statecode property.
The statecode is a field type of the ActivityPointerStateInfo class, which has two properties: formattedvalue and Value.
formattedvalue should be a string representation of the ActivityPointerState Enumeration, and the Value should be the numerical equivalent, as shown below:
Canceled = 2
Completed = 1
Open = 0
Scheduled = 3
But, this does not appear to be the case. When I examine the activitypointer class inside of Visual Studio, I see the following:
As you can see, formattedvalue is null, while the Value property is the textual representation of the ActivityPointerState Enumeration.
Just FYI should you be expecting to find a number in the Value property.
A possible work around:
A possible solution to this issue is to use the statuscode property. As you can see from the above picture, it has the correct name and Value pairs.
As you have probably seen, CRM has the ability to roll-up information from child Entities to the parent Entity. Activities would be one such example: When you look at the Activities for an Account, you actually see Activities for both the main Account as well as all Activities for the Account's Contacts as well. A pretty great feature, if you ask me.
Anyway, the CRM SDK also has Roll-up messages that allow you to retrieve information in a similar manner. The following list shows the target classes for the Rollup message:
TargetRollupActivityPointerByAccount
TargetRollupActivityPointerByContact
TargetRollupActivityPointerByOpportunity
TargetRollupAnnotationByAccount
TargetRollupAnnotationByContact
TargetRollupAnnotationByOpportunity
TargetRollupOpportunityByAccount
TargetRollupOpportunityByContact
TargetRollupSalesOrderByAccount
TargetRollupSalesOrderByContact
I haven't worked through all of these messages, but I have tested the Activitypointer ( Activities ) and Annotation ( Notes ) messages, and they work exactly as you would expect.
I did have one problem when I first started playing around this morning: I couldn't make it work. No matter what I tried, I could not make the rollup message execute successfully. Luckily, Jonathan Randall, one of the Microsoft Online Support resources, had posted a solution to my exact problem, to another person back in April of 2006. His code is follows:
RollupResponse related = null; try { QueryExpression query = new QueryExpression(); query.EntityName = EntityName.activitypointer.ToString(); query.ColumnSet = new AllColumns(); TargetRollupActivityPointerByAccount activityRollup = new TargetRollupActivityPointerByAccount(); activityRollup.AccountId =
new Guid("69B242AE-0348-DB11-AAA0-00142A05B544");
activityRollup.Query = query;
RollupRequest rollup = new RollupRequest();
rollup.ReturnDynamicEntities=false;
rollup.RollupType=RollupType.Related;
rollup.Target=activityRollup;
related = (RollupResponse)service.Execute(rollup);
if (related.BusinessEntityCollection.BusinessEntities.Length >0)
{
string txtResults = string.Empty;
foreach (activitypointer pointer in
related.BusinessEntityCollection.BusinessEntities)
{
txtResults += pointer.subject + " : " +
pointer.description + " : " +
pointer.activitytypecode.Value.ToString() +
" : " +
pointer.statecode.ToString() +
Environment.NewLine;
}
MessageBox.Show(txtResults, "Activities");
}
}
catch (System.Web.Services.Protocols.SoapException err)
{
MessageBox.Show(err.Detail.OuterXml.ToString(), "Error");
}
So what is the big deal?
The problem I was having, was related to the formation of the Query field that is being passed to the Rollup message. Let's take the TargetRollupActivityPointerByAccount for example. This message has two fields: AccountId and Query.
It turns out that the Query field is a query on the Entity being rolled up, not on the parent Entity to which those records belong. In other words, given the above message, I would specify my Query parameters for the ActivityPointer Entity, not the Account Entity.
TargetRollupAnnotationByAccount works in a similar manner. We specify Query parameters for the Annotation Entity, not the Account Entity.
Once I understood that little fact, all of the other stuff made perfect sense.
Note: In the example above, we specify no expression filters so the query will return All of the activities.
Reference:
One of my customers is an association whose membership is subscription based ( like most associations ).
They have a business requirement to remove companies that have dropped their membership from the Accounts Entity and add them back to the Leads Entity ( with history, etc. ).
I am curious if others in my audience have a similar requirement to revert an Account and/or Contact back to a Lead. If you do, and you don't mind sharing, then I would like to know more about how and why your business ( or customer ) has such a requirement and how their process is implemented.
Just drop me a quick email: mitch (at) infinite-x (dot) net.
Thanks, Mitch
Or does he stick everything into the sleigh when he leaves the North Pole?
Just one of the questions that popped into my head yesterday.





