QuickReport做动态报表做成动态链接库,退出预览时怎么释放控件呀? ( 积分: 150 )

  • 主题发起人 主题发起人 sayur
  • 开始时间 开始时间
S

sayur

Unregistered / Unconfirmed
GUEST, unregistred user!
procedure TfrmPrintDlg.CreateReport(Sender: TObject);
Var
I:Byte;
CHBlf,ObWidth:Word;
DlgMes:string;
begin
TotalFieldNum:=0;
ClientDataSet1.First;
for i:=1 to ClientDataSet1.RecordCountdo
begin
if ClientDataSet1.FieldByName('IsPrint').AsBoolean =True then
Inc(TotalFieldNum);
ClientDataSet1.Next;
end;
if TotalFieldNum=0 then
begin
ClientDataSet1.EnableControls ;
Messagebox(Application.Handle,'对不起,您还没有选择要打印的字段!','预览',MB_IconError+MB_Ok);
Exit;
end;

Screen.Cursor:=crHourGlass;
CHBlf:=0;
//建立的控件在带区中的左边位置
ObWidth:=0;
//建立的控件的宽度
PrintFieldNum:=0;
//需打印的字段
//建立报表标题
PHB.Height :=60;
RpTitle:=TQRLabel.Create(PHB);
RpTitle.Parent :=PHB;
RpTitle.AutoSize :=False;
RpTitle.Top :=PHB.Top;
RpTitle.Left :=PHB.Left;
RpTitle.Height :=PHB.Height;
RpTitle.Width :=PHB.Width;
RpTitle.Caption :=ReportTT.Text;
RpTitle.Alignment :=taCenter;
//控件名数组分配空间
SetLength(ColumnCaption,TotalFieldNum);
SetLength(ColumnDB,TotalFieldNum);
ClientDataSet1.First;
for i:=0 to ClientDataSet1.RecordCount-1do
begin

if ClientDataSet1.FieldByName('IsPrint').AsBoolean =False then
begin
ClientDataSet1.Next;
Continue;
end;
//获得对齐方式
if ClientDataSet1.FieldByName('Align').AsString ='左对齐' then
DJ:=taleftJustify
else
if ClientDataSet1.FieldByName('Align').AsString ='右对齐' then
DJ:=taRightJustify
else
if ClientDataSet1.FieldByName('Align').AsString ='居中对齐' then
DJ:=taCenter
else
DJ:=taleftJustify;
//获得列宽
if ClientDataSet1.FieldByName('ColumnWidth').IsNull then
ObWidth:=60
else
ObWidth:=ClientDataSet1.FieldByName('ColumnWidth').AsInteger;
if CHBlf+ObWidth>=HB.Width then
begin
//建立控件>纸宽?
DlgMes:='纸张宽度不够,请更改纸张尺寸。';
MessageBox(Application.Handle,Pchar(DlgMes),'报表',Mb_IconInformation+MB_Ok);
break;
end
else
begin
Inc(PrintFieldNum);
ColumnCaption[PrintFieldNum-1]:=TQRLabel.Create(HB);//建立列标头带区线条控件
ColumnCaption[PrintFieldNum-1].Parent:=HB;
ColumnCaption[PrintFieldNum-1].AutoSize :=False;
ColumnCaption[PrintFieldNum-1].Top:=0;
ColumnCaption[PrintFieldNum-1].Left:=CHBlf;
ColumnCaption[PrintFieldNum-1].Width:=ObWidth;
ColumnCaption[PrintFieldNum-1].Height:=HB.Height;
ColumnCaption[PrintFieldNum-1].Alignment :=DJ;
ColumnCaption[PrintFieldNum-1].Caption :=ClientDataSet1.FieldByName('FieldCaption').AsString;//取字段作为列名
ColumnDB[PrintFieldNum-1]:=TQRDBText.Create(DB);
//建立细节带区线条控件
ColumnDB[PrintFieldNum-1].Parent:=DB;
ColumnDB[PrintFieldNum-1].ParentReport:=QuickRep;
ColumnDB[PrintFieldNum-1].AutoSize :=False;
ColumnDB[PrintFieldNum-1].Top:=0;
ColumnDB[PrintFieldNum-1].Left:=CHBlf;
ColumnDB[PrintFieldNum-1].Width:=ObWidth;
ColumnDB[PrintFieldNum-1].Height:=DB.Height-1;
ColumnDB[PrintFieldNum-1].Alignment :=DJ;
ColumnDB[PrintFieldNum-1].DataSet :=ADOQry;
ColumnDB[PrintFieldNum-1].DataField :=ClientDataSet1.FieldByName('FieldName').AsString ;
//边框
if ChkBorder.Checked then
begin
ColumnCaption[PrintFieldNum-1].Frame.DrawTop :=True;
ColumnCaption[PrintFieldNum-1].Frame.DrawBottom :=True;
ColumnCaption[PrintFieldNum-1].Frame.DrawLeft :=True;
ColumnCaption[PrintFieldNum-1].Frame.DrawRight :=True;
ColumnDB[PrintFieldNum-1].Frame.DrawTop :=True;
ColumnDB[PrintFieldNum-1].Frame.DrawBottom :=True;
ColumnDB[PrintFieldNum-1].Frame.DrawLeft :=True;
ColumnDB[PrintFieldNum-1].Frame.DrawRight :=True;
end;

CHBlf:=CHBlf+ObWidth;//当前字段处理完成,往右一个字段宽度
end;
ClientDataSet1.Next;
end;
//end for
Screen.Cursor:=crDefault;
QuickRep.DataSet :=ADOQry;
QuickRep.Preview;
end;
我在报表预览结束时清除报表
procedure TfrmPrintDlg.ClearRep();//清除生成报表格式时建立的控件
Var
I:Byte;
begin

//清除报表标题
RpTitle.Free;
RpTitle:=Nil;
if PrintFieldNum>0 then
For I:=0 to PrintFieldNum-1do
begin
//列标题
if Assigned(ColumnCaption) then
begin
ColumnCaption.Free;
ColumnCaption:=nil;
end;

if Assigned(ColumnDB) then
begin
ColumnDB.Free;
ColumnDB:=nil;
end;
end;
end;
为什么这样做每次退出预览时就出错呢?是不是释放有问题,还是其它哪里有问题?请各位帮忙看看.
 
procedure TfrmPrintDlg.CreateReport(Sender: TObject);
Var
I:Byte;
CHBlf,ObWidth:Word;
DlgMes:string;
begin
TotalFieldNum:=0;
ClientDataSet1.First;
for i:=1 to ClientDataSet1.RecordCountdo
begin
if ClientDataSet1.FieldByName('IsPrint').AsBoolean =True then
Inc(TotalFieldNum);
ClientDataSet1.Next;
end;
if TotalFieldNum=0 then
begin
ClientDataSet1.EnableControls ;
Messagebox(Application.Handle,'对不起,您还没有选择要打印的字段!','预览',MB_IconError+MB_Ok);
Exit;
end;

Screen.Cursor:=crHourGlass;
CHBlf:=0;
//建立的控件在带区中的左边位置
ObWidth:=0;
//建立的控件的宽度
PrintFieldNum:=0;
//需打印的字段
//建立报表标题
PHB.Height :=60;
RpTitle:=TQRLabel.Create(PHB);
RpTitle.Parent :=PHB;
RpTitle.AutoSize :=False;
RpTitle.Top :=PHB.Top;
RpTitle.Left :=PHB.Left;
RpTitle.Height :=PHB.Height;
RpTitle.Width :=PHB.Width;
RpTitle.Caption :=ReportTT.Text;
RpTitle.Alignment :=taCenter;
//控件名数组分配空间
SetLength(ColumnCaption,TotalFieldNum);
SetLength(ColumnDB,TotalFieldNum);
ClientDataSet1.First;
for i:=0 to ClientDataSet1.RecordCount-1do
begin

if ClientDataSet1.FieldByName('IsPrint').AsBoolean =False then
begin
ClientDataSet1.Next;
Continue;
end;
//获得对齐方式
if ClientDataSet1.FieldByName('Align').AsString ='左对齐' then
DJ:=taleftJustify
else
if ClientDataSet1.FieldByName('Align').AsString ='右对齐' then
DJ:=taRightJustify
else
if ClientDataSet1.FieldByName('Align').AsString ='居中对齐' then
DJ:=taCenter
else
DJ:=taleftJustify;
//获得列宽
if ClientDataSet1.FieldByName('ColumnWidth').IsNull then
ObWidth:=60
else
ObWidth:=ClientDataSet1.FieldByName('ColumnWidth').AsInteger;
if CHBlf+ObWidth>=HB.Width then
begin
//建立控件>纸宽?
DlgMes:='纸张宽度不够,请更改纸张尺寸。';
MessageBox(Application.Handle,Pchar(DlgMes),'报表',Mb_IconInformation+MB_Ok);
break;
end
else
begin
Inc(PrintFieldNum);
ColumnCaption[PrintFieldNum-1]:=TQRLabel.Create(HB);//建立列标头带区线条控件
ColumnCaption[PrintFieldNum-1].Parent:=HB;
ColumnCaption[PrintFieldNum-1].AutoSize :=False;
ColumnCaption[PrintFieldNum-1].Top:=0;
ColumnCaption[PrintFieldNum-1].Left:=CHBlf;
ColumnCaption[PrintFieldNum-1].Width:=ObWidth;
ColumnCaption[PrintFieldNum-1].Height:=HB.Height;
ColumnCaption[PrintFieldNum-1].Alignment :=DJ;
ColumnCaption[PrintFieldNum-1].Caption :=ClientDataSet1.FieldByName('FieldCaption').AsString;//取字段作为列名
ColumnDB[PrintFieldNum-1]:=TQRDBText.Create(DB);
//建立细节带区线条控件
ColumnDB[PrintFieldNum-1].Parent:=DB;
ColumnDB[PrintFieldNum-1].ParentReport:=QuickRep;
ColumnDB[PrintFieldNum-1].AutoSize :=False;
ColumnDB[PrintFieldNum-1].Top:=0;
ColumnDB[PrintFieldNum-1].Left:=CHBlf;
ColumnDB[PrintFieldNum-1].Width:=ObWidth;
ColumnDB[PrintFieldNum-1].Height:=DB.Height-1;
ColumnDB[PrintFieldNum-1].Alignment :=DJ;
ColumnDB[PrintFieldNum-1].DataSet :=ADOQry;
ColumnDB[PrintFieldNum-1].DataField :=ClientDataSet1.FieldByName('FieldName').AsString ;
//边框
if ChkBorder.Checked then
begin
ColumnCaption[PrintFieldNum-1].Frame.DrawTop :=True;
ColumnCaption[PrintFieldNum-1].Frame.DrawBottom :=True;
ColumnCaption[PrintFieldNum-1].Frame.DrawLeft :=True;
ColumnCaption[PrintFieldNum-1].Frame.DrawRight :=True;
ColumnDB[PrintFieldNum-1].Frame.DrawTop :=True;
ColumnDB[PrintFieldNum-1].Frame.DrawBottom :=True;
ColumnDB[PrintFieldNum-1].Frame.DrawLeft :=True;
ColumnDB[PrintFieldNum-1].Frame.DrawRight :=True;
end;

CHBlf:=CHBlf+ObWidth;//当前字段处理完成,往右一个字段宽度
end;
ClientDataSet1.Next;
end;
//end for
Screen.Cursor:=crDefault;
QuickRep.DataSet :=ADOQry;
QuickRep.Preview;
end;
我在报表预览结束时清除报表
procedure TfrmPrintDlg.ClearRep();//清除生成报表格式时建立的控件
Var
I:Byte;
begin

//清除报表标题
RpTitle.Free;
RpTitle:=Nil;
if PrintFieldNum>0 then
For I:=0 to PrintFieldNum-1do
begin
//列标题
if Assigned(ColumnCaption) then
begin
ColumnCaption.Free;
ColumnCaption:=nil;
end;

if Assigned(ColumnDB) then
begin
ColumnDB.Free;
ColumnDB:=nil;
end;
end;
end;
为什么这样做每次退出预览时就出错呢?是不是释放有问题,还是其它哪里有问题?请各位帮忙看看.
 
请在报表/统计图形中提问。
 
gzhubin@163.com,加说明
 
嘿,我也有一个动态生成报表的QR,你留Email,我发你瞧瞧,不过对于报表的释放,一般都是在SHOW后面跟着FREE来保证在报表退出后对其进行释放的
 
在哪一步出问题的?跟踪一下
我一般用TList来保存,你也可以尝试一下,我帮你修改了一下,看看能满足你的要求不
var
ColumnDB , ColumnCaption : TList;
ColumnDB := TList.Create;
ColumnCaption := TList.Create;
上面几个声明一下,和你定义数组的地方一样就行了,记得最后释放
procedure TfrmPrintDlg.CreateReport(Sender: TObject);
Var
I:Byte;
CHBlf,ObWidth:Word;
DlgMes:string;
QRLabel: TQRLabel;
QRDBText: TQRDBText;
begin
TotalFieldNum:=0;
ClientDataSet1.First;
for i:=1 to ClientDataSet1.RecordCountdo
begin
if ClientDataSet1.FieldByName('IsPrint').AsBoolean =True then
Inc(TotalFieldNum);
ClientDataSet1.Next;
end;
if TotalFieldNum=0 then
begin
ClientDataSet1.EnableControls ;
Messagebox(Application.Handle,'对不起,您还没有选择要打印的字段!','预览',MB_IconError+MB_Ok);
Exit;
end;

Screen.Cursor:=crHourGlass;
CHBlf:=0;
//建立的控件在带区中的左边位置
ObWidth:=0;
//建立的控件的宽度
PrintFieldNum:=0;
//需打印的字段
//建立报表标题
PHB.Height :=60;
RpTitle:=TQRLabel.Create(PHB);
RpTitle.Parent :=PHB;
RpTitle.AutoSize :=False;
RpTitle.Top :=PHB.Top;
RpTitle.Left :=PHB.Left;
RpTitle.Height :=PHB.Height;
RpTitle.Width :=PHB.Width;
RpTitle.Caption :=ReportTT.Text;
RpTitle.Alignment :=taCenter;
//控件名数组分配空间
ClientDataSet1.First;
for i:=0 to ClientDataSet1.RecordCount-1do
begin

if ClientDataSet1.FieldByName('IsPrint').AsBoolean =False then
begin
ClientDataSet1.Next;
Continue;
end;
//获得对齐方式
if ClientDataSet1.FieldByName('Align').AsString ='左对齐' then
DJ:=taleftJustify
else
if ClientDataSet1.FieldByName('Align').AsString ='右对齐' then
DJ:=taRightJustify
else
if ClientDataSet1.FieldByName('Align').AsString ='居中对齐' then
DJ:=taCenter
else
DJ:=taleftJustify;
//获得列宽
if ClientDataSet1.FieldByName('ColumnWidth').IsNull then
ObWidth:=60
else
ObWidth:=ClientDataSet1.FieldByName('ColumnWidth').AsInteger;
if CHBlf+ObWidth>=HB.Width then
begin
//建立控件>纸宽?
DlgMes:='纸张宽度不够,请更改纸张尺寸。';
MessageBox(Application.Handle,Pchar(DlgMes),'报表',Mb_IconInformation+MB_Ok);
break;
end
else
begin
Inc(PrintFieldNum);
QRLabel := TQRLabel.Create(HB);//建立列标头带区线条控件
with QRLabeldo
begin
Parent:=HB;
AutoSize :=False;
Top:=0;
Left:=CHBlf;
Width:=ObWidth;
Height:=HB.Height;
Alignment :=DJ;
Caption :=ClientDataSet1.FieldByName('FieldCaption').AsString;//取字段作为列名
end;
ColumnCaption.Add(QRLabel);
QRDBText := TQRDBText.Create(DB);
//建立细节带区线条控件
with QRDBTextdo
begin
Parent:=DB;
ParentReport:=QuickRep;
AutoSize :=False;
Top:=0;
Left:=CHBlf;
Width:=ObWidth;
Height:=DB.Height-1;
Alignment :=DJ;
DataSet :=ADOQry;
DataField :=ClientDataSet1.FieldByName('FieldName').AsString ;
end;
ColumnDB.Add(QRDBText);
//边框
if ChkBorder.Checked then
begin
with TQRLabel(ColumnCaption[PrintFieldNum-1]).Framedo
begin
DrawTop :=True;
DrawBottom :=True;
DrawLeft :=True;
DrawRight :=True;
end;
with TQRDBText(ColumnDB[PrintFieldNum-1]).Framedo
begin
DrawTop :=True;
DrawBottom :=True;
DrawLeft :=True;
DrawRight :=True;
end;
end;

CHBlf:=CHBlf+ObWidth;//当前字段处理完成,往右一个字段宽度
end;
ClientDataSet1.Next;
end;
//end for
Screen.Cursor:=crDefault;
QuickRep.DataSet :=ADOQry;
QuickRep.Preview;
end;

procedure TfrmPrintDlg.ClearRep();//清除生成报表格式时建立的控件
Var
I:Integer;
begin
//清除报表标题
RpTitle.Free;
For I:=0 to ColumnCaption.Count - 1do
begin
//列标题
TQRLabel(ColumnCaption.Items).Free;
TQRDBText(ColumnDB.Items).Free;
end;

// 这两个在你释放数组的地方释放就可以了,一般和TList.Create的对应地方
ColumnCaption.Free;
ColumnDB.Free;
//最后不用设置nil了,因为你用不到了,一般会有编译hint的
end;
 
就用 Grid++Report, 专门开发动态报表的报表构件。主页:http://www.rubylong.cn
 
后退
顶部