MS CRM 2011 如何嵌入Report Viewer
原创地址:http://www.cnblogs.com/jfzhu/archive/2012/12/27/2835098.html
转载请注明出处
在CRM 2011中,Chart与Report是两个很强大的数据统计的图形化工具,只有用好了Chart与Report才能发挥出CRM在数据统计方面的威力。我在前面的博客中演示了如何将Chart嵌入到Dashboard和Form中,本文中我再演示如何利用Report Viewer将Report嵌入到Dashboard与Form中。
(一) 将Report嵌入Dashboard中
CRM 2011中,创建Report有两种方式,基于SQL的Report与基于Fetch的Report。我在本文中以基于Fetch的Report为例,创建一个report,里边给出所有的account及order的TotalAmount。
使用的FetchXML定义如下:
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false"> <entity name="account"> <attribute name="accountid" /> <attribute name="name" /> <order attribute="name" descending="false" /> <link-entity name="salesorder" from="customerid" to="accountid" alias="aa"> <attribute name="ordernumber"/> <attribute name="totalamount"/> <filter type="and"> <condition attribute="totalamount" operator="not-null" /> </filter> </link-entity> </entity> </fetch>
Report的定义如下:
将report上传到CRM中,上传成功后,获得reportid为{7EC592B7-B14F-E211-B622-D48564531939}
然后我们创建一个web resource, new_ReportViewerDashboard.html
<html> <head> <title></title> </head> <body onload="submitForm()"> <script type="text/javascript" src="ClientGlobalContext.js.aspx"></script> <script type="text/javascript"> function submitForm() { var form = document.forms[0]; var context = GetGlobalContext(); form.action = context.getServerUrl() + '/CRMReports/rsviewer/reportviewer.aspx'; form.uniquename.value = context.getOrgUniqueName(); var query = window.location.search.substring(1); var vars = query.split("&"); var idSet = false; for (var i = 0; i < vars.length; i++) { var pair = vars[i].split("="); switch (pair[0]) { case 'data': var params = unescape(pair[1]).split("&"); for (var j = 0; j < params.length; j++) { var param = params[j].split("="); switch (param[0]) { case 'reportid': form.id.value = param[1]; idSet = true; break; case 'hideparams': form.PromptAreaCollapsed.value = param[1]; break; case 'iscustomreport': form.iscustomreport.value = param[1]; break; default: // Add any other values as report parameters var paramInput = document.createElement('input'); paramInput.setAttribute('type', 'hidden'); paramInput.setAttribute('name', 'p:' + param[0]); paramInput.setAttribute('value', param[1]); form.appendChild(paramInput); break; } } } } if (idSet) { form.submit(); } else { // Show message var dvMessage = document.createElement("div"); dvMessage.innerHTML = "Report Id is not set"; form.appendChild(dvMessage); } } </script> <form action="" method="post"> <input type="hidden" name="id" value="{xxx}" /> <input type="hidden" name="uniquename" value="" /> <input type="hidden" name="iscustomreport" value="true" /> <input type="hidden" name="reportName" value="Report Name" /> <input type="hidden" name="isScheduledReport" value="false" /> <input type="hidden" name="PromptAreaCollapsed" value="false" /> </form> </body> </html>
注意几点:
(1) 在body的onload事件中,直接将表单(Form)提交到Report Viewer(/CRMReports/rsviewer/reportviewer.aspx)中;
(2) 对ClientGlobalContext.js.aspx的引用。如果你的web resource命名为new_test/ReportViewerDashboard.html,那么引用就应改为../ClientGlobalContext.js.aspx
(3) 表单提交的方式必须为 post。
接下来创建一个新的Dashboard,并插入web resource new_ReportViewerDashboard.html
在对web resource的属性定义中,一定要在Custom Parameter(data)中填写进reportid,如下图所示
publish 之后,打开Dashboard看一下
如果你将web resource 的表单提交方式改为get(当然这样你就无法在dashboard中看到report了),你会看到提交到report viewer的URL为
https://aaronbabbitt.crm4.dynamics.com/CRMReports/rsviewer/reportviewer.aspx?id={7EC592B7-B14F-E211-B622-D48564531939}&uniquename=aaronbabbitt&iscustomreport=true&reportName=Report Name&isScheduledReport=false&PromptAreaCollapsed=false
(二) 将Report嵌入Dashboard中并使用自定义参数
如果嵌入dashboard的report使用了自定义参数该怎么办?下面我们创建一个report使用自定义参数ownerid,我们只获得ownerid等于参数值的account及order。Fetch的定义如下:
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true"> <entity name="account"> <attribute name="accountid" /> <attribute name="name" /> <order attribute="name" descending="false" /> <filter type="and"> <condition attribute="ownerid" operator="eq" uitype="systemuser" value="@ownerid" /> </filter> <link-entity name="salesorder" from="customerid" to="accountid" alias="aa"> <attribute name="ordernumber"/> <attribute name="totalamount"/> <filter type="and"> <condition attribute="totalamount" operator="not-null" /> </filter> </link-entity> </entity> </fetch>
同样将report上传到CRM中,获得reportid为{BD814A01-BB4F-E211-B622-D48564531939}。我的CRM用户systemuserid 为 {D608D786-8654-4933-9E7E-28B2950A382B}。
在Dashboard中再插入一次web resource new_ReportViewerDashboard.html,但注意这次web resource的属性与上面不同,在Custom Parameter(data)中,需要定义reportid, ownerid,以及hideparams(用来隐藏参数)。
reportid={BD814A01-BB4F-E211-B622-D48564531939}&ownerid={D608D786-8654-4933-9E7E-28B2950A382B}&hideparams=true
publish后看到结果如下:
(三) 将Report嵌入Form中并使用自定义参数
将report嵌入到form中,通常就意味着我们只想看到关于该entity的report。还以上面的report为例,我们使用一个entityid自定义参数,再报表中我们只显示accountid等于参数值的account及order。FetchXML定义如下:
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true"> <entity name="account"> <attribute name="accountid" /> <attribute name="name" /> <order attribute="name" descending="false" /> <filter type="and"> <condition attribute="accountid" operator="eq" uitype="account" value="@entityid" /> </filter> <link-entity name="salesorder" from="customerid" to="accountid" alias="aa"> <attribute name="ordernumber"/> <attribute name="totalamount"/> <filter type="and"> <condition attribute="totalamount" operator="not-null" /> </filter> </link-entity> </entity> </fetch>
同样将report上传到CRM中,获得reportid为{E13A5A3D-C04F-E211-B622-D48564531939}。
创建一个新的HTML web resouce,它与之前web resouce的不同之处在于对entityid的处理,具体看下面代码:
<html> <head> <title></title> </head> <body onload="submitForm()"> <script type="text/javascript" src="ClientGlobalContext.js.aspx"></script> <script type="text/javascript"> function submitForm() { var form = document.forms[0]; var context = GetGlobalContext(); form.action = context.getServerUrl() + '/CRMReports/rsviewer/reportviewer.aspx'; form.uniquename.value = context.getOrgUniqueName(); var query = window.location.search.substring(1); var vars = query.split("&"); var idSet = false; for (var i = 0; i < vars.length; i++) { var pair = vars[i].split("="); switch (pair[0]) { case 'id': var paramInput = document.createElement('input'); paramInput.setAttribute('type', 'hidden'); paramInput.setAttribute('name', 'p:entityid'); paramInput.setAttribute('value', unescape(pair[1])); form.appendChild(paramInput); break; case 'data': var params = unescape(pair[1]).split("&"); for (var j = 0; j < params.length; j++) { var param = params[j].split("="); switch (param[0]) { case 'reportid': form.id.value = param[1]; idSet = true; break; case 'hideparams': form.PromptAreaCollapsed.value = param[1]; break; case 'iscustomreport': form.iscustomreport.value = param[1]; break; default: // Add any other values as report parameters var paramInput = document.createElement('input'); paramInput.setAttribute('type', 'hidden'); paramInput.setAttribute('name', 'p:' + param[0]); paramInput.setAttribute('value', param[1]); form.appendChild(paramInput); break; } } } } if (idSet) { form.submit(); } else { // Show message var dvMessage = document.createElement("div"); dvMessage.innerHTML = "Report Id is not set"; form.appendChild(dvMessage); } } </script> <form action="" method="post"> <input type="hidden" name="id" value="{xxx}" /> <input type="hidden" name="uniquename" value="" /> <input type="hidden" name="iscustomreport" value="true" /> <input type="hidden" name="reportName" value="Report Name" /> <input type="hidden" name="isScheduledReport" value="false" /> <input type="hidden" name="PromptAreaCollapsed" value="false" /> </form> </body> </html>
然后在account的Form中插入该web resouce,web resouce的属性如下:
要注意需要勾选上 Pass record object-type code and unique identifier as parameter。
如果你感兴趣可以试着看一下传递给web resouce的参数为什么,alert(window.location.search.substring(1));
data=reportid%3d%7bE13A5A3D-C04F-E211-B622-D48564531939%7d%26hideparams%3dtrue&id=%7b55B16BF4-6219-E211-B112-3C4A92DBD80A%7d&orglcid=1033&orgname=aaronbabbitt&type=1&typename=account&userlcid=1033
我们看到有account的id,用户使用的语言,organization name等等。
最后看一下结果,只显示了当前form的account:
总结:本文介绍了如何将report嵌入到dashboard或者form中。基本的方法就是,先手动创建一个report(最好不要使用CRM生成的report),你可以为该report定义自定义参数,然后将report上传到CRM中。接下来再创建一个web resouce,web resouce中利用了body的onload事件处理,将表单提交到Report Viewer中去。在dashboard或者form中插入web resouce时,要注意对web resouce 属性的配置。