润乾报表教程

润乾报表V4.0 高级教程

北京润乾信息系统技术有限公司

第1章 序言

中国式报表有别于西方报表,中国式报表很复杂!

润乾报表是专门用于解决中国式复杂报表的报表工具!

润乾报表软件的核心特点在于开创性地提出了非线性报表数学模型,采用了革命性的强关联语义模型、多源关联分片、不规则分组、自由格间运算、行列对称等技术,使得复杂报表的设计简单化,以往难以实现的报表可以轻松实现,避免了大量的复杂SQL编写与前期数据准备,报表设计的效率提高了一个数量级。

润乾报表采用JAVA开发,由两个部分构成:报表设计器和报表服务器。

润乾报表是一个很容易掌握的报表工具,对于复杂的中国式报表,完全不需要编程和复杂sql,只需要学习简单的表达式规则,就可以完成。

为了帮助读者快速掌握润乾报表的非线性模型用法,我们在《快逸报表V4.0入门教程》的基础上编写了这份《润乾报表V4.0高级教程》,希望读者先学习《快逸报表V4.0入门教程》,再来学习这份文档,效果更好。

本教程沿袭《快逸报表V4.0入门教程》的思路,避免复杂的概念,通过由浅入深的实例,深入浅出的讲解,辅以有针对性的练习题,一步一步帮助读者迅速掌握润乾报表的非线性报表模型的理论和操作。只要你照着本教程去做,半天就可以初步掌握润乾报表。

希望在轻轻松松的过程中,你能很快地掌握非线性报表设计!

第2章 多源关联分片

这份文档的思路,不再强调界面操作上的东西,比如某个按钮在哪里点,某个对话框怎么打开,更多地强调表达式怎么写,模型的原理是啥,表达式的规则是啥,用到的函数等

2.1 多层交叉报表 2.1.1

一个例子

我们先看下面这个多层交叉报表:

[截图]

从上面这个报表可以看出,这是一个多层的交叉报表,上边有两层动态横向扩展的上表头,左边有两层动态纵向扩展的左表头,中间的交叉点进行汇总统计,统计值和上表头、左表头息息相关。我们看一下这样的报表在润乾报表中是如何设计的:

1、 首先定义数据集:

[列出这个报表用到的数据集及其sql即可]

2、 写入单元格表达式,如下图所示:

[设计界面截图,把格子拉大,表达式尽量看全]

从上图可以看出,上表头分别通过[ ]格和[ ]格横向扩展形成,左表头通过[ ]格和[ ]格纵向扩展形成,中间的交叉点利用[sum]函数进行汇总,于是一个多层交叉报表很轻松就完成了。

这个例子用到了非线性报表模型中的扩展模型以及主格和附属格的模型,介绍如下:

2.1.2 扩展模型

扩展单元格:

当单元格的数据值表达式为集合表达式时,该单元格默认为可扩展单元格。可以为扩展单元格设置一个扩展方向,扩展可以有横纵两个方向,即横向扩展和纵向扩展,但一个扩展格同时只能有一个扩展方向。

横向扩展:

当可扩展单元格的扩展方向为横向时,该单元格进行的扩展称为横向扩展。此时该单元

格会横向进行复制,复制出的单元格的数据值依次为表达式的结果数据值,表达式返回几个值,单元格就复制几个。

复制出来的新单元格的所有属性都引用被复制单元格的属性;

纵向扩展:

当可扩展单元格的扩展方向为纵向时,该单元格进行的扩展称为纵向扩展。此时该单元格会纵向进行复制,复制出的单元格的数据值依次为表达式的结果数据值,表达式返回几个值,单元格就复制几个。

复制出来的新单元格的所有属性都引用被复制单元格的属性;

不可扩展:

当单元格的数据值表达式为单值表达式时,该单元格默认为不可扩展单元格。

2.1.3 主格模型

主格和附属格:

单元格进行扩展的过程中,缺省情况下,相对于其右(下)边的单元格而言,扩展格是主动复制的,被称为其它格(其右/下的格)的主格,而其右(下)的单元格是被动跟随复制的,被称为扩展格的附属格或子格。主格和附属格是相对的概念,即某格是另一格的主格或附属格,不存在单独的主格和附属格。

从主格的定义中看,显然只有扩展格才能是其它格的主格!

要注意的是,在缺省情况下,扩展格左(上)的格并不是其附属格,只有右(下)的格才是其附属格。

特别地,某个单元格的主格属性可以人为被改变。

左主格和上主格:

单元格进行纵向扩展时,我们又称其为其它格(其右/下的格)的左主格,而横向扩展时则称为上主格。一个单元格可以既有左主格又有上主格。 特别地,某个单元格的左主格或者上主格属性可以人为的被改变,即可以人为的把某个纵向扩展格右边的单元格设为他的左主格,或者把某个横向扩展格下方的单元格设为他的上

主格。

多层扩展:

多个单元格同时进行扩展时,一个扩展格可以既是某些格的主格又是另一个扩展格的附属格,这种情况下就形成多层扩展的情况。如果主格A1的附属格是B1,而B1还有附属格C1,那么B1称为A1的1级子格(或1级附属格),C1称为A1的2级子格(或2级附属格),同时A1称作B1的1级主格,A1称作C1的2级主格。如果C1再有附属格D1,那么A1是D1的3级主格,而D1是A1的3级子格。显然,B1是D1的2级主格,D1是B1的2级子格。

同一行(列)上有两个或更多的扩展格。左(上)边的扩展格将是右(下)边的扩展格的主格,右(下)边的扩展格是其左(上)边扩展格的附属格,同时又是其右(下)边单元格的主格。

图示:

[把这个图改一下,改成to(1,3)……]

直接主格和直接附属格:

单元格进行多层扩展时,若主格A的附属格B不再有任何同方向的主格是该主格A的附属格,则称B为A在该方向上的直接附属格,也称为一级附属格;反之,A称为B的直接主格,也称为一级主格

扩展变化规则:

多层扩展时,扩展次序是从主到次的,即先扩展主格,然后扩展其附属格,再扩展其二级附属格,依此类推。

单元格进行横向扩展时,会将其同列的上主格拉大,把其附属单元格复制,特别地,如果其某个上主格不在同列上,则该上主格不会被拉大;

单元格进行纵向扩展时,会将其同行的左主格拉大,把其附属单元格复制,特别地,如果其某个左主格不在同行上,则该左主格不会被拉大。

一般地,主格能够主动进行扩展复制,称为主动扩展格;附属单元格被主单元格带动着复制,称为被动复制格。由于附属单元格同时又可能是别的单元格的主格,本身还可以进行主动扩展复制,因此主动扩展格和被动复制格是相对的。既不能主动扩展复制,也不能被动复制的单元格,我们称为不可复制格,或者叫固定格。

同一报表中可能同时有纵向扩展格和横向扩展格,如果它们的子格有重叠部分,则这些子格就即有左主格又有上主格,在扩展时会被即向下又向右复制,形成一片矩形单元格区域,从而做到交叉扩展。相应地,在这种机制下,多层交叉也不难实现。

在交叉扩展中,有的单元格有可能既被横向扩展向右复制,也被纵向扩展向下复制,可

是,单元格的横向扩展与纵向扩展这两种扩展是相互独立的,既可以先进行横向扩展,也可以先进行纵向扩展,并不会影响扩展之后的结果。

例3.3.2-2:

[把这个图改一下,改成to(1,3)……] 例3.3.2-3:

[把这个图改一下,改成to(1,3)……] 例3.3.2-4:

[把这个图改一下,改成to(1,3)……]

例3.3.2-5:

[把这个图改一下,改成to(1,3)……]

2.2 纵向分片

现在,我们把2.1.1中的报表做一些改变,首先,我们在原有数据集的基础上增加如下数据集的定义: [列出增加的数据集及其sql即可]

然后在报表下方追加一行,增加一个纵向扩展格,如下图所示:

[截图,注意:新增加的这一行换一种比较浅的背景色,以示区别]

该报表的预览效果如下图所示:

[截图]

从上图可以看出,该报表出现了两片纵向扩展区域,这两片纵向扩展区域看起来毫无关系,但是格线严格对齐。下面我们对这个报表继续做改变,在新增加的行中写入计算表达式,如下图所示:

[截图]

[ ]格中的表达式为: 其含义是: ;可以看出,这个表达式既和上表头[]格有关联,又和左表头[]格有关联,我们再看一下预览效果:

[截图]

从上图可以看出,上下两片本来没有关系的扩展区域,通过[]格的表达式和上表头[]格关联起来,变成了上下两片紧密关联的扩展区域。

2.3 横向分片

[参照纵向分片的写法,在2.2的报表基础上继续做变化]

2.4 扩展区域与静态区域混合

[参照前面的写法,在2.3的报表基础上继续做变化,横向纵向分别增加静态列]

2.5 行列对称

从前面的几个例子可以看出,润乾报表横向扩展横向分片的能力和纵向是完全对称的,中国式报表中,经常出现类似的需求。

行列对称的能力不仅仅体现在扩展和分片的能力上,还体现在左表头固定,表体横向滚动以及横向分页时左表头每页重复的能力上。

就拿2.4中的报表例子来说,该报表横向已经很宽了,浏览的时候很可能屏幕不够大,需要固定左表头,横向滚动着浏览才方便;打印的时候,一张A4纸也肯定容不下这么宽的报表,只能横向分页,分页的时候左表头很可能需要重复,此时如何实现?

下面看一下润乾报表中的做法: [……]

1、 设置左表头

2、 在tag中设置固定表头属性 3、 。。。。。。

2.6 多片扩展 2.6.1

一个例子

我们看下面这个报表:

[截图,单表式主子表的效果图]

这是一个很常见的主子报表,主表和子表往往存储在不同的物理表中,而且通常是一对多的关系。在一般的报表工具中,这种报表往往利用专门的子表控件来实现,虽然功能实现了,但是存在的缺点是:主子表之间不容易共享数据,不容易进行表间数据的运算。润乾报表利用其多源关联分片模型,很轻松地在单个报表中实现了主子表的功能。下面我们介绍一下该报表的制作方法: [

1、 定义数据集:

2、 定义单元格的表达式 3、 设置左主格属性

4、 …… ]

这个例子中,我们发现,左主格是人为指定的,并不是缺省的,这用到了润乾主格模型中的主格认定规则,主格的认定包括缺省认定和人为认定,下面我们对该理论进行介绍:

2.6.2 主格认定规则

缺省主格认定

单元格横向扩展时,上方横向扩展单元格缺省为它的上主格,下方单元格缺省为它的附属格;如果上方没有横向扩展格,则上主格缺省为 `0 格

单元格纵向扩展时,左边纵向扩展单元格缺省为它的左主格,右边单元格缺省为它的附属格;如果左边没有纵向扩展格,则左主格缺省为 `0 格

人为改变主格规则

除了上面提到的缺省情况外,我们允许人为地改变单元格的主格。可以将某个单元格的左主格设置成某个纵向扩展格、上主格设置的某个横向扩展格,左主格和上主格是分别设置的。

为了符合扩展变化的规则,我们可以知道人为设置主格需要满足一些条件:

 左主格必须是纵向扩展格,上主格必须是横向扩展格,否则设置无效。

 不允许出现循环设置的情况,即设置A的主格是B,B的主格是C,C的主格又是A,

出现循环设置时认为设置有误,报表无法计算。显然,在缺省的情况下是不可能出现循环设置的,而在人为设置时必须避免这种情况的出现。

 横向扩展格不允许有左主格,纵向扩展格不允许有上主格。

人为设置时,可能发生左(上)主格在右(下)边的情况,而且主格也不一定和附属格在同一行(列)上。

例3.3.2-1:

2.7 多源关联分片的概念与特征总结

从前面的报表例子,我们可以总结出多源关联分片的概念:

多源是指一个报表的数据来源来自多个物理数据表(或类似数据体),甚至是多个物理数据库。这里的“多个”常常不是两个三个,而是七八个乃至十几个。

多源往往带来分片,正是由于分片,使得报表设计必须直接基于多源进行,而不能先将多源转成单源进行。有相当一部分分片报表无论如何也不可能转化成单源处理,部分能转成单源的报表处理也非常繁琐。

分片是指报表的纵向或横向或双向同时被分成了多个区域,每个区域独立扩展或者其中一个扩展区域为另一个扩展区域的子扩展区域,也可能是扩展区域和静态区域的混合。

关联是指不同的扩展区域或者扩展与静态区域之间,数据存在着关联,不同区域之间的数据还可能进行运算。

第3章 不规则分组

3.1 分组报表 3.1.1

一个例子

我们先看下面这个分组报表:

[截图,单层的分组报表即可,找个按地区分组的报表,后面的例子比较好演变]

从上面的这个报表可以看出,这是一个分组报表,左边按照[ ]维度进行了完全的分组,整个报表被分成 [列举组名,例如日用品、饮料、海鲜等] 等[n]组,我们看一下这样的报表在润乾报表中是如何设计的:

1、 首先定义数据集:

[列出这个报表用到的数据集及其sql即可]

2、 写入单元格表达式,如下图所示:

[设计界面截图,把格子拉大,表达式尽量看全]

从上图可以看出,该报表最关键的是[]格和[]格,其中[]格利用group函数对数据集进行了分组,并把分组结果在报表中进行纵向扩展,[]格利用select函数把当前组的记录取出来进行纵向扩展。

这个例子用到了group函数和select函数,下面我们做一下介绍:

3.1.2 group()

函数说明: 根据分组表达式,从数据集中选出一组组集。

语法: datasetName.group( , , )

//适用于不需要排序或数据集中已排好序

datasetName.group(selectExp{,descExp{,filterExp{,sortExp{,groupSortExp{,groupDescExp{,rootGroupExp}}}}}})

参数说明: selectExp 选出的分组表达式,可以是字段列名/列号,也可以是表达式。列号 用#n表示,例如#0代表第0列,#1代表第1列,依此类推

descExp 分组前记录的排序顺序,true为逆序,false为顺序 filterExp 过滤表达式 sortExp 分组前记录的排序依据表达式 groupSortExp 分组后对组的排序表达式,一般是汇总运算的表达式,如组合计等 groupDescExp 组排序顺序,true为逆序,false为顺序 rootGroupExp 是否root数据集表达式

返回值: 一组数据的集合,数据类型由selectExp的运算结果来决定 示例: 例1:ds1.group(class) 把数据集ds1中所有记录按照class字段进行分组,并返回每组的class值组成的集合 例2:ds1.group(class, true ) 把数据集ds1中所有记录按照class字段降序排列,然后根据class进行分组,并返回每组的class值组成的集合 例3:ds1.group(class,false,sex=='1') 从数据源ds1中选取性别为"1"的记录,按照class字段升序排列,然后根据class进行分组,并返回每组的class值组成的集合 例4:ds1.group(class, true, sex=='1', id ) 从数据源ds1中选取性别为"1"的记录,按照id字段降序排列,然后根据class进行分组,并返回每组的class值组成的集合 例5:ds1.group(省份,true,,,sum(工业产值),true) 对数据集ds1按照省份进行分组,分组后求出每组的sum(工业产值),然后按照这个汇总值对组进行逆序排列

●注意

group函数是对数据集按照某个字段或者表达式进行分组,获得一组组的集合,然后从每组中取出一个指定字段或者表达式的值,放到单元格中进行扩展,扩展出来的每个单元格都保留了一个指针指向当前的组集,该组集称为当前组。 因此在附属单元格中,需要对该组集进行操作时,不需要用任何条件和主单元格关联了,如果加设了条件,反倒画蛇添足,导致报表引擎还对组集中的记录进行遍历检索。

正确的group 用法:

不合理的group用法:

[把上面的截图改一下,a3改成A3]

group函数的原理图示:

3.1.3 select()

函数说明: 从数据集的当前行集中选取符合条件的记录 语法: datasetName.select( {, desc_exp{, filter_exp{, sort_exp{,rootGroupExp}}}} ) datasetName.select( , , )//适用于不需排序或数据集中已排好序 参数说明: select_exp: 要选择的字段列名/列号,,也可以是表达式。

列号用#n表示,例如#0代表第0列,#1代表第1列,依此类推 desc_exp: 指定数据排序的顺序,true表示降序排列,false表示升序排列。 filter_exp: 数据过滤表达式,如果全部选出,则此参数省略,仅用“,”占位。 sort_exp: 数据排序表达式。当此项为空时先检查desc_exp是否为空,如果为空,则不排序,否则使用select_exp排序。 rootGroupExp 是否root数据集表达式 返回值:

一组数据的集合,数据类型由select_exp的运算结果决定 函数示例: 例1:ds1.select( name ) 从数据源ds1中选取name字段列的所有值,不排序 例2:ds1.select( #2, true ) 从数据源ds1中选取第二个字段列的所有值并降序排列 例3:ds1.select( name,false,sex=='1') 从数据源ds1中选取性别为男性('1')的name字段列的值并升序排列 例4:ds1.select( name, true, sex=='1', id ) 从数据源ds1中选取性别为男性的name字段列的值并按id字段降序排列

●注意

使用select函数时,相当于从数据集中取出一组符合条件的记录集合,在单元格中进行扩展,此时每个扩展出来的单元格都保留一个指针,指向当前记录,即当前行,因此在这些单元格的附属单元格中,应当直接用“数据集名.列名”来引用同一个数据集同一条记录的值,此时报表引擎不需要对数据集进行检索遍历了,而是直接从当前行中取值。

图示:

典型的select用法:

不合理的用法:

3.2 不完全分组

我们把3.1中的报表做些变化,不要把所有的记录用于分组,因为某些组用户并不关心,我们仅仅保留[……..]这几个组,把剩余的组全部归并成一组,命名为“其他”,报表样式如下图所示:

[结果报表截图]

这种仅仅对数据集中的部分记录进行分组的报表,我们称为不完全分组报表。

这种不完全分组的报表,不能简单地用sql中的过滤条件来实现,因为剩余没有参与分组的记录也要在“其他”组中进行统计,而不是sql中过滤掉就行了。

看看润乾报表中如何实现这样的报表: [

1、 定义数据集

2、 定义单元格属性和表达式 3、 预览 ]

●说明

可以看出,润乾报表处理这种问题很巧妙,润乾报表提供的select和group函数均带有过滤条件参数,可以在进行选出或者分组的时候,过滤掉无关的记录,仅仅对部分记录进行分组。之后还可以对同一个数据集重复进行多次的分组或者选出、汇总操作,从而可以实现很复杂的分组报表。参见函数说明[此处加上超链接]

3.3 归并分组

如果把3.1中的报表做些变化,变成下面的报表,该如何做呢?

[结果报表的截图]

该报表和3.1的报表很类似,所不同的是分组规则发生了变化,把[]组和[某某]组合并成了一组,组名改成[];……

这种人为地把某几组合并成一组,且合并规则并无规律,需要逐组枚举的报表,我们称为归并分组的报表。

下面我们看看该报表在润乾报表中如何设计:

[设计界面截图,把格子拉大,表达式尽量看全]

从这个报表可以看出,核心部分在[]格,利用enumGroup函数代替了group函数,下面我们看一下该函数的介绍:

3.3.1 enumGroup

函数说明: 根据表达式的不同计算结果,返回不同的值,然后按这些值进行分组。本函数:从左到右计算,先出现的表达式先算,如果出现满足的表达式,则返回相应的结果,后面的不再计算。如果没有一个表达式满足条件,而且有缺省值表达式,则返回缺省值,否则返回null。

语法:

ds.enumGroup({hasNullGroup{,termExp1,resultExp1{,term2,resultExp2{,...{,defaultExp}}}}})

参数说明:

hasNullGroup 布尔表达式,true返回空组,false不返回空组 termExp(n) 条件表达式 resultExp(n) 返回结果表达式 defaultExp 缺省值表达式,如果所有表达式结果都不满足,则返回本表达式计算结果

返回值: 一组数据的集合,数据类型由resultExp1的运算结果决定 函数示例:

例1:ds1.enumGroup(true,类别ID==1 or 类别ID==3,"副食品",类别ID==6,"肉类","其他")

将数据集中满足类别ID==1 or 类别ID==3的记录归到“副食品”组中,满足类别ID==6的记录归到“肉类”组中,其他的记录归到“其他”组中

3.4 重叠分组 3.4.1

一个例子

我们把3.2中的报表继续做变化,如下图所示:

[截图,把3.2的报表变成含有“其中:”的报表]

图上可以看出,[]组中的一部分记录被拎出来在[其中:…..]组中进行了重复的统计,便于用户一目了然,既了解总的统计数据,又了解[其中:….]的统计数据,这种同一部分记录在不同组中被重复统计的分组报表称为重叠分组报表。

下面我们介绍一下润乾报表中如何实现该报表: [

1、 定义数据集

2、 定义单元格表达式

3、 看设计界面截图[尽量能在图上看清单元格表达式] ]

从上述介绍可以看出,重叠分组的关键在于[]格的表达式发生了变化,用overlap函数代替了enumGroup函数,下面我们介绍一下overlap函数的用法: 3.4.2

overLap

函数说明:

对每一条记录依次计算条件表达式,如果满足则把该条记录加入到相应的组里。如果有多个组满足,则这些组中都会含有此条记录。如果都不满足并且有缺省值表达式,则把该条记录加入到缺省组中。组值为以该组的第一条记录计算结果表达式所得到的值。

语法:

ds.overlap({hasNullGroup{,termExp1,resultExp1{,term2,resultExp2{,...{,defaultExp}}}}}) 参数说明:

hasNullGroup 布尔表达式,true返回空组,false不返回空组 termExp(n) 条件表达式

resultExp(n) 返回结果表达式 defaultExp 缺省值表达式,如果所有表达式结果都不满足,则返回本表达式计算结果

返回值: 一组数据的集合,数据类型由resultExp1的运算结果决定

函数示例: 例1:ds1.overlap(true,货主地区=="华北","华北",货主城市=="北京"," 其中:北京",货主地区=="华南","华南",货主地区=="华中","华中","其他") 把数据集中满足“货主地区=="华北"”的记录归到"华北"组中,满足“货主城市=="北京"”的记录归到" 其中:北京"组中,满足“货主地区=="华南"”的记录归到"华南"组中,满足“货主地区=="华中"”的记录归到"华中"组中,剩余的记录归到"其他"组中。

3.5 条件分组

利用enumGroup函数,设计一个比较复杂的条件分组的报表,每一组的条件均不相同,没有规律,写法参照前面的章节,采用设问、解答、总结的思路

例如ds1.enumGroup(true,类别ID500,"组2",”quantity

3.6 按段分组

参照前面的章节

3.7 不规则分组概念与特征总结

不规则分组是中国复杂报表中的典型特征之一。

不规则分组是相对于传统报表工具中的规则分组而言的,传统工具中的数据分组延用了关系数据库中的相应概念,为完全规则分组,即分组标准一致且有规则(一般都按某个字段或表达式),所有事实都必须出现且只出现一次,分组值次序与原数据记录次序一致。

不规则分组的分组标准看不出规律(常常只能穷举,或者写复杂的条件表达式,每一组的条件表达式均不相同,见3.5的例子),所有事实不一定全部出现在分组结果中、个别事实还可能重复出现,次序也与原数据记录无关。

第4章 动态格间运算

对于拿excel设计出来的静态报表(行数列数固定),行间、列间甚至组间的运算都不存在任何问题,可是对于传统报表工具设计出来的浮动行列(行列数不定,动态扩展)的报表,行间、列间、尤其是组间运算就很头痛了。请看下例:

4.1 占比报表

[占比报表设计界面与预览界面截图,用箭头指示预览效果,占比那一列仅仅写标题,表达式先空着]

这是一张比较典型的浮动行(行数不定,动态扩展)的报表,如果要计算占比该怎么办?所谓的占比运算,就是拿每一行的数值除以所有行的合计值,因此,我们要先把合计值算出来,做法是: [

1、 追加一个空行

2、 在空行处写入表达式,算出合计值 3、 设计界面截图 4、 预览截图 ]

[可以看到合计值出来了,此时我们再加上占比的表达式,……]

●说明

这是一个比较简单的行间运算例子,该例子要求报表引擎在解析报表时,能够先解析表达式,判断出[]格的占比表达式用到了[]格,从而先计算[]格,然后再计算[]格。

对于很多引用第三方表达式解析器(如BeanShell)的报表工具来说,就无法智能的判断运算优先级了。因此,对于那类报表工具来说,看起来很简单的占比报表,实现起来却很麻烦。

4.2 累积报表 4.2.1

一个例子

先看下面的报表:

[截图,参照占比的做法,累积报表的设计界面和预览界面的截图,用箭头指示预览过程,

累积那列的表达式空着,仅仅写上标题]

这是一个很简单的网格式报表(参照《快逸报表V4.0入门教程》中[第几章]的介绍),现在需要在这个报表中增加累积的计算表达式。所谓的累积,就是从第一行起累加到当前行的数值之和,这里我们需要进行累积计算的是[ ]列,该怎么做呢?

分析:对第一行来说,[]格的值==[]格,对第二行来说,[]格的值==第一行的[]格+第二行的[]格,对第三行来说,……

结论:累积值=上一行的累积值+当前行需要被累积的值

问题:如何在单元格表达式中表示“上一行的累积值”?从图[ ]可以看出,在设计状态,只有一行单元格,[]格只有一个,扩展后变成了很多行,变成了很多个[]格,因此,在设计状态下要描述扩展后的[]格,是比较困难的。

解决:润乾报表提供了位移坐标的表示法,可以很轻松地描述这种关系,参见[。。。加超链接]。在这个例子中,[]格的表达式可以写成[=……],如下图所示:

[截图,加上累积计算的表达式]

预览效果:

[截图,预览后的截图]

4.2.2 位移坐标的简单写法

在没有复杂的主格关系的报表中,位移坐标的简单表示法如下:

语法:

Cell[±n] 说明:

表示当前格Cell往上位移n格或者往下位移n格,其中+代表往下位移,-代表往上位移

举例: [画图来说明]

4.3 比值报表 4.3.1

一个例子

我们看下面这个报表例子:

[报表设计截图和预览截图,用箭头指示,报表的样子大概如下所示,记录按照销售额从大到小排列,和第一名的差距表达式空着,只写标题

名次 销售 销售额 和第一名的差距 ]

这个报表中,和第一名的差距这个指标的运算逻辑是:当前销售的销售额/第一名的销售额

从上图中可以看出,[]格的表达式最关键的在于如何表达出“第一名的销售额”,该报表是按照销售额从大到小排列的,因此第一名的销售额肯定是第一个[]格。如何在报表扩展前在表达式中描述出扩展后的第N个[]格呢?

这里用到了润乾报表非线性模型中的绝对层次坐标,请参见[ 。。加上超链接],我们把[]格的表达式写成:[……],如下图所示: [设计截图]

预览效果: [预览截图]

4.3.2 绝对层次坐标

在进行报表设计时,单元格尚未进行扩展,但是其它某些单元格的表达式往往需要对这个单元格扩展后的单元格进行精确定位并运算。

例3.4.1-1:

扩展后:

对单元格B3来说,需要从B2扩展出来的单元格中找到对应月份为3月的格子然后返回其值。

然而B2能扩展出几个格子以及每个格子在什么位置,在扩展前很难描述,因此,为了避免混淆,应该对扩展后的每个单元格进行唯一性定义,这就是单元格的层次坐标。层次坐标是用于唯一描述(精确定位)扩展后的每一个单元格的表达式。

层次坐标的运算结果返回目标单元格。如果层次坐标能够定位到一个单元格,那么返回该单元格的值,如果定位到多个单元格,那么返回这些单元格中的第一个单元格的值。

表达式规则:

说明: a)

Lk为Cellx的左主格,lk为左主格扩展后的次序,即扩展后的第几个单元格,如果

不指定lk或者lk为0,则表示为当前表达式所在单元格所属的当前左主格,Cellx为目标单元格,应该为Lk,Lk1„L1的附属单元格。与之类似,Tk为Cellx的上主格,tk为上主格扩展后的次序。

b) 如果只有上主格,没有左主格,分号不能省略,即应该写成:

Cellx [;Tk:tk, Tk-1: tk-1,……T1: t1]

如果只有左主格,没有上主格,分号可以省略,即可以写成:

Cellx [Lk:lk, Lk-1:lk-1,……L1:l1 ] c)

Lk与Tk的次序是从远到近的,也就是说越上级的主格越靠前。而找到层次坐标所

表示单元格的次序是从最上级的主格开始。

如:

C1[A1:2,B1:1]找C1的次序是:先找单元格A1展开后的第2格,再找第二个A1下属的B1单元格扩展出来的第一个B1,然后找到和该B1对应的C1。

d) 完整的层次坐标表达式应该包括Cellx的所有主格,层次坐标与写在哪个单元格中无关。

例3.4.1-2:

例3.4.1-3:

4.4 同期比 4.4.1

一个例子

先看一张同期比报表

[此例子年、月连续,因此仅仅用位移坐标就可以实现,不需要条件表达式]

该报表的运算逻辑是啥?理想情况下该如何计算?润乾如何实现的?

4.4.2 位移坐标

有了层次坐标后,很多时候并不够用,因为大部分时候报表设计者并不知道目标单元格的具体位置,仅仅知道目标单元格相对于当前单元格的位置,基于这种考虑,我们给出了位移坐标,从而层次坐标更多时候成了模型上的意义,而非应用上的意义。

位移坐标的运用非常广泛,例如报表中常常需要计算同期比、比上期之类的与时间相关的运算,而这些运算往往需要用到下一行的数据减上一行数据,后一列数据减前一列数据,等等,这种涉及到相邻n行或者n列的行间、列间的运算,称为位移运算,相关的表达式称为位移表达式。

位移坐标是用来描述目标单元格和当前格之间的位置关系的表达式。

表达式规则:

说明:

1、Lk为Cellx的左主格,lk为单元格的偏移量,即当前格所属的Lk主格和目标格所属

的Lk主格之间的偏移量,如果不指定lk,则表示为当前所在的左主格Lk,Cellx为目标单元格,一般为Lk,Lk-1,。。。。。。L1的附属单元格

2、如果没有左主格,只有上主格的话,分号不能省略,即写成Cellx [;Tk :±tk, Tk-1 :

±tk-1,……T1 :±t1]

3、如果没有上主格,只有左主格的话,分号可以省略,即写成Cellx [Lk:±lk, Lk-1:

±lk-1,……L1:±l1 ]

4、Lk的次序是从远到近的,也就是从离当前格最远的主格开始的,也可以理解为从

最高级别的主单元格开始

5、完整的位移坐标表达式应该包括Cellx的所有主格,位移坐标与写在哪个单元格中

紧密相关。

例3.4.3-1:

4.4.3 坐标缺省表示法

由于层次坐标和位移坐标的表示很烦琐,而大部分时候对于单元格的定位是和当前格的位置有关系的,一般是指当前格的主格或者和当前格有着相同主格的单元格,此时可以采用缺省的写法。

缺省情况下,如果目标单元格的某个主格Lk和当前单元格的主格相同,那么层次坐标(位移坐标)中该主格可以不写

如果目标单元格与当前格的关系满足3.3.2中的缺省引用规则,那么直接遵循该规则的引用表示法,不需要层次坐标(位移坐标)。

例3.4.2-1:

4.5 分组汇总 4.5.1

例子

[一个普通的分组汇总的例子,利用缺省格级,即sum(A1[]{})或者sum(A1{})]

4.5.2 格集

在实际应用中,往往需要对一组单元格进行运算,而不是单个单元格。这些单元格有可能是固定格,也有可能是主动扩展、被动复制格,为了能在表达式中描述确定的一组单元格,我们引入格集的概念。

格集可以看为满足某种条件的一组单元格的集合。特别的,单个单元格也可以视为仅含一个单元格的格集。

为了说明格集的概念及其作用,我们看看下面的表格:

例6-1: 扩展前:

扩展后:

填入数据:

③Jerry在2005-2-1买的商品;④所有买牛奶的金额。

在做这些统计时,涉及到的数据都是发生在一系列格子中的,我们分别来看一下:①c2,c3;②d4,d5;③d9,d11;④d2,d3,d6,d7,d8。

4.5.2.1 格集表示法 4.5.2.1.1

固定格的格集表示法

对于固定的单元格,我们可以用list()函数,:(link)操作符来表示,书写规则如下:

List(Cell1, Cell2, Cell3,……Celln) 表示由Cell1, Cell2, Cell3,……Celln组成的格子的集合

Cellx : Celly 其中Cellx与Celly均为单元格,该表达式表示以Cellx与Celly为对角点圈起的矩形区域,而且,Cellx在左上角,Celly在右下角。

提示:Link操作符返回的结果是一个格集,可以对其应用集合函数,如count()、sum()、max()、min()等,但是包含link操作符的单元格不允许设为扩展格。 举例:

List(A1,B3,C4) 表示由A1,B3,C4三个单元格组成的集合

Sum(A1:B3) 表示对以A1与B3为对角点圈起的矩形区域里的格子求和。

4.5.2.1.2 扩展格的格集表示法

对于扩展格的格集表示,我们一般和层次坐标结合起来,由层次坐标来界定一个范围,在这个范围内的所有单元格的集合,其书写规则如下:

Cellx[层次坐标或者位移坐标]{}

说明:从上述书写规则可以看出,格集相当于在层次坐标或者位移坐标的基础上增加了{},即可表示该层次坐标或者位移坐标界定的范围内的所有单元格。前文已经提到,如果没有{},而层次坐标界定的范围内的单元格不止一个,那么该层次坐标返回的是该范围内的第一个单元格,有了{},就返回该范围内单元格的集合。

例3.5.2-1: 扩展前:

扩展后:

根据上述表格,我们写几个格集并分析其结果由哪些单元格组成。

C2[`0]{} 返回扩展后的c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12 C2[A2:2]{} 返回扩展后的c7,c8,c9,c10,c11,c12 D2[A2:1,B2:2]{} 返回扩展后的d4,d5,d6

4.5.2.2 缺省格集

同样的,为了简化格集的表示,很多时候会有缺省的写法,其缺省的规则和层次坐标、位移坐标完全一样,主要也是为了简化其中的层次坐标、位移坐标的写法,即目标单元格和当前格的主格相同时,层次坐标(位移坐标)中的该主格可以省略,如果所有主格都相同,则层次坐标(位移坐标)可以为空,甚至连中括号都可以省略。

其书写规则为:

Cellx[缺省的层次坐标或者位移坐标]{}

如果层次坐标(位移坐标)完全省略,则缺省的写法为:

Cellx[]{}或Cellx{}

例:3.5.3-1

例:3.5.3-2

4.6 条件汇总 4.6.1

例子

[4.5中的例子做点变化,改成部分汇总,增加条件表达式,即满足条件的记录才汇总]

4.6.2 格集的条件表达式

如前文所述,当需要对一组单元格进行操作时,我们引入了格集表示法,但是格集的表示是和层次坐标、位移坐标紧密相关的,即层次坐标或者位移坐标确定的范围内的单元格的集合,缺省情况下则是当前格所属的主格管辖范围内所有目标单元格的集合。

但是,很多时候,我们需要运算的目标不是层次坐标确定的所有单元格集合,而是该范围内满足某种条件的单元格集合,此时我们引入了条件表达式,其书写规则如下:

Cellx[层次坐标或者位移坐标]{条件表达式}

从上面的表达式可以看出,其含义是对层次坐标或者位移坐标界定的单元格集合再运用条件表达式进行过滤,把符合条件的单元格找出来,并返回。

例3.5.4-1:

4.7 复杂同期比 4.7.1

例子

把4.4中的例子改成年、月不连续,从而用到比较复杂的条件表达式

4.7.2 $运算符

请看下面的表格:

该表格在设计界面中是如下样子:

可以看出,设计器中只有一行的表达式单元格,但是扩展后变成了很多的行。而该表格中的难点是计算比去年同期,也就是说,对于2006年7月份的格子来说,需要和2005年7月份的数据进行对比运算,而2006年4月份的格子需要和2005年4月份的格子进行对比运算。

而这个表格中的月份不是连续的,而且不是按顺序排列,因此仅仅靠层次坐标、位移坐标无法定位到去年同月份的单元格,需要借助条件表达式。

此时我们往d2单元格中写入表达式:C2-C2[A2:-1]{当前格的b2主格值==目标格的b2主格值}

这时我们会发现,条件表达式没法写了,当前格的主格是b2,目标格的主格也是b2,如果我们写成b2=b2,显然搞不清谁是谁的,于是我们引入了$运算符,他在格集条件表达式中指代当前格的主格

例如上面的条件表达式我们可以写成:C2-C2[A2:-1]{$B2==B2},其中$B2指代当前格的B2主格,B2指代目标格的B2主格

总结:$运算符的书写规则如下:

$Cellx

其含义是在格集表达式中指代当前格的Cellx主格

4.8 排名 4.8.1

一个例子

先看一张最简单的排名报表 [采用根坐标表示法]

讲解理想情况下该如何计算?再介绍润乾的实现方法

然后把这个排名报表复杂化,做成多级的排名

再介绍如何实现

4.8.2 根坐标表示法

描述: 在3.3.1中提到了根格的概念,即报表有个首格(根格),报表中的扩展单元格是逐级扩展的,有主格、附属格的概念,呈树状的结构,而根格则是这棵树的根。如下图所示:

由此可以看出,单元格逐级扩展后实际形成了以根格(报表首格)为根的一棵树,报表中存在多片独立扩展,那么根上就长出多棵树,每一个可主动扩展的格子都是树上的一个节点,最末一级的不可扩展格则是节点上的叶子。而层次坐标相当于描述任意一个节点或者叶子到达根的路径。 由于根格是客观存在的,而树上的所有节点都是由根格发展而来,因此前面介绍的层次坐标忽略了根节点的描述,下面我们加上根坐标的描述,把层次坐标重新表示一下:

表达式规则:

Cellx[`0, Lk:lk, Lk-1:lk-1,……L1:lk; `0, Tk:tk, Tk-1:tk-1,……T1:t1]

从上面的层次坐标可以看出,完整的层次坐标是从根上开始的,而`0 则代表根坐标。

4.9 独立格运算

先看一张典型的独立格报表例子

[利用demo数据库造一个和城八区电信销售统计表的下方独立格运算类似的例子,该例子用到了层次坐标、条件表达式、缺省的格集等,应当是上述所有概念的一个综合运用] 介绍该报表的特点,以及理想的计算方式 介绍润乾的实现方法

4.10 序号

4.10.1 组内序号例子

4.10.2 &运算符

描述: 从前面的介绍可知,单元格是可以扩展的,一个格子可以扩展出多个,那么如何知道某个扩展出来的格子在所有扩展出来的格子中排第几呢?此时我们就引入了&运算符,他可以获得当前格所属的某主格在所有扩展出来的格子中排第几,这种运算我们也称为层次坐标的逆运算。

表达式规则: &Cellx

返回值: 整数,当前格所属的Cellx主格在所有扩展出来的格子中的排序 说明: Cellx必须是当前格的主格,这样&Cellx才能够正确运算,其返回值相当于是当前格所属的Cellx主格的位置

4.10.3 组间序号例子

[即组间的连续序号,采用seq()函数来实现]

4.10.4 seq()

函数说明:

取得指定扩展单元格的同源号,即扩展格扩展后,将此单元格的同源格按行(列)

号从小到大排序后,此单元格所在的序号。

语法:

seq({cellExp}) 参数说明:

cellExp 单元格表达式,必须返回扩展格 返回值:

整数 举例:

假设A1是扩展格,B1的主格为A1,在B1单元格中写入=seq(A1),则扩展后B1的值将依次从1变到A1扩展出来的单元格的数目。

4.11 动态格间运算的概念与特征总结

自由格间运算是中国复杂报表另一个典型特征。

一般来说,固定的列间或者固定的行间运算处理非常简单,所有的报表工具包括excel均可轻松处理。我们这里所说的自由格间运算,特指浮动行列的情况,即行列均为动态扩展出来的,此时行间、列间、甚至组间的运算。

自由格间运算有如下特征:

1、 行列浮动

2、 运算可能跨行、跨列,还可能跨组

3、 行列对称:运算可能是纵向的行间组间运算,还可能是横向的列间、组间运算 4、 单元格的定位不仅仅靠位置,还可能根据复杂的条件来定位

5、 独立格运算,即位于扩展区域之外的某些独立的格子,需要引用扩展区域内的单元格的

6、 序号,为扩展出来的格子编号,可能存在多种编号方式,例如组内的编号;组间大排队,

统一编号;等等

第5章 动态参数的应用

一个典型的例子

例如:输入日期,算出该日期所在周的起始日期和结束日期,作为最终参数传递给报表等

思路:先介绍这样的业务需求,然后讲解怎么做,最后总结润乾动态参数的概念以及扩展应用

第6章 动态宏的应用

参照动态参数的路子写

第7章 高级统计图

介绍思路:先给出一幅图形,介绍该图形有啥特征,适用于哪种业务情况,如何看懂这个图 然后介绍如果设计这样的图,应该准备什么样的数据结构 最后介绍如何设计该图


相关文章

  • 建立"产品发货单"模板,Excel实例教程,Excel系列教程,Excel
  • 建立"产品发货单"模板 www.firnow.com    时间 : 2007-02-14  作者:佚名   编辑:本站 点击:  1312 [ 评论 ] - - 返回目录列表 本节目的:建立一个最简单的模板,并填报,体会Excel服务器最基本的用法. 点评:Excel服务器20 ...

  • 用友财务软件教程
  • 一.建立账套 双击桌面 "系统管理"→系统→注册→用户名(admin)→密码(不填)→确定 1.增加操作员:[权限]→操作员→增加→编号(001)→姓名(张健)→口令(不填)→增加→退出 2.建帐:[帐套]→建立→输入账套号(如:666)→账套名称(如:新奥计算机公司)→启用会计 ...

  • 山东省会计从业资格模拟考试软件安装与操作教程
  • 山东省会计从业资格考试初级会计电算化 实务操作题部分文字教程 炎龙博客(http://ylblog.net)专供 2009年最新版 1.考试模拟系统软件的安装 1.1.安装前的注意事项 1.安装此模拟考试系统软件的计算机,计算机名称中不能带有"-".汉字或者用数字开头,建议改为8 ...

  • 现金支票填写样本详解及填写实例演示
  • 现金支票填写样本详解及填写实例演示 本文主要内容:1.如何巧用Excel轻松套打支票,讲述Excel一些鲜为人知的独门秘诀,从此不再为手写支票费时费力易出错而烦恼:2.如何免费下载价值198元的会计出纳做账宝典教程,从此会计出纳做账轻松无忧,不再求助别人. 先赠送各位财务同行一套非常著名的金码出纳日 ...

  • 最新版会计电算化实训教程
  • 会计电算化实训操作 基于金蝶KIS专业版 目录 第一篇 新建账套 练习一:建账 一.新建公司机构及账套 „„„„„„„„„„„„„„„„„„„„„„„„ 1 二.设置账套参数 „„„„„„„„„„„„„„„„„„„„„„„„„„ 1 三.添加用户 „„„„„„„„„„„„„„„„„„„„„„„„„„ ...

  • 昆仑通态触屏20**年_高级技术培训教程_V1.0
  • 昆仑通态 高级技术培训教程 (内部使用版本) 修改日志 日期 2014-3-3 版本 V1.0 修改人 王倩 修改内容 第一版定稿 目录 第一章 第1节 第2节 第3节 显示和存盘 ........................................................... ...

  • 神机妙算教程
  • 神机妙算 定额与清单计价教程 目录 定额计价 一.创建新工程 ...................................................................................................................- 1 ...

  • [会计电算化专业综合实训]教学大纲
  • <会计电算化专业综合实训>教学大纲 实训名称:会计电算化实训 实训课代码:1650952 实训周数:2周 实训学分:2 适用专业:会计电算化 一.实训教学的性质.目的和任务 (一)课程性质 <会计电算化综合实训>是财会类学生的专业实训课. <会计电算化综合实训>就 ...

  • 会计模拟实习报告1031
  • [会计模拟实习报告]第一部分 一.实习时间:2010年3月3日2010年3月26日 二.实习地点:湘西民族职业技术学院 南校区 育才楼 阅览室 三.实习目的: 通过本套<会计综合实习教程>模拟实习,培养我们的会计业务处理能力,会计模拟实习报告.使我们比较系统的学习企业会计核算的基本程序和 ...

© 2024 范文中心 | 联系我们 webmaster# onjobs.com.cn