在报表中录入数据时如何实现行列转换

应用场景及需求:

某电力集团在实际应用中需要在填报数据时将数据库中的字段以更符合业务人员使用习惯的方式进行呈现,其中就有行列转换的情况。在常规的应用开发中,一般都是通过专门设计的数据界面进行录入,然后再通过程序转换存入数据库。而现在有了集算器支持的润乾填报表,就能够处理各种有关数据结构的填报需求了,这种行列转换自然也不在话下。

首先,我们来看一下行列转换的准确含义:

在一些企业应用中,一些指标项在数据库存储时会做为不同的字段存储,这样数据结构会更加清晰,但是在报表展示或填报表数据录入时,又需要将列转换成行的形式,从而更加符合业务人员的使用习惯,这就是行列转换。首先看一个报表展示页面:

需求一:这个填报表是月度报表,要求按照月份查询某公司下各项目以及机组信息数据,并且能够对数据进行修改。

需求二:工具栏中增加两个按钮:“报表保存”保存当前页面数据,“报表锁定”能够对当前页面数据进行保存并对数据锁定,锁定后用户再次访问该月份数据就无法再修改了。

需求三:报表第二列是项目名称。用户系统结构比较特殊,页面中每个项目名称都是数据库表中的字段名称,第三列和第四列为机组信息数据,在数据库中每个机组为一条记录,也就是说数据存放在数据库中两个表中,分别是 rep_tl_config 表和 rep_tl_yb 表,取数或回写时要根据项目名称从不同表中取数或回写。

下面是这些需求的实现过程。

解决方案:

这个报表的格式相对比较简单,按照需求制作即可,如下图:

A 列为序号列,单元格中设置序号。

B 列为项目名称

C 设置,B 列中项目名称中是有特殊符号的,和数据库中字段名称无法完全对应,会对取数造成影响,所以增加了 C 列,单元格类型为维度格,值为对应的字段名称。

D 列、E 列为数值格,该报表要取两个机组的数据,分别显示在 D 列、E 列中。

F 列为固定列,输入相应信息即可,

G 列用于控制页面端加锁后数据是否能够被修改。

C、D、E、G 列均需要设置字段名称,根据数据取数的数据对象来确定。

取数设置

由于数据结构较为特殊,所以取数使用集算器文件(dfx),并且由于报表中数据来自数据库两张数据表,所以取数脚本分两部分处理,脚本一如下:

A1:链接数据源

D1:单元格从数据表中取出公司名称赋值给变量:公司名称

E1:填报表首次访问时,如果没有传入年月,则取当前系统时间上月数据,表达式为:>month=if(month==null,[email protected](now()),date(month/“-01”))

A2、A3 单元格分别定义了从两个数据表中取数的字段名称

D4、E4 分别定义两个变量设置机组名称,groupID 为机组传入参数,传入格式为 #1#2 方式,所以此处做了拆分。

A5:从 rep_tl_config 表中取出需要数据,数据返回如下:

A6:使用集算器的 pivot 函数,将 A5 中的数据做行列转换,将列转成行,将字段名称转为行数据。

A8:将 A7 数据按照脱硫设备编号进行分组拆分,将数据放到 data 列中

A9、B9、C9 取第一个脱硫编号的数据,处理后放到 t1 对象中

A10、B10、C10 取第二个脱硫编号的数据,处理后放到 t2 对象中

A11:通过序号字段,将 t1、t2 两个对象关联在一起

A12:取出需要数据,此时数据格式为:

可以看到,已经将数据进行了行列转换,原来的字段做为项目字段中的值,另外两列存储对应的数据值。

A13:将 A12 单元格数据赋值给 tl_config 对象

至此,第一部分取数完成,接下来看下第二部分数据处理。

A16:从 rep_tl_yb 表中取出相应数据

B16:设置页面端是否加锁标志,数据表中有个字段“是否经过修正”,判断 A16 是否为空,如果为空,那么证明是第一次访问该月数据,所以值为 false,否则取数据库中对应值。

A17 中做判断,如果 A16 数据为空,则直接在之前定义的 tl_config 对象基础上增加公司名称、month、是否经过修正、flag 字段,返回给报表,即报表第二部分数据为空。

B22~B30 之间单元格设置和脚本一中设置设置方式类似,由于篇幅原因,此处不做过详细说明,最终将所需要数据放到 tl_config 对象中,tl_config 对象中数据为:

接下来,设置填报表中对应单元格的字段名称,将 C 列单元格字段名称设置为:tl_config. 项目,D 列字段名称设置为:1 脱硫装置,E 列字段名称设置为:2 脱硫装置,G 列设置为:是否经过修正

这样,填报表能够从数据库中取出相应数据展示到页面中。

数据回写

接下来看下数据回写脚本,同样,回写时也需要将数据回写到数据库的两个表中,此处脚本分两段来说明:

B1:取出公司名称

D1:设置 month 对象值,如果传入参数为空,则取当前系统时间的前一个月

A2、A3 分别定义两个表中的字段名

D4、E4,分别解析两个机组编号放大 groupID1、groupID2 中

A7:>tl_config=tl_config.new(项目,1 脱硫装置,2 脱硫装置, 是否经过修正),从 tl_config 对象中取出相应字段,并生成新对象 tl_config

A9:从对象中取出项目在 A2 中的数据,A2 为数据库表 rep_tl_config 中字段名

B9:=A9.new(#1,#2).derive(groupID1: 脱硫设备编号,kks:kks 编码,B1(1). 所属公司: 所属公司 ),从 A9 中取第 1、第 2 两列数据,并且增加相应字段,之前看过 tl_config 对象中数据,1、2 列中存储的是项目名称、机组 1 数据

C9:=B9.pivot(kks 编码, 脱硫设备编号, 所属公司;#1,#2),通过 pivot 函数,将行在转回成列形式。

B10、C10,取 1、3 列,同上,将机组 2 数据取出并作行列转换。

A11:>[email protected](C9|C10,rep_tl_config,${C9.fname().concat(“,”)};kks 编码, 脱硫设备编号, 所属公司 ),用 update 函数执行更新操作,将页面中数据更新到 rep_tl_config 表中,其中 C9|C10 是将机组 1 和机组 2 纵向拼接,fname() 取 C9 的字段名,并转换成字符串格式。

这样,rep_tl_config 表更新完毕,接下来看下 rep_tl_yb 表的处理,脚本如下:

处理方式和之前一样,A3 单元格定义的是 rep_tl_yb 中的字段名称,在 A14~A17 中按照之前方式,取出对应字段并通过 pivot 做行列转换,将数据更新到数据库即可。

这样就完成了数据的取数及回写操作。

加锁设置

在取数对象中,取出了数据库的是否经过修正字段,通过该字段的值控制页面中的数据是否经过锁定,该字段的值在报表的 G 列中取出,所以报表可以根据 G 列的值控制页面端是否能够修改数据,是否修改数据可以通过报表单元格的是否可编辑表达式属性控制,在 D、E 两列(两个机组数据列)的是否可编辑表达式中写入:G4!=“true”,表示 G4 单元格不为 true 时,在页面端可编辑。

上述完成了报表取数时可以根据相应字段控制页面端是否能够修改数据,接下来看下,如果在页面端点击报表锁定按钮,实现数据加锁操作。

报表工具栏默认使用的是 inputtoolbar.jsp,里边定义了工具栏的按钮,可在该页面自定义按钮:

<li class="borderRight submitLi" onClick="submit(‘<%=sgid %>‘);return false;" href="#"> <a title="加锁" href="#" class="jiasuo"></a></li>

里边增加按钮,点击时调用 submit 函数,在 showInput.jsp 中增加 submit 函数如下:

function submit(arg1){

for(var i=4;i<=65;i++){// 报表共 65 行,从第 4 行开始设置

document.getElementById(arg1+“0_G”+i).setAttribute(“value”,“true”);// 将值设成 true

_inputSubmit(arg1);// 调用报表保存的 js 函数

}

这样,在页面端点击报表锁定按钮,就能通过 js 更改标识位的值并将值保存到数据库中,再次访问报表时,页面中的数据处于锁定状态,无法编辑。

总结:

至此,完成了客户的所有需求,该例中可以看到,对于数据库结构比较特殊的表,可以通过集算器先对数据进行处理,将处理后的数据返回给报表使用,点击填报后又能在脚本中对数据再次处理,从而实现行列转换的需求,此例中主要是 pivot 函数的使用,具体可以看一下函数说明。并且,润乾填报表页面端的值可以通过 javascript 进行处理,从而实现数据加锁等相应需求。

原文地址:https://www.cnblogs.com/xiaohuihui-11/p/12108765.html

时间: 2024-11-05 17:30:57

在报表中录入数据时如何实现行列转换的相关文章

android 修改listview中adapter数据时抛出异常java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification问题

近日在做项目时遇到非必现crush,具体异常信息为: // Short Msg: java.lang.IllegalStateException // Long Msg: java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not mo

在Oracle中更新数据时,抛出:ORA-01008: not all variables bound

在Oracle中更新数据时,抛出了一个 :ORA-01008 not all variables bound, 我的理解是不是所有的变量/参数都有边界,不懂: 后来知道了,原来是“不是所有变量/参数都确定”, 就是有些变量没有指定,缺少变量参数, 最后发现是因为在写三层时少写了一个"new OracleParameter(":ID",userinfo.ID);" 导致的.

在往oracle中插数据时,如何处理excel读取的时间空值

//若从excel中读取的时间值为空值时,做如下转换 string YDKGSJ = string.Empty; if (dbdata.Rows[i]["约定开工时间"].ToString() == "") { YDKGSJ = "null,"; } else { YDKGSJ = "to_date('" + Convert.ToDateTime(dbdata.Rows[i]["约定开工时间"]) + &q

访问cv::Mat中的数据时遇到的指针类型问题

在用Opencv的时候由于下图原本的图像尺寸是1111*1111,要进行resize,代码如下: cv::Mat img = cv::imread("//Users//apple//td3//vase//19201.png",CV_LOAD_IMAGE_GRAYSCALE); cv::Mat img2; cv::resize(img, img2, cv::Size(400,400),0,0, cv::INTER_AREA); 因为我根本不知道img的数据是什么类型(不知道数据类型根本无

【转】从QDataStream向QByteArray中写入数据时的注意点(QT)

最近发现从QDataStream向QByteArray中写入数据常常是写不进去的,通过查看QT的源码: QDataStream &operator>>(QDataStream &in, QByteArray &ba){ ba.clear(); quint32 len; in >> len; if (len == 0xffffffff) return in; const quint32 Step = 1024 * 1024; quint32 allocated

向数据库中插入数据时字符集或查询是数据无法正常显示出现乱码问题

当向数据库插入数据出错或出局无法正常显示出现乱码时.首先应该想到的是数据库的编码问题.查看当前数据库服务器默认对数据库处理的字符集 show variables like  'character_set%'; character_set_client: 默认客户端来的数据格式 character_set_connection : 连接层字符集 character_set_database:  当前数据库字符集 character_set_results:服务器给外部的字符集 假如客户端字符集与数

2014.11.26 向MySQL数据表中插入数据时,显示“syntax error”时应检查

插入语句: "insert into tablename (a,b,c,d) values(1,2,3,4)" 插入结果: a b c d 1 2 3 4 有误时,请检查: 1.名值对有没有写错: 2.代码的字符串处理有没有问题: 3.代码中的列名和表中的列名是不是一一对应的: 4.定义的列名是否跟SQL语句中的关键字重复,例如dec等.

django rest framework 向数据库中插入数据时处理外键的方法

一.models.py中 from django.db import models class UserModel(models.Model) user_name = models.CharField() class MyModel(models.Model) author = models.Foreignkey(user) age = models.CharField() 二. 序列化文件 serializers.py 中创建序列化类 from rest_framework.serialize

MYSQL中插入数据时出现的问题:

问题: mysql> insert tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES('Y400N 14.0英寸笔记本','笔记本','联','3990',default,default); ERROR 1366 (HY000): Incorrect string value: '\xB4\xE7\xB1\xCA\xBC\xC7...' for column 'goods_name