我想把stringgrid内容添加到RAVE报表中,请问大虾们如何做呢? (200分)

  • 主题发起人 主题发起人 大老虎
  • 开始时间 开始时间
关注中...
为什么没有人回答?
 
我想打印stringgrid 中的内容!怎么做啊!请高手指点啊!
 
期待高手!
 
内容的来源和去处,怎样,说明以下
 
我已经有一个stringgrid 譬如 stringgrid1 ,我想打印出表格中的内容!
就是
for i:=0 to stringgrid1.rowcountdo
for j:=0 to stringgrid1.colcountdo
begin
printer.canvas.textout(1,1,stringgrid1.cells[i,j]);
end
但是这样不行,打出的不象表格!
如何格式化打印!
 
ding ding ding ding....[:)][:)]
 
我用的是d7,请问如何利用rave打印stringgrid?
 
Delphi数据库开发及统计表格设计

Delphi是Borland公司开发的基于PASCAL语言的Windows平台应用程序开发工具,它将可视化编程(Visual Programming)与面向对象(Object-Oriented)的卓越优点结合在PASCAL语言开发平台上,而且同时可以支持Client/Server模式的SQL 数据库访问与ODBC(开发数据库互连),是一个真正面向对象的开发工具。

Delphi最吸引人的特点是它的强大的数据库访问能力,它主要通过使用数据库引擎(Borland Database Engine,简称BDE)来访问本地数据库和远程数据库。

但对于用户而言,不必直接编程访问BDE,而只需通过采用窗体(FORM)和大量方便且实用的数据库访问元件(Component)来实现,通过ReportSmith报表生成器可以生成多种随心所欲的报表。

但是,用ReportSmith制作的各类报表,只便于输出至打印机上打印出来,若想把报表在屏幕上显示,则还需调用ReportView。而ReportView窗口界面对不太懂Delphi和Windows操作的普通用户来说,不直观,也不易操作。如何制作并在屏幕上显示出直观的二维统计报表,这是本文所要阐述的主要问题。

以表格形式显示数据库内容一般地采用下面两种方式:
●纵向列表
●交叉统计列表

一、纵向列表

Delphi可以用TDBRID控件,以表格形式非常方便地显示单一或多数据库纵向列表。一般采用两种方法实现:

(一)采用TTable与Tdatasource、TDbgrid控件

在窗体中引入上述三个控件,并在Ttable中控件指出要访问的数据库存放路径及数据库名,在Tdatasource控件中指出数据源与Ttable相连,在TDbgrid控件中指出显示Tdatasource数据源内容,程序运行后,则显示出如图1所示的数据库纵向列表。

该种方法一般用来显示单数据库表格或一对多两个数据库表格。

(二)采用TQuery与Tdatasource、TDbgrid控件

同样,在窗体中引入上述三个控件,并在TQuery控件中用SQL语句给出对有关数据库的查询,在Tdatasource控件中指出数据源与TQuery相连,在TDbgrid控件中指出显示查询的结果。程序运行后,则显示出如图1所示的数据库纵向列表。

该种方法一般用于两个以上的多数据库查询。

在TQuery控件中建立SQL查询有两种方法,一种是在程序设计阶段使用SQL查询,即为静态查询,第二种是在程序运行阶段使用SQL查询,即为动态查询。

1.静态查询在编写程序时,在窗体中放置Tquery元件,并设置对象名称,如Query 1。使用Delphi对象检测器Object,双击Query 1对象的SQL属性,则激活SQL语句输入框,根据要求输入SELECT语句。当程序运行后,则显示出数据库纵向列表。静态查询比较简单,但实用性差。对于较复杂的查询,一般采用动态查询。

2.动态查询同样,在编写程序时,在窗体中放置TQUERY元件,并设置对象名称,如Query 1。在相关的事件函数中输入SQL语句,例如:

WITH QUERY 1do

begin

SQL.CLEAR;
SQL.ADD(‘SELECTDW
COUNT(DW)FROM B_BASETJ F
B_INFO E’);
SQL.ADD(‘WHERE F.”SHBZCODE”=E.”SHBZCODE”GROUP BY DW’);
OPEN;
end;

当程序运行后,由某一事件激发,则显示出查询结果纵向列表。

二、交叉统计列表

在Delphi环境下,无论用上述哪种方法制作数据库纵向列表,都是相对容易的。但要生成如图2所示二维统计报表,则并非易事。

下面以笔者开发的《社会养老保险管理系统--统计管理》中的一段程序为例,详细说明图2所示交叉统计列表的制作。
(一)调用数据库B_BASETJ.DB和B_INFO.DB

上述两数据库的结构分别为:
B_BASETJ.DB B_INFO.DB 字段名字段类型字段长度字段名字段类型字段长度
dw a 4(单位代码)shbzcode a 21(社会保障号码)
shbzcode a 21(社会保障号码)attribution a 10(工作属性)
cadre_zw a 4(干部职务)sex a 2(性别)

在B_INFO.DB数据库中存放着各人的基本情况,其中ATTRIBUTION字段包含固定工、农民合同工等工作属性;CADRE_ZW字段包含干部职务,若该字段内容为空,则表示为工人。

(二)窗口界面设计及各组件属性说明

用到的重要组件及其属性如下:
QYERYTB1:TQUERY;{指明SQL的存取元件名为QUERYTB1}
DataSourceTB1:Tdatasource;{指明与TQUERY相连的数据源为DatasourceTB1 }
Datasourcename=DataSourceTB1
Dataset=QYERYTB1
SG11:TstringGrid;{字符型二维数据表格}
BTNEXIT:Tbutton;{取消按钮}

(三)程序代码及其分析

程序中主要通过使用TStringGrid和TQUERY控件来生成交叉统计列表。其中T StringGrid控件以二维网格形式显示字符型数据表格,CELL[I
K]为表格中的一个数据单元,K为行号,I为列号,K、I的起始值为0;TQUERY控件的作用是利用SQL 语句统计出表格中某一列数据,如图2表格中共有6列,则需6次调用TQUERY。

本程序还设置了公共程序段procedure COL(var I
k:INTEGER),这一子程序将被多次调用,用于填写表格中某一列数据。
主要程序代码如下:
unit T1;
interface
uses
SysUtils
WinTypes
WinProcs
Messages
Classes
Graphics
Controls

Forms
Dialogs
StdCtrls
ExtCtrls
Grids
DB
DBTables
DBGrids
Report;
type
TT1FORM=class(TForm)
BTNEXIT:TButton;
SG11:TStringGrid;
Labell:TLabel;
QueryTB1:TQuery;
DataSourceTB1:TDataSource;
procedure FormCreate(Sender:TObject);
procedure BTNEXIT Click(Sender:TObject);
private
PROCEDURE COL(VAR I
K:INTEGER);
PROCEDURE CC(VAR I
K:INTEGER);
{Private declarations}
public
{Public declarations}
end;

var
T1FORM:TT1FORM;
implementation
{$R*.DFM}
PROCEDURE tt1form.COL(VAR I
K:INTEGER);{用FOR...DO循环填写SG11表格中第I列的VAR J:INTEGER;值}
begin

WITH SG11do

begin

QUERYTB1.FIRST;
FOR J:=2 TO K-1do

begin

IF CELLS[0
J]=QUERYTB1.FIELDS[0].ASSTRING{第0列填写单位代码}
then
begin

CELLS[I
J]:=QUERYTB1.FIELDS[1].ASSTRING;{填写第I列中某一行的值}
QUERYTB1.NEXT;
CELLS[I
1]:=INTTOSTR(STRTOINT(CELLS[I
1])+STRTOINT(CELLS[I
J]));
END
else
CELLS[I
J]:=INTTOSTR(0);
end;
{FOR}
end;
{WITH}
end;

PROCEDURE Tt1form.CC(VAR I
K:INTEGER);
VAR J:INTEGER;
begin

WITH SG11do

begin

FOR J:=1TO K-1do

CELLS[I
J]:=INTTOSTR(STRTOINT(CELLS[1
J]-STRTOINT(CELLS[I-1
J])));
end;
{WITH}
end;

procedure TT1FORM.FormCreate(Sender:TObject);{在创建窗体T1FORM时生成表格并填写统计值}
VAR R
I
K
J:INTEGER;
begin

WITH SGLLdo

begin
CELLS[0
0]:=’单位’{填写第0行各列标题}
CELLS[1
0]:=’总人数’;
CELLS[2
0]:=’固定’;
CELLS[3
0]:=’合同’;
CELLS[4
0]:=’干部’;
CELLS[5
0]:=’工人’;
FOR I:=1 TO 5do

begin

CELLS[I
1]:=INTTOSTR(0);
end;

end;

WITH QUERYTB1do

begin

SQL.CLEAR;
SQL.ADD(‘SELECT DW
COUNT(DW)FROM B_BASETJ F
B_INFO E’);
SQL.ADD(‘WHERE F.”SHBZCODE”=E.”SHBZCODE”GROUP BY DW’);
OPEN;
R:=RECORDCOUNT+2;
SG11.ROWCOUNT:=R;
SG11.CELLS[0
1]:=’合计’;
FIRST;
K:=R;
FOR J:=2 TO Kdo

begin
SG11.CELLS[0
J]:=FIELDS[0].ASSTRING;{填写第0列单位号}
NEXT;
end;

I:=1;
COL(I
K);{填写第1列合计}
SQL.CLEAR;
SQL.ADD(‘SELECT DW
COUNT(E.”DW”)’);
SQL.ADD(‘FROM“B_BASETJ.DB”E
B_INFO F WHERE E.”SHBZCODE”=F.”SHBZCODE”AND F.”ATTRIBUTION”=”固定职工”GROUP BY DW’);
I:=2;
OPEN;
COL(I
K);{填写第2列各单位固定工人数}
SQL.CLEAR;
SQL.ADD(‘SELECT DW
COUNT(E.”DW”)’);
SQL.ADD(‘FROM“B_BASETJ.DB”E
B_INFO F WHERE E.”SHBZCODE”=F.”SHBZCODE”AND F.”ATTRIBUTION”=”农民合同工”GROUP BY DW’);
I:=3;
CC(I
K);{填写第3列各单位合同工人数}
SQL.CLEAR;
SQL.ADD(‘SELECT DW
COUNT(E.”DW”)’);
SQL.ADD(‘FROM“B_BASETJ.DB”E
B_INFO F
WHERE E.”SHBZCODE”=F.”SHBZCODE”AND F.”CADRE_ZW”<>””GROUP B Y DW’);
I:=4;
OPEN;
COL(I
K);{填写第4列各单位干部人数}
I:=5;
CC(I
K);{填写第5列各单位工人人数}
end;

end;

......
end.
 
我用QR实现了具体做法如下:
打印按钮的代码:
procedure Tfrmingoods.printbuttonClick(Sender: TObject);
var
i:integer;
begin
if not assigned(frmpevingoods) then
begin
application.CreateForm(Tfrmpevingoods,frmpevingoods);
frmpevingoods.outgoodsid.Caption :=danjutext.Caption ;
frmpevingoods.clientshop.Caption :=supplyname.Text ;
frmpevingoods.currentdate.Caption :=datetext.Caption ;
frmpevingoods.operatorname.Caption :=operatename.Text ;
frmpevingoods.SomeList1:=Tstringlist.Create ;
frmpevingoods.SomeList2:=Tstringlist.Create ;
frmpevingoods.SomeList3:=Tstringlist.Create ;
frmpevingoods.SomeList5:=Tstringlist.Create ;
for i:=1 to listgrid.RowCount -1do
begin
frmpevingoods.SomeList1.Add(listgrid.Cells[2,i]);
frmpevingoods.SomeList2.Add(listgrid.Cells[5,i]);
frmpevingoods.SomeList3.Add(listgrid.Cells[6,i]);
frmpevingoods.SomeList5.Add(listgrid.Cells[7,i]);
end;
frmpevingoods.paycount.Caption :=totalmoney.Text ;
frmpevingoods.currentcount.Caption :=currentmoney.Text ;
frmpevingoods.paymentclass.Caption :=paymentbox.Text ;
frmpevingoods.QuickRep1.Preview ;
if assigned(frmpevingoods) then
frmpevingoods:=nil;
end;
end;
报表的代码如下:
unit pevingoods;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, QRCtrls, QuickRpt, ExtCtrls;
type
Tfrmpevingoods = class(TForm)
QuickRep1: TQuickRep;
QRBand1: TQRBand;
QRLabel1: TQRLabel;
QRSubDetail1: TQRSubDetail;
goodsname: TQRLabel;
outcount: TQRLabel;
outprice: TQRLabel;
totalmoney: TQRLabel;
GroupFooterBand1: TQRBand;
QRLabel6: TQRLabel;
QRLabel12: TQRLabel;
QRLabel13: TQRLabel;
QRLabel14: TQRLabel;
paycount: TQRLabel;
currentcount: TQRLabel;
paymentclass: TQRLabel;
QRShape2: TQRShape;
GroupHeaderBand1: TQRBand;
QRLabel7: TQRLabel;
QRLabel8: TQRLabel;
QRLabel9: TQRLabel;
QRLabel11: TQRLabel;
QRBand2: TQRBand;
QRLabel2: TQRLabel;
QRLabel3: TQRLabel;
QRLabel4: TQRLabel;
QRLabel5: TQRLabel;
outgoodsid: TQRLabel;
clientshop: TQRLabel;
currentdate: TQRLabel;
operatorname: TQRLabel;
QRShape1: TQRShape;
procedure QuickRep1BeforePrint(Sender: TCustomQuickRep;
var PrintReport: Boolean);
procedure QRSubDetail1NeedData(Sender: TObject;
var MoreData: Boolean);
private
{ Private declarations }
CurrentIndex: integer;
public
{ Public declarations }
SomeList1: TStringlist;
SomeList2: TStringlist;
SomeList3: TStringlist;
SomeList5: TStringlist;
end;

var
frmpevingoods: Tfrmpevingoods;
implementation
{$R *.dfm}
procedure Tfrmpevingoods.QuickRep1BeforePrint(Sender: TCustomQuickRep;
var PrintReport: Boolean);
begin
CurrentIndex:=0;
end;

procedure Tfrmpevingoods.QRSubDetail1NeedData(Sender: TObject;
var MoreData: Boolean);
begin
MoreData := (CurrentIndex < SomeList1.Count);
if MoreData then
begin
goodsname.Caption := SomeList1[CurrentIndex];
outcount.Caption := SomeList2[CurrentIndex];
outprice.Caption := SomeList3[CurrentIndex];
totalmoney.Caption := SomeList5[CurrentIndex];
end;
Inc(CurrentIndex);
end;

end.
 
能否用循环加参数传递的方法。
 

Similar threads

后退
顶部