润乾报表重复值列的两种计算排名方法

来源:互联网 发布:域名注册后怎么建站 编辑:程序博客网 时间:2024/06/05 02:04

需求背景:

对可扩展的单元格的值计算排名,可利用单元格集运算函数和$运算符实现。比如对扩展格A1格排序,可通过表达式=count(A2[`0]{A2>$A2})+1实现,即统计所有A1单元格值大于当前A1单元格值的单元格个数,然后加一,从而实现对A1单元格值排名的效果。

实现效果如下:


 

但是,如果A1单元格值中存在重复值,用上面的方式就会得到如下结果:对重复值项排名会相同,后续的数据项的排名会不连续。


 

基于上述场景,本文介绍其他的两种排序方法:

1.       重复值的单元格按行号递增排序,比如上例中值为8的单元格就应该由上到下排序2和3。

2.       重复值的单元格排名相同,后续的数据项排名保持连续递增。比如上例中值为8的两个单元格的排名均为2,值为6的两个单元格排名为3而不是4。

 

排序方式一实现:

 

报表模板设计如下:


A2为待排序单元格,其中为模拟的含有重复值的一组数据。表达式:=list(1,5,5,5,6,6,8,8,9)

B2表达式:=count(A2[`0]{A2>$A2})+1,统计所有A1单元格值大于当前A1单元格值的单元格个数。

C2表达式:=row(),取得当前单元格所在行的行号。

D2表达式:=B2+count(A2[`0]{B2==$B2&&C2<$C2}),其中count(A2[`0]{B2==$B2&&C2<$C2})统计和当前B2单元格值(排名)相同且行号小于当前行的A2单元格数。那么D2表示用初始计算得到的排名加上比自己行号小且值重复的单元格数。

最终效果:


黄色区域为待排序列和最终不重复递增排序结果。可根据具体情况隐藏中间两列。

 

排序方式二实现:

实现思路:

用自定义函数实现统计值不同的单元格集的单元格数目。再利用该自定义函数统计满足小于当前格值的不重复单元格数,然后加一,从而实现对A1单元格值排名的效果。

具体实现:

1.自定义函数:

报表提供了自定义函数接口,继承function类或者DSFunction类,实现其中的calculate方法,并返回运算结果。如果在模板中使用自定义函数还需进行函数登记,在java的类路径的config目录下,找到customFunctions.properties文件,并在其中进行自定义函数类及函数名的登记。

  • 自定义函数类实现:

public class count2 extends Function {

         public Object calculate(Context arg0, boolean arg1) {   

             //报表中调用该函数传递过来的参数列表

                   if ( this.paramList.size() == 0 ) {

                            throw new ReportError( "count2函数参数列表为空" );

                   }

                   //取得计算表达式(得到传递给报表的参数)

                   Expression param1 = ( Expression )this.paramList.get( 0 );

                   if ( param1 == null ) {

                            throw new ReportError( "count2函数出现无效参数" );

                   }

                  

                   //==================================================================

                   //运算表达式,并取得运算结果(Object)

                   Object result1 = Variant2.getValue( param1.calculate(arg0,arg1),false,false );

        if( result1==null ) return ObjectCache.getInteger( 0 );

                   if ( result1 instanceof List ) {

                            //如结果为List,求得List中保存不同对象的个数

                            List list = ( List ) result1;

                            Hashtable ht = new Hashtable();

                            Iterator it = list.iterator();

                            for(;it.hasNext();){

                                     ht.put(it.next(),"");

                            }

                            //返回实际的不同值中的人数

                            return ObjectCache.getInteger( ht.size() );

                   }

        return ObjectCache.getInteger( 1 );

        //===================================================================

         }

}

  • 自定义函数登记:

    将编译好的类文件(.class)分别拷贝到java类路径下(\报表安装路径\ \webappsdemo\WEB-INF\classes\和\报表安装路径\designer\web\WEB-INF\classes\,前者为服务器端,后者为设计器端),分别进行服务器端和设计器端自定义函数登记,在java的类路径的config目录下,找到customFunctions.properties文件(服务器端: \webapps\demo\WEB-INF\classes\config\customFunctions.properties;设计器端:\designer\web\WEB-INF\classes\config\customFunctions.properties),登记如下:

#用户自定义函数在此添加

#格式: 函数名 = 函数类型(0:普通函数,1:数据集函数), 类名称

count2=0,com.count2

2.报表模板设计:


A2为待排序单元格,其中为模拟的含有重复值的一组数据。表达式:=list(1,5,5,5,6,6,8,8,9)

B2表达式:=count2(A2[`0]{A2>$A2})+1,统计所有A1单元格值大于当前A1单元格值且单元格值不重复的A2单元格个数。

 

最终效果:



0 0
原创粉丝点击