被抽调学习CRM两个礼拜,要回java组了,以后接触机会应该不多了。记录下这段时间的学习总结,以备不时之需。
通过微软提供的视频教程,基本上你想了解的一些很基础的问题,都能找到入口处,剩下的就是通过sdk和在各个论坛寻找解决方法了。
http://www.microsoft.com/china/msdn/events/webcasts/shared/webcast/Series/CRM.aspx
这个里面包含了的视频虽然不多,但老师都讲得很详细,对开发方面也有了相当篇幅的介绍。如plugin、ReportingService、workflow这些自定义开发都做了入门的基础介绍和例子。
学习圈子:
微软的CRM的圈子,目前我去得比较多的是google论坛上的Microsoft Dynamics CRM 3.0/4.0 微软客户管理系统。(:)因为会把所有我讨论关心的话题都发到邮箱中。)还有当然就是微软的官方论坛了。
这里面不得不提的几个人,刀客、darren liu 人都很不错呢,技术很牛,而且很热心,基本上都是有问必答。
好了,剩下的就是自己在学习过程中遇到的一些怪问题了
1.工作流突然不能使用。不知是不是与虚拟机迁移服务器有关,工作流不管设置如何的启动条件都无法运行。后来到了服务器上,查看日志发现,MSSQLSERVER审核失败。发现Microsoft CRM 异步处理服务的服务怪异的停止了。重新启动完后流程正常。在后面的3.0到4.0升级也发现了这个问题,把自己觉得相关的服务启动了后,也可以了。没有一个具体的说法,就是觉得很奇怪。
2.视图排序问题。看了Darren Liu的视图隐藏方式后,稍加修改,变成了现在的视图排序。目前自己还没有找到更好的对系统视图排序的方法,使用了一种很笨的方式来实现客户要求的视图排序顺序(通常客户提出的是按照他们的使用习惯来分类的,所以没有办法按照name来order)。
以下是实现方式。
public class ViewSort : IPlugin
{
#region IPlugin 成员
public void Execute(IPluginExecutionContext context)
{
if (context.InputParameters != null && context.InputParameters.Contains(ParameterName.Query))
{
QueryExpression qe = (QueryExpression)context.InputParameters.Properties[ParameterName.Query];
if (qe.EntityName == "savedquery")
{
if (qe.Criteria != null)
{
if (qe.Criteria.Conditions != null)
{
OrderExpression order = new OrderExpression("modifiedon", OrderType.Descending);
qe.Orders.Clear();
qe.Orders.Add(order);
context.InputParameters.Properties[ParameterName.Query] = qe;
}
}
}
}
}
#endregion
}
呵呵,看完代码,大家大概明白我是用了什么方式来实现自定义排序的吧。在 savedquerybase表中提供了修改时间的字段(modifiedon),大家如果要将视图位置往前排的话,只要让视图modify一下就可以了。主要是为了使当前的修改时间靠前而已。这个方法很笨,如果知道的朋友,希望能提出更简单的方式。
3.在之前的crm实践中说到,owner字段在更新后是无法捕捉onchange事件的。其实认真观察一下,在对商机选择完负责人后,系统直接对数据库进行更改,更新负责人。然后刷新页面重新加载商机。页面重新加载了,当然就没有什么onchange事件了。
在google论坛上,刀客提过可以通过assign message plugin来实现,但是我在做测试的时候发现,context.InputParameters.Properties["Target"]是Moniker。所以通过了TargetRetrieveDynamic来获得DynamicEntity对象。底下只是代码只是进行了update操作的测试。具体要实现选择更新,可以根据需要进行更改。
public class AssignUpdatePlugin: IPlugin
{
#region IPlugin 成员
public void Execute(IPluginExecutionContext context)
{
Moniker m = (Moniker)context.InputParameters.Properties["Target"];
if (m.Name == EntityName.opportunity.ToString())
{
ICrmService service = context.CreateCrmService(true);
TargetRetrieveDynamic targetRetrieve = new TargetRetrieveDynamic();
targetRetrieve.EntityName = m.Name;
targetRetrieve.EntityId = m.Id;
RetrieveRequest request = new RetrieveRequest();
request.ColumnSet = new AllColumns();
request.Target = targetRetrieve;
request.ReturnDynamicEntities = true;
RetrieveResponse response = (RetrieveResponse)service.Execute(request);
DynamicEntity entity = (DynamicEntity)response.BusinessEntity;
entity.Properties["description"] = "ss";
service.Update(entity);
}
}
#endregion
}
4.工作流实践:
待填充
5.报表实践: