我们往往需要对运行报表时用户输入的参数进行验证,在检查到错误的的输入时弹出错误提示用户修正,要实现这个功能首先要区分报表使用的是哪种数据源,对于使用Query、Data method、OLAP数据源的报表可以通过扩展SrsReportRdlDataContract类来完成检查,而对使用report data provider为数据源的报表,则可以直接在data contract类中完成对报表参数的检查。
先来看第一种情况,实际在运行每一个报表时,AX都会创建一个SrsReportRdlDataContract类或者子类的实例,具体是在\Classes\SrsReportRunService\getReportDataContract()通过SrsReportRunRdlParser类得到的,后者的方法parseRdl()会解析报表的metadata来创建报表对应的SrsReportRdlDataContract类对象,下面我们能看到这是通过运用特性SrsReportNameAttribute来完成的,对于没有指定SrsReportRdlDataContract扩展类的报表则默认创建SrsReportRdlDataContract的实例。SrsReportRdlDataContract提供了一些方法来操作报表的参数,比如获取报表参数的输入值,SrsReportRdlDataContract实现接口SysOperationValidatable,在它的方法validate()完成对参数的验证。来看看系统自带报表Hcmi9DocumentExpireList的rdl contract类:
[ SrsReportNameAttribute('Hcmi9DocumentExpireList.Report'), SysOperationContractProcessingAttribute(classStr(Hcmi9DocumentExpireListUIBuilder)) ] class Hcmi9DocumentExpireListRdlContract extends SrsReportRdlDataContract implements SysOperationValidatable { #define.parameterFromDate('FromDate') #define.parameterToDate('ToDate') } public boolean validate() { boolean isValid = super(); // Check whether FromDate and ToDate parameters are getting values or not if(this.getValue(#parameterFromDate) && this.getValue(#parameterToDate) ) { // Check whether FromDate is greater than ToDate or not if (this.getValue(#parameterFromDate) > this.getValue(#parameterToDate)) { error("@SYS91020"); isValid = false; } } return isValid; }
需要做的工作就是从SrsReportRdlDataContract扩展自己的子类,使用特性SrsReportNameAttribute和报表联系起来,注意需要指定报表的设计名称,在随后的validate()中使用getvalue()得到报表参数的值进而进行验证。在上面的例子中还使用了SysOperationContractProcessingAttribute特性,由它指定一个SrsReportDataContractUIBuilder的扩展类,它所完成的工作类似于早先morphx报表runbasereport的dialog()和getfromdialog()方法完成的工作,手工创建报表参数提示对话框,以及从对话框获取输入的参数值,有兴趣的可以看看系统自带的Hcmi9DocumentExpireListUIBuilder类。
对于使用RDP作为数据源的报表,由于已经有了Data contract类,我们只需要在Data contract类上实现接口SysOperationValidatable并重载它的validate()方法就可以了,比如系统自带的AssetDueReplacementContract类:
[ DataContractAttribute, SysOperationContractProcessingAttribute(classStr(AssetDueReplacementUIBuilder)) ] public class AssetDueReplacementContract implements SysOperationValidatable { CurrentOperationsTax postingLayer; AssetReplacementDate dateFrom; AssetReplacementDate dateTo; Name dimension; NoYes includeSubTotal; } public boolean validate() { boolean isValid = true; if (!dateFrom) { isValid = checkFailed(strFmt("@SYS84753", "@SYS180311")); } if (!dateTo) { isValid = checkFailed(strFmt("@SYS84753", "@SYS180217")); } if (dateFrom > dateTo) { isValid = checkFailed(strFmt("@SYS300457", date2StrUsr(dateFrom, DateFlags::FormatAll), date2StrUsr(dateTo, DateFlags::FormatAll))); } return isValid; } ......
同样也可以在data contract类上通过SysOperationContractProcessingAttribute特性来指定自定义提示对话框的UI构建类,当然这不是必须的。
更多内容详见http://msdn.microsoft.com/EN-US/library/gg731942.aspx。