水晶报表数据整形模型 兼答CSDN

来源:互联网 发布:vb精简版官方下载 编辑:程序博客网 时间:2024/04/28 22:57
本文为CSDN图表区问题的一个解答模型,却不是最终答案
原来的帖子中已经提出了解决该问题的更好的方法,就是事先在数据库中进行数据修整
本文仅从水晶报表角度来探讨实现方法,可能在其他的地方会用得的到。
(对于数据修整的操作方法,其实在前面的交叉表实现的时候我也曾提到过,尽量在数据库中进行整形)

本问题的相关帖子为:
http://topic.csdn.net/u/20080505/23/69a83cf6-e6f1-4771-abf1-14a089810bac.html
http://topic.csdn.net/u/20080509/20/4c8772d1-3761-46d5-a8f5-126f9abc5273.html

本文的问题是,有这样一个考勤表。

仅有考勤日的数据,但是为了显示上的美观,需要显示该月所有日期,即从1日到月末最后1日
(在这里,我们假设为31日,虽然数据中是2月份,这里仅是个模型,实际操作中,
需根据实际情况对29日、30日、31日三个日期加额外的公式公式,当然这个就比较简单了)。

这样就涉及到一个补行的问题,如果用程序来补行的话,可以直接根据1~31之间的有无来插入
但是对水晶报表来说,如果第一行不是1号,最后一行不是最后1日,那么数据就会被分为3段。
第一段是出现在第一条记录之前的,也就是2月4日之前的。
第二段是出现在第一条和最后一条中间的差异行
第三段是出现在最后一条记录之后的

1:做一个普通的报表,显示这个数据行。
2:拆分详细资料节,在现有数据行的后面增加31个详细资料节,全部抑制显示(31个节,为了对应最大的31日)。
3:在现有数据行前再拆分出8个详细资料皆,抑制显示
(一般来说,每月月头最多有周六、周日两个非工作日,无数据,考虑到国庆节,可能有7个休息日,所以用了8个节,这个根据实际需要可再加几个)

最终的样子是这样的,设计模式下(限于图片大小,后面的几个节抓出来),黄色的段为正常数据显示段


然后我们就要用公式来控制这些节的显示

黄色段前的节公式为(以详细资料节a为例,其余的公式只是将1从上到下一次替换为2~8):
if onfirstrecord then
  day({myData.date1})<=1
else
   true


这个意思是,如果是第一行数据(if onfirstrecord then)则,
判断当前数据行是否<=1(其实也可以写为=1),如果是,则返回true(抑制显示),否则就返回false(不抑制显示)
如果不是第一行数据(else),则直接返回true,抑制显示。

黄色段后的节公式为(以后面第一个节j为例子,其余公式依次替换其中的数据,把所有的数据一次+1)
if OnFirstRecord then
    day ({myData.date1})>1 or day(next ({myData.date1}))<=2
else if onlastrecord then
    //如果是最后一条记录
      day ({myData.date1})>=2
else
day({myData.date1})>=2 or day(next ({myData.date1}))<=2


这句的意思是
如果当前是第一条数据,判断当前数据是否>=1,或者第2条数据<=2
    如果是的话(也就是说,如果该行记录出现在1号后面,或者下一条记录是在2号前面),则抑制显示
如果是最后一条数据,
   如果当前记录是>=2,也就是说如果是在1号之后的,为true,抑制显示
其他的情况,就是夹杂在数据之间的判断当前行和下一行的数据即可

这个公式不复杂,但是逻辑上却比较复杂,需要好好理解。(而且似乎还可以再简化)

最终显示的效果为:


非黄色的区域都是自动补的行,后面的数字是我写的固定公式,不是自动递增的,是每个节上固定的一个公式
这个公式可以根据需要修改显示为需要补的日期。

需要说明的是
1:本文仅为说明水晶报表可以实现类似的效果,但是却并不推荐.详细资料节是嵌套出现的,效率比较低。
水晶报表并不能主动为数据整形,原理可参考<大数据量下水晶报表的实现及显示过程中的进度条显示讨论 >一文中的水晶报表工作模型
所以还是依靠在呈现时进行处理(WhilePrintingRecords)
2:本文所构造的公式虽然实现了现有效果,但是可能还存在缺陷或者能进一步简化。

本文所用到的示例数据库及rpt模板可在此处现在,解压缩密码babyt
/Files/babyt/CR20080511.rar