如何制作可动态增加列的报表?

Ascn 2001-10-02 06:25:34
我想制作一个报表,要求该报表的列可以动态增加。例如,最初时该报表有三列,ID、名称和属性1。在某个时候,可能会增加第四个项目,如属性2;甚至第五个:属性3......

上述的“属性n”是用户可以定义的,只要用户想新增一个属性,则该报表应能增加一列。
同时,已增加的数据应该在数据库中体现,即在下次运行系统后,报表应该多了一列。

请问,如何实现上述功能?在数据库中如何设计?

lx130@sina.com
2001-10-02
...全文
191 12 打赏 收藏 举报
写回复
12 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
Ascn 2002-04-14
非常感谢 Hanson_bati_zhu(Hanson_bati_zhu)。
该方法很好。我在此非常感谢各位朋友的参与。

如果有更好的方法,欢迎大家提出来,我会再来看的;如果必要,可以另行开贴
给与奖励。
  • 打赏
  • 举报
回复
winwhere 2002-03-13
收藏
  • 打赏
  • 举报
回复
Hanson_bati_zhu 2002-03-12
举个例子吧
不知道是否切题

行号 姓名 部门 基本工资 奖金合计 全勤奖 安全奖 车补 工资总计 应扣金额 实发合计
1 张三 门卫 300 100 40 60 50 400 17 383
2 李四 司机 500 140 40 100 0 640 25 615


这是一个很简单的工资条表格的样式(其中行号为唯一标识列,一般常用人员ID作此列,在此用于是为了使描述简单),其中横行列有10列,前两列内容可以从职工信息表中获取,而后面的8项则可能经常要发生变动,比较常见的设计办法是创建一个几十列的大数据库表,如果用户改变报表的格式,程序则调整数据的内容或列的显示顺序(即表格格式中保存当前表格列对应当数据库表列ID),表格样式的存储结构一般常定义为:



序号 列显示名 对应数据库表列ID 列计算公式 。。。
1 姓名 NAME
2 部门 BUMEN
3 基本工资 COL1
4 奖金合计 COL2 COL3+COL4
5 全勤奖 COL3
6 安全奖 COL4
7 车补 COL5
8 工资总计 COL6 COL1+COL2+COL5
9 应扣金额 COL7
10 实发合计 COL8 COL6-COL8



这样做的主要缺点是用户表格内容的类别有限制,很难在这张表中加入一个扣款说明列
因为如果不可预知用户字符列和数值列的数量,无法确定数据存储表的列结构。而且数据库数据存储表的数据冗余比较严重。

如果把这个数据存储方式的思路调整一下,把数据的存储格式变一下,改为以下结构:


表格结构存储:

表格元素ID 表格元素显示名 元素类别 计算公式
001 姓名 字符
002 部门 字符
003 基本工资 金额
004 奖金合计 金额 005+006
005 全勤奖 金额
006 安全奖 金额
007 车补 金额
008 工资总计 金额 003+004+007
009 应扣金额 金额
010 实发合计 金额 008-009


如果需要处理多张报表,可以在前面加一个表格ID,在此只讨论这一张报表,所以不引用

数据存储:


行号 元素ID 字符数据列 金额数据列
1 001 张三
1 002 门卫
1 003 300
1 004 100
1 005 40
1 006 60
1 007 50
1 008 400
1 009 17
1 010 383
2 001 李四
2 002 司机
2 003 500
2 004 140
2 005 40
2 006 100
2 007 0
2 008 640
2 009 25
2 010 615



由数据存储表的存储内容可以看出,该表的主键列为:行号+元素ID
对于同一张表,数据内容实际上可以划分为数值型和字符型(日期型其实也可以转化为一种字符型),根据用户对表格格式的定义中各列的类型定义,数据分别存储到对于的数据类别列中
这样做的优点为,用户表格格式的变化只会影响到数据存储表的行次数据,而对数据存储表的结构不会有任何影响,而且表格格式定义时,不需要考虑数据存储表的结构是否有限制要求,所以这样就能大幅度提高表格结构定义的灵活度


如果需要从数据存储表中获取所需的数据,可以采用这个办法:


SELECT 行号,
MAX(CASE WHEN 元素ID='001' THEN 字符数据列 ELSE '' END) AS 姓名,
MAX(CASE WHEN 元素ID='002' THEN 字符数据列 ELSE '' END) AS 部门,
SUM(CASE WHEN 元素ID='003' THEN 金额数据列 ELSE 0 END) AS 基本工资,
SUM(CASE WHEN 元素ID='004' THEN 金额数据列 ELSE 0 END) AS 奖金合计,
SUM(CASE WHEN 元素ID='005' THEN 金额数据列 ELSE 0 END) AS 全勤奖,
SUM(CASE WHEN 元素ID='006' THEN 金额数据列 ELSE 0 END) AS 安全奖,
SUM(CASE WHEN 元素ID='007' THEN 金额数据列 ELSE 0 END) AS 车补,
SUM(CASE WHEN 元素ID='008' THEN 金额数据列 ELSE 0 END) AS 工资总计,
SUM(CASE WHEN 元素ID='009' THEN 金额数据列 ELSE 0 END) AS 应扣金额,
SUM(CASE WHEN 元素ID='010' THEN 金额数据列 ELSE 0 END) AS 实发合计
FROM 数据存储表
GROUP BY 行号


这个SQL语句乍一看起来感觉很复杂,而且感觉运行效率肯定很差劲,实际上不用担心,仔细看看就会发现,这个SQL语句是有规律可循的,对于字符型列,使用MAX,对于数值型列,使用SUM,后面就是根据表格结构定义生成的一个很简单的字符串,最后为每一个计算列设置一个别名以便程序处理,运行效率吗,尽可放心,绝对可以满足使用的要求。
  • 打赏
  • 举报
回复
winwhere 2002-03-12
更改数据结构,参看http://www.csdn.net/Expert/Topic/562/562028.xml
  • 打赏
  • 举报
回复
killerdanny 2002-03-12
没有限制的列,只有一种方式,就是把列变成行!
  • 打赏
  • 举报
回复
Ascn 2001-10-06
如果不更改报表结构,如何办?
  • 打赏
  • 举报
回复
zhang_zpz 2001-10-03
可以这样考虑:

国际A公司 BBB厂 Cc公司
子公司x 日售出
子公司y 日售出

子公司不定,但是总公司个数该定了吧
然后增加行即可!
  • 打赏
  • 举报
回复
Ascn 2001-10-02
能更详细吗?比如针对:
客户单位名 | 子公司x 日售出 | 子公司y 日售出 | ... ...
国际A公司 32吨 19.35吨
BBB厂 17吨 0
Cc公司 0 7吨
... ... ...

如何实现?
  • 打赏
  • 举报
回复
lcong 2001-10-02
报表作成复合式,数据库作成包含三个子段的多行数据即可
  • 打赏
  • 举报
回复
rightyeah 2001-10-02
对单一dwobject原则上不可以,但是你可以采用更换dwobject的办法解决
  • 打赏
  • 举报
回复
JWhiteHorse 2001-10-02
up
  • 打赏
  • 举报
回复
JWhiteHorse 2001-10-02
up
  • 打赏
  • 举报
回复
相关推荐
发帖
PowerBuilder
加入

958

社区成员

PowerBuilder 相关问题讨论
申请成为版主
帖子事件
创建了帖子
2001-10-02 06:25
社区公告
暂无公告