如何生成矩阵报表(不知这样提法对否? 100分)(100分)

  • 主题发起人 主题发起人 ctk
  • 开始时间 开始时间
C

ctk

Unregistered / Unconfirmed
GUEST, unregistred user!
记录
字段1 字段2 字段3
aa 01 a1
aa 02 a2
aa 03 a3
aa 04 a4
bb 01 b1
bb 03 b3
bb 05 b5
.
.
.
要求生成的报表如下:
01 02 03 04 05 ... //字段名
aa a1 a2 a3 a4 null //记录1
bb b1 null b3 null b5 //记录2
.
.
.
 
假设你的报表是EXCEL的报表
var
temp:type;
msexcel:olevariant;
wbook,wsheet:olevariant;
begin
MsExcel:= CreateOleObject('Excel.Application');
WBook:=MsExcel.Application;
WBook.Visible:= True;
wbook.workbooks.Open(ExtractFileDir(paramstr(0))+'/yourreport.xls');
WSheet:=WBook.ActiveSheet;
with query1do
begin
close;
sql.clear;
sql.add('select 1,2,sum(3) from your table group by 1,2');
open;
i:=1;
temp:=fields[0].astype;
wsheet.cells[1,1].value:=fields[0].asstring;
while not eofdo
begin
if fields[0]<>temp then
begin
i:=i+1;
wsheet.cells[i,1].value:=fields[0].asstring;
end;
wsheet.cells[i,fields[1].asinteger+1]:=fields[2].asfloat;
next;
end;
end;
end;
 
假设你的报表是EXCEL的报表//再次修改
var
temp:type;
msexcel:olevariant;
wbook,wsheet:olevariant;
begin
MsExcel:= CreateOleObject('Excel.Application');
WBook:=MsExcel.Application;
WBook.Visible:= True;
wbook.workbooks.Open(ExtractFileDir(paramstr(0))+'/yourreport.xls');
WSheet:=WBook.ActiveSheet;
with query1do
begin
close;
sql.clear;
sql.add('select 1,2,sum(3) from your table group by 1,2');
open;
i:=1;
temp:=fields[0].astype;
wsheet.cells[1,1].value:=fields[0].asstring;
while not eofdo
begin
if fields[0]<>temp then
begin
i:=i+1;
temp:=fields[0].asstring;
wsheet.cells[i,1].value:=fields[0].asstring;
end;
wsheet.cells[i,fields[1].asinteger+1]:=fields[2].asfloat;
next;
end;
end;
end;

 
//生产经营去向台帐// 跟你的要求一模一样
//单位 一类 二类 三类
1 200 300 400
你自己看一下吧
procedure Treportfrm.shjyqxtz1;
var
i,J,dwbh,row,colmn,a:integer;
filetype:smallint;
month,year,day:word;
begin
with datamodule1.REPORTQRY1do
begin
close;
sql.Clear;
sql.Add('truncate table report');
execsql;
close;
sql.Clear;
sql.add('insert into report select dwbh,bh,fcj from clmx where dwbh is not null ');
sql.add(' union all select dwbh,bh,fcj from clmxyk where dwbh is not null');
execsql;
close;
end;
decodedate(now,year,month,day);
filetype:=F1FileExcel5;
f1book1.read(ExtractFileDir(paramstr(0))+'/f1book1.xls',filetype);
REPORTFRM.Refresh;
//表1
row:=1;DWBH:=-1;
f1book1.sheet:=1;
with DATAMODULE1.REPORTQRY1do
begin
CLOSE;
SQL.CLEAR;
SQL.ADD('select dwbh,bh,sum(fcj) from report where dwbh is not null group by dwbh,bh order by dwbh,bh ' );
OPEN;
FIRST;
dwbh:=fieldbyname('dwbh').asinteger;
while not eofdo
begin
IF DWBH<>fieldbyname('dwbh').asinteger then
begin
ROW:=ROW+1;
DWBH:=fieldbyname('dwbh').asinteger;
end;
colmn:=fieldbyname('bh').asinteger;
IF COLMN>19 then
begin
next;
CONTINUE;
end;
f1book1.textrc[row+4,1]:=fields[0].asSTRING;
f1book1.numberrc[row+4,colmn+2]:=fields[2].asfloat;
next;
end;
end;
a:=row+4;
//
ROW:=1;
DWBH:=-1;
with DATAMODULE1.REPORTQRy2do
begin
CLOSE;
SQL.CLEAR;
SQL.ADD('SELECT DWBH,SUM(FCJ) FROM report WHERE DWBH IS NOT NULL GROUP BY DWBH ORDER BY DWBH');
OPEN;
FIRST;
dwbh:=fieldbyname('dwbh').asinteger;
while not eofdo
begin
IF DWBH<>fieldbyname('dwbh').asinteger then
begin
ROW:=ROW+1;
DWBH:=fieldbyname('dwbh').asinteger;
end;
if f1book1.TextRC[row+4,1]='' then
f1book1.textrc[row+4,1]:=fields[0].asSTRING;
f1book1.numberrc[row+4,2]:=fields[1].asfloat;
next;
end;
F1BOOK1.FormulaRC[4,2]:='SUM(B4:B80)';
f1book1.TextRC[1,1]:='1--'+inttostr(month)+'月份生产(经营)耗用物资及去向台帐';
f1book1.TextRC[2,2]:=datetostr(now);
end;
//OK }
//table 2
f1book1.Sheet:=2;
row:=1;DWBH:=-1;
with DATAMODULE1.REPORTqry1do
begin
FIRST;
dwbh:=fieldbyname('dwbh').asinteger;
while not eofdo
begin
IF DWBH<>fieldbyname('dwbh').asinteger then
begin
ROW:=ROW+1;
DWBH:=fieldbyname('dwbh').asinteger;
end;
colmn:=fieldbyname('bh').asinteger;
IF (COLMN<=19) or (colmn>=40) then
begin
next;
CONTINUE;
end;
f1book1.textrc[row+4,1]:=fields[0].asSTRING;
f1book1.numberrc[row+4,colmn-18]:=fields[2].asfloat;
next;
end;
end;
//
ROW:=1;dwbh:=-1;
with DATAMODULE1.REPORTqry2do
begin
FIRST;
dwbh:=fieldbyname('dwbh').asinteger;
while not eofdo
begin
IF DWBH<>fieldbyname('dwbh').asinteger then
begin
ROW:=ROW+1;
DWBH:=fieldbyname('dwbh').asinteger;
end;
if f1book1.TextRC[row+4,1]='' then
f1book1.textrc[row+4,1]:=fields[0].asSTRING;
next;
end;
f1book1.TextRC[1,1]:='1--'+inttostr(month)+'月份生产(经营)耗用物资及去向台帐(续一)';
f1book1.TextRC[2,2]:=datetostr(now);
end;
//
//table 3
f1book1.Sheet:=3;
row:=1;DWBH:=-1;
with DATAMODULE1.REPORTqry1do
begin
FIRST;
dwbh:=fieldbyname('dwbh').asinteger;
while not eofdo
begin
IF DWBH<>fieldbyname('dwbh').asinteger then
begin
ROW:=ROW+1;
DWBH:=fieldbyname('dwbh').asinteger;
end;
colmn:=fieldbyname('bh').asinteger;
IF (COLMN<40) then
begin
next;
CONTINUE;
end;
f1book1.textrc[row+4,1]:=fields[0].asSTRING;
if colmn=99 then
f1book1.numberrc[row+4,21]:=fields[2].asfloat
else
f1book1.numberrc[row+4,colmn-38]:=fields[2].asfloat;
next;
end;
CLOSE;
end;
//
ROW:=1;dwbh:=-1;
with DATAMODULE1.REPORTqry2do
begin
FIRST;
dwbh:=fieldbyname('dwbh').asinteger;
while not eofdo
begin
IF DWBH<>fieldbyname('dwbh').asinteger then
begin
ROW:=ROW+1;
DWBH:=fieldbyname('dwbh').asinteger;
end;
if f1book1.TextRC[row+4,1]='' then
f1book1.textrc[row+4,1]:=fields[0].asSTRING;
next;
end;
CLOSE;
end;
f1book1.TextRC[1,1]:='1--'+inttostr(month)+'月份生产(经营)耗用物资及去向台帐(续二)';
f1book1.TextRC[2,2]:=datetostr(now);
with DATAMODULE1.REPORTqry1do
begin
CLOSE;
SQL.CLEAR;
SQL.ADD('select bh,sum(fcj) from report where dwbh is not null group by bh order by bh');
OPEN;
first;
while not eofdo
begin
colmn:=strtoint(fields[0].asstring);
if colmn<=19 then
begin
f1book1.sheet:=1;
f1book1.numberRC[4,colmn+2]:=fields[1].asfloat;
end;
if (colmn>19) and (colmn<=39) then
begin
f1book1.sheet:=2;
f1book1.numberRC[4,colmn-18]:=fields[1].asfloat;
end;
if colmn>39 then
begin
f1book1.sheet:=3;
if colmn<>99 then
f1book1.numberRC[4,colmn-38]:=fields[1].asfloat
else
f1book1.numberRC[4,21]:=fields[1].asfloat;
end;
next;
end;
end;
WITH DATAMODULE1.REPORTQRY1do
begin
CLOSE;
SQL.CLEAR;
SQL.ADD('SELECT * FROM YLDWMX');
OPEN;
end;
FOR I:=1 TO 3do
begin
F1BOOK1.SHEET:=I;
f1book1.SetRowHeight(4,80,365,true);
FOR J:=5 TO 80do
IF F1BOOK1.TEXTRC[J,1]<>'' then
IF DATAMODULE1.REPORTQRY1.LOCATE('DWBH',F1BOOK1.TEXTRC[J,1],[]) then
F1BOOK1.TEXTRC[J,1]:=DATAMODULE1.REPORTQRY1.FIELDS[0].ASSTRING;
end;
f1book1.sheet:=1;
filetype:= F1FileExcel5;
f1book1.write(ExtractFileDir(paramstr(0))+'/SHHH.xls',filetype);
MsExcel:= CreateOleObject('Excel.Application');
WBook:=MsExcel.Application;
WBook.Visible:= True;
wbook.workbooks.Open(ExtractFileDir(paramstr(0))+'/SHHH.xls');
WSheet:=WBook.ActiveSheet;
REPORTFRM.Close;
wbook.Sheets['表1'].Select;
setgridline(3,A,'U');
WSheet.pagesetup.LeftMargin:=msexcel.InchesToPoints(0.196850393700787);
WSheet.pagesetup.RightMargin:=msexcel.InchesToPoints(0.196850393700787);
wbook.Sheets['表2'].Select;
setgridline(3,A,'U');
WSheet.pagesetup.LeftMargin:=msexcel.InchesToPoints(0.196850393700787);
WSheet.pagesetup.RightMargin:=msexcel.InchesToPoints(0.196850393700787);
wbook.Sheets['表3'].Select;
setgridline(3,A,'U');
WSheet.pagesetup.LeftMargin:=msexcel.InchesToPoints(0.196850393700787);
WSheet.pagesetup.RightMargin:=msexcel.InchesToPoints(0.196850393700787);
wbook.Sheets['表1'].Select;
end;
 
谢谢arm,我用的是Oracle数据库,
想在delphi下直接生成上述报表,
不知有无其它办法?
 
源表:
操作员 单号 金额(元)
aa 01 123
aa 02 345
aa 03 678
...
bb 01 234
bb 03 345
...
cc 01 888

目标表:
操作员 单号1金额 单号2金额 单号3金额 单号4金额 单号5金额 ...
aa 123 456 789 null
bb 234 null 567 null
cc 888
先转换,后做报表。
转换:
遍历“源表”
读“源表”的“操作员” (如得aa)
if 查找“目标表”中“操作员” =aa 的记录
then

case "单号"
01 就 写“目标表”."单号1金额”=“源表”."金额"
02 就 写“目标表”."单号2金额”=“源表”."金额"
...
end //case
else
增加一条记录 “操作员” =aa
case "单号"
01 就 写“目标表”."单号1金额”=“源表”."金额"
02 就 写“目标表”."单号2金额”=“源表”."金额"
...
end //case
end //遍历
做“目标表”报表:你会!
 
矩阵报表是Oracle的说法,其它我见过的名称好象为CrossReport,
不知是否正确。
我也一直在寻找这样的控件和处理方法,包括显示、编辑和报表。
我现在的想法处理该问题有两种方法:
1、动态生成Table,如其他人讨论的一样,行列根据不同的数据种类定义。
灵活、没有冗余,但每次都创建不同的表,显得比较麻烦。
2、数据冗余,这样可以固定一个属性(作为Field),对另一个属性实行处理.
冗余要足够大,即字段名固定为某一个值,该值足以容纳需要的字段。
在具体显示时,多的部分要进行处理,让它不显示。
如果有比较好的处理方法请告诉我。
 
我的做法于黄耀彰同,但此法有很大缺点。(列会很长)
不知谁有比较好的处理方法。
 
多人接受答案了。
 
这是交叉表嘛,现在用RBuid控件很容易解决
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
I
回复
0
查看
876
import
I
I
回复
0
查看
680
import
I
后退
顶部