Skip to main content

 路由器设置 > 新闻资讯 >

crystal report水晶报表无法实现的多数据源计算

2014-01-23 22:25 浏览:

 最近帮用户解决了一个crystalreport多数据源计算的问题。由于计算过程有一定的复杂性,依靠报表工具自身的功能很难实现。

  项目背景:用户新上线了绩效考核系统,原本的工资算法需要相的调整。以前的工资表主要由员工的基本工资计算得到,基本工资存储在财务管理软件的MSSQL数据库中。新的工资表由基本工资+绩效工资组成。绩效工资由绩效分数计算得出,而绩效分数存储在绩效考核系统的Oracle数据库中。显然,新的工资表需要两个数据库的跨库计算才能得到。

   具体的绩效工资算法比较复杂。首先,不同的岗位算法不同。有些岗位是根据基本工资的区间来计算的,而有些岗位不需要按区间来计算。有些岗位只是单纯的用绩效来计算,而有些岗位要考虑绩效和工龄双重因素。还有些岗位有绩效得分但没有绩效工资。其次,同样是按基本工资区间来计算绩效的岗位,不同的岗位其区间划分方法、每个区间内的具体算法也有不同。最后,所有的员工工资要合并为一张报表。

   为了便于理解,这里将算法大幅简化,并去掉交税的影响,岗位也简化为2个:normalsalesNormal有绩效得分但没有绩效工资,其税前工资=基本工资。sales的税前工资=基本工资+绩效工资。其中绩效工资是这样算的:

   (1)基本工资2000以下的:基本工资*(绩效得分/100);

   (2)基本工资在20004000的:基本工资*((绩效得分*0.9)/100);

   (3)基本工资在4000以上的基本工资*((绩效得分*0.8)/100);

 

   可以看到,要计算完整的工资表,需要将MSSQLemployee表按照岗位分成多份(简化后是2份),每份数据单独计算出税前工资,最后再将不同岗位的税前工资合并起来。两种岗位的算法不同,岗位是sales的需要关联Oracle中的performance表,其税前工资需要按不同的区间分别计算。而岗位是normal不需要做这种关联计算。

   这张报表的难点在于:一、employeeperformance分属不同的数据库,需要跨库计算。二、算法较复杂,仅将两张表简单地关联起来是无法实现目标的。

   跨库计算最理想的解决方案是依靠报表工具。如果报表工具能在一张报表中处理两种数据源就可以实现“报表层跨库”。但Crystal report处理多数据源的办法很复杂,实现成本不低。而且报表工具也只能提供简单的内外关联,难以处理这种循环中判断以及多结果集合并的复杂算法。

   报表工具无法解决这种问题,只能从报表之外寻求解法。事先ETL到一个库里显然不是个好办法,一方面ETL开发成本太高,另一方面还有数据同步和实时性的麻烦。自定义数据源可以解决这个问题,而集算器可以很好地为报表工具提供自定义数据源。

wKiom1LgbNaQC5tJAAKLbWTuGJk686.jpg

上述代码很容易解读。

  A1、A2:分别从ORACLEMSSQL取数据。

  A3:employee加一个空列preTax,用来存储将来的税前工资。

  A4、A10:从employee分别取出岗位是salesnormal的数据。由于后期要合并,用业务名引用比较方便,因此这两部分数据分别定义为salesnormal。当然,A3这种临时的计算结果并没有额外定义变量,而是直接在A4中按格名来引用A3。类似的还有A5中引用A1

  A5-C9:计算sales的税前工资。其中A5是关联计算,将sales的基本工资和绩效分数关联了起来。A6C9是个循环,将sales逐条循环判断,按不同区间不同算法来计算税前工资。这里需要注意三点。一是循环体是用缩进来表示的,B7-C9都是循环体。二是循环变量就是for所在的单元格,即A6。循环体中可以用A6来表示当前记录。三是A6.empID.score的用法,这是对象的引用方式。这表示当前记录A6empID字段所关联的记录(即performance中的记录)的score字段,即当前员工的绩效分数。

   A11:直接将normalpreTax赋值为baseSalary

   A12将不同岗位的计算结果合并起来。当然,实际的算法中远不止两种岗位,每种岗位的税前工资算法也比示例中复杂。

   A13:从A12中挑选一些需要输出的字段。

   A14:以JDBC的形式输出A13,以便JAVA代码或报表工具通过JDBCURL直接调用。可以看到,这实际上这也是一种将多数据源合并为单数据源的方法,只是Crystal的数据源关联过于简单,无法实现这种过程性的跨库计算罢了。

   

   可以看到,Crystal report中的这个跨库的问题被轻松解决了。另外Crystal report会把集算器当作MSSQLOracle这样的数据库来调用,配合起来也很容易。