麻烦的问题
我也做过类似的报表,从那以后,就自己开发了一个自带外挂编辑器的报表工具
外挂环境类似于WORD里制表工具, 编辑环境里放一个报表控件就可以
需要改动报表样式时,只需在外部编辑报表格式文件就可以了
需要的话, emailto:hehe@tonghua.com.cn
如果您使用QRREPORT的话,完成上述操作要这么做
首先自定义一个INI文件(REGISTER里写也可以)
然后,做一个小编辑环境,改动INI(OR REGISTER)
然后使用动态对象数组的办法,手动生成报表
下面是我的一个例子, 把另一个数据表的表记录写到报表的列头上
使用了动态数组
unit danaprint;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
quickrpt, Qrctrls, Db, DBTables, ExtCtrls;
type
TResultArray = array[0..0, 0..0] of Real;
PResultArray = ^TResultArray;
//从表中得到的数据暂时保存在这里
TShuJuArray = array[0..0,0..0] of TQrLabel;
PShuJuArray = ^TShuJuArray;
//用于显示交叉表中的数据
THangArray = array[0..0] of TQrLabel;
PHangArray = ^THangArray;
//用于显示行头
TLieArray = array[0..0] of TQrLabel;
PLieArray = ^TLieArray;
//用于显示列标题
Tdanaprintfrm = class(TForm)
DataSource1: TDataSource;
Query1: TQuery;
Query2: TQuery;
QuickRep1: TQuickRep;
QRBand1: TQRBand;
TitleBand1: TQRBand;
QRMemo1: TQRMemo;
QRLabel5: TQRLabel;
QRGroup2: TQRGroup;
QRSubDetail2: TQRSubDetail;
QRLabel8: TQRLabel;
Query3: TQuery;
QRLabel1: TQRLabel;
procedure QRSubDetail2BeforePrint(Sender: TQRCustomBand;
var PrintBand: Boolean);
procedure QuickRep1BeforePrint(Sender: TQuickRep;
var PrintReport: Boolean);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
danaprintfrm: Tdanaprintfrm;
pfl_array
HangArray;
pks_array
LieArray;
pArrayOfResult: PResultArray;
pSum_array
ShuJuArray;
implementation
uses kssf_ylb;
{$R *.DFM}
procedure Tdanaprintfrm.QRSubDetail2BeforePrint(Sender: TQRCustomBand;
var PrintBand: Boolean);
//用于初始化临时数据数组
//var i,j:integer;
begin
PrintBand := False;
{ query1.open;
query1.first;
query2.open;
query2.first;
query3.open;
query3.first;
try
GetMem(pArrayOfResult, query2.recordcount * query3.recordcount * SizeOf(real));
//为数组分配内存
for i := 0 to query2.recordcount-1do
for j := 0 to query3.recordcount-1do
pArrayOfResult^[i, j] := 0;
while not query1.EOFdo
begin
query2.first;
i:=0;
while (not (query2.fieldbyname('aa').asstring = query1.FieldByName('aa').asstring))
and (not query2.eof)do
begin
i:=i+1;
query2.next;
end;
query3.first;
j:=0;
while (not (query3.fieldbyname('flmc').asstring=query1.FieldByName('flmc').asstring))
and (not query3.eof)do
begin
j:=j+1;
query3.next;
end;
pArrayOfResult^[i,j]:=pArrayOfResult^[i,j]+query1.fieldbyname('column3').value;
query1.next;
end;
finally
FreeMem(pArrayOfResult, query2.recordcount * query3.recordcount * SizeOf(real));
end;
ShowMessage('Done');}
end;
procedure Tdanaprintfrm.QuickRep1BeforePrint(Sender: TQuickRep;
var PrintReport: Boolean);
begin
//row:=0;
end;
{ pfl_array
HangArray;
pks_array
LieArray;
pArrayOfResult: PResultArray;
pSum_array
ShuJuArray;}
procedure Tdanaprintfrm.FormCreate(Sender: TObject);
var
BandWidth,bandleft,bandtop,bandheight:integer;
i,j: integer;
// printshape:tqrshape;
begin
qrlabel1.Caption:=KsSf_ylb_Frm.MaskEdit1.Text+'至'+KsSf_ylb_Frm.MaskEdit2.Text+' 收费一览';
Query1.ParamByName('param1').AsDateTime:=KsSf_ylb_Frm.Query1.parambyname('param1').AsDateTime;
Query1.ParamByName('param2').AsDateTime:=KsSf_ylb_Frm.Query1.parambyname('param2').AsDateTime;
Query1.Prepare;
query1.open;
query1.first;
Query2.Prepare;
query2.open;
query2.first;
Query3.Prepare;
query3.open;
query3.first;
// BandWidth := Trunc(QRBand1.Width / Query3.RecordCount);
BandWidth:=QrLabel5.Width;
bandleft:=qrlabel5.left+qrlabel5.Width;
//所有标签的其始LEFT偏移地址
bandtop:=qrlabel5.Top+qrlabel5.Height;
bandheight:=qrlabel5.Height;
GetMem(pfl_array,Query3.RecordCount * sizeof(TQrlabel));
GetMem(pks_array,Query2.RecordCount * sizeof(TQrlabel));
GetMem(pArrayOfResult, query2.recordcount * query3.recordcount * SizeOf(real));
//为数组分配内存
GetMem(pSum_array,query2.recordcount * query3.recordcount * SizeOf(TQrlabel));
for j := 0 to Query3.RecordCount-1do
begin
Pfl_Array[j] := TQRLabel.Create(self);
with pfl_Array[j]do
begin
Parent := QRBand1;
AlignToBand := False;
AutoSize := True;
AutoStretch := False;
Color := clWhite;
Top := qrlabel5.top;
height:=BandHeight;
//Width := BandWidth;
if j=0 then
Left :=BandLeft + 6 + j*(BandWidth)
else
Left :=pfl_Array[j-1].left+pfl_array[j-1].Width+8;
caption:=query3.fieldbyname('flmc').asstring;
Font.Style := [];
Font.Name :='宋体';
Font.Size :=10;
end;
Query3.Next;
end;
for i:=0 to Query2.RecordCount-1do
begin
Pks_Array
:= TQRLabel.Create(self);
with pks_Arraydo
begin
Parent := QRBand1;
AlignToBand := False;
AutoSize := false;
AutoStretch := False;
Color := clWhite;
Left := qrlabel5.Left;
Width := BandWidth;
Height :=BandHeight;
Top:=BandTop + 6 + i*(BandHeight+6);
// frame.DrawTop :=true;
// frame.DrawLeft :=true;
// frame.DrawBottom :=true;
// frame.DrawRight :=true;
Caption:=query2.fieldbyname('ksmc').asstring;
Font.Style := [];
Font.Name :='宋体';
Font.Size :=11;
// printshape:=TQrShape.Create(self);
// printshape.parent:=qrband1;
// printshape.Top :=pks_Array.top;
// printshape.Height :=pks_Array.height+12;
// printshape.Width :=bandWidth;
// printshape.left :=qrlabel5.left;
AlignToBand := False;
end;
query2.Next;
end;
i:=0;
j:=0;
query1.first;
query2.first;
query3.first;
try
for i := 0 to query2.recordcount-1do
for j := 0 to query3.recordcount-1do
pArrayOfResult^[i, j] := 0;
while not query1.EOFdo
begin
query2.first;
i:=0;
while (not (query2.fieldbyname('ksmc').asstring = query1.FieldByName('ksmc').asstring))
and (not query2.eof)do
begin
i:=i+1;
query2.next;
end;
//end while...
query3.first;
j:=0;
while (not (query3.fieldbyname('flmc').asstring=query1.FieldByName('flmc').asstring))
and (not query3.eof)do
begin
j:=j+1;
query3.next;
end;
//end while...
pArrayOfResult^[i,j]:=pArrayOfResult^[i,j]+query1.fieldbyname('column3').value;
query1.next;
if pArrayOfResult^[i,j]<>0 then
begin
Psum_Array[i,j] := TQRLabel.Create(self);
with psum_array[i,j]do
begin
Parent := QRBand1;
AlignToBand := False;
AutoSize := false;
AutoStretch := False;
Color := clWhite;
Font.Style := [fsitalic];
Font.Name :='Arial';
Font.Size :=6;
top :=pks_array.top;
left :=pfl_array[j].left;
height:= pks_array.height;
width :=pfl_array[j].left;
caption:=Format('%m', [pArrayOfResult^[i,j]]);
//Format('%8.2f', [pArrayOfResult^[i,j]])
end;
//with
end;
//if 实数数组的数字不为0,那么产生一个TQRLABEL对象,并赋值给这个对象
end;
//end while not query1.eof...
// 上面这段过程预先分配数值给一个2维实数数组
finally
FreeMem(pArrayOfResult, query2.recordcount * query3.recordcount * SizeOf(real));
end;
{try}
end;
procedure Tdanaprintfrm.FormDestroy(Sender: TObject);
var i,j:integer;
begin
for i:=0 to query2.RecordCount-1do
pks_array.free;
for j:=0 to query3.RecordCount -1do
pfl_array[j].free;
// for i:=0 to query2.recordcount -1do
// for j := 0 to query3.recordcount -1do
// psum_array[i,j].free;
end;
end.