请问有没有好的方法做横着打印的报表(100分)

  • 主题发起人 主题发起人 天堂鸟6420
  • 开始时间 开始时间

天堂鸟6420

Unregistered / Unconfirmed
GUEST, unregistred user!
大家好,我写了一个SQL结果如下
张三 一号 24 25
张三 二号 24 25
张三 三号 24 25 
..........
李四 一号 24 25
李四 二号 24 25
......
希望做出来的报表是
人员   一号 二号    ......
    数字1 数字2 数字1 数字2  ......
张三  24 25 24 25   ......
李四  24 25 24 25   ......
....................
请多提意见,最好写的循环能够精简和不用第三方控件(QR,EXCEL之外)
 
你把表结构给出来看看,或许有办法。
 
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB, StdCtrls, Buttons, Grids, DBGrids;
type
TForm1 = class(TForm)
ADODataSet1: TADODataSet;
ADODataSet2: TADODataSet;
BitBtn1: TBitBtn;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
DBGrid2: TDBGrid;
DataSource2: TDataSource;
procedure FormCreate(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
ADODataSet1.Close;
ADODataSet1.FieldDefs.Clear;
ADODataSet1.FieldDefs.Add('type', ftstring, 20, false);
ADODataSet1.FieldDefs.Add('month', ftstring, 10, false);
ADODataSet1.FieldDefs.Add('money', ftinteger, 0, false);
ADODataSet1.CreateDataSet;
ADODataSet1.Open;
ADODataSet1.Append;
ADODataSet1.FieldByName('type').AsString := 'A1';
ADODataSet1.FieldByName('month').AsString := '1月';
ADODataSet1.FieldByName('money').AsInteger := 200;
ADODataSet1.Append;
ADODataSet1.FieldByName('type').AsString := 'A1';
ADODataSet1.FieldByName('month').AsString := '1月';
ADODataSet1.FieldByName('money').AsInteger := 201;
ADODataSet1.Append;
ADODataSet1.FieldByName('type').AsString := 'A1';
ADODataSet1.FieldByName('month').AsString := '2月';
ADODataSet1.FieldByName('money').AsInteger := 200;
ADODataSet1.Append;
ADODataSet1.FieldByName('type').AsString := 'A1';
ADODataSet1.FieldByName('month').AsString := '2月';
ADODataSet1.FieldByName('money').AsInteger := 202;
ADODataSet1.Append;
ADODataSet1.FieldByName('type').AsString := 'A1';
ADODataSet1.FieldByName('month').AsString := '3月';
ADODataSet1.FieldByName('money').AsInteger := 200;
ADODataSet1.Append;
ADODataSet1.FieldByName('type').AsString := 'A1';
ADODataSet1.FieldByName('month').AsString := '3月';
ADODataSet1.FieldByName('money').AsInteger := 203;
ADODataSet1.Append;
ADODataSet1.FieldByName('type').AsString := 'A2';
ADODataSet1.FieldByName('month').AsString := '1月';
ADODataSet1.FieldByName('money').AsInteger := 100;
ADODataSet1.Append;
ADODataSet1.FieldByName('type').AsString := 'A2';
ADODataSet1.FieldByName('month').AsString := '1月';
ADODataSet1.FieldByName('money').AsInteger := 101;
ADODataSet1.Append;
ADODataSet1.FieldByName('type').AsString := 'A2';
ADODataSet1.FieldByName('month').AsString := '2月';
ADODataSet1.FieldByName('money').AsInteger := 100;
ADODataSet1.Append;
ADODataSet1.FieldByName('type').AsString := 'A2';
ADODataSet1.FieldByName('month').AsString := '2月';
ADODataSet1.FieldByName('money').AsInteger := 102;
ADODataSet1.Append;
ADODataSet1.FieldByName('type').AsString := 'A2';
ADODataSet1.FieldByName('month').AsString := '3月';
ADODataSet1.FieldByName('money').AsInteger := 100;
ADODataSet1.Append;
ADODataSet1.FieldByName('type').AsString := 'A2';
ADODataSet1.FieldByName('month').AsString := '3月';
ADODataSet1.FieldByName('money').AsInteger := 103;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
var
i, m, n: integer;
str, strMonth: string;
begin
ADODataSet2.Close;
ADODataSet2.FieldDefs.Clear;
ADODataSet2.FieldDefs.Add('type', ftstring, 20, false);
with ADODataSet1do
begin
first;
while not eofdo
begin
str := FieldByName('month').AsString;
if ADODataSet2.FieldDefs.IndexOf(str) < 0 then
ADODataSet2.FieldDefs.Add(str, ftinteger, 0, false);
next;
end;
ADODataSet2.CreateDataSet;
ADODataSet2.Open;
first;
while not eofdo
begin
str := FieldByName('type').AsString;
if not ADODataSet2.Locate('type', str, [loCaseInsensitive, loPartialKey]) then
begin
ADODataSet2.Append;
ADODataSet2.FieldByName('type').AsString := str;
for i := 1 to ADODataSet2.FieldCount - 1do
ADODataSet2.Fields.AsInteger := 0;
end;
next;
end;

first;
while not eofdo
begin
str := FieldByName('type').AsString;
strMonth := FieldByName('month').AsString;
m := FieldByName('money').AsInteger;
ADODataSet2.Locate('type', str, [loCaseInsensitive, loPartialKey]);
n := ADODataSet2.FieldByName(strMonth).AsInteger;
ADODataSet2.Edit;
ADODataSet2.FieldByName(strMonth).AsInteger := m + n;
next;
end;

end;
end;

end.

object Form1: TForm1
Left = 192
Top = 103
Width = 544
Height = 375
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object BitBtn1: TBitBtn
Left = 8
Top = 176
Width = 75
Height = 25
Caption = 'BitBtn1'
TabOrder = 0
OnClick = BitBtn1Click
end
object DBGrid1: TDBGrid
Left = 104
Top = 48
Width = 320
Height = 120
DataSource = DataSource1
TabOrder = 1
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = 'MS Sans Serif'
TitleFont.Style = []
end
object DBGrid2: TDBGrid
Left = 104
Top = 224
Width = 320
Height = 120
DataSource = DataSource2
TabOrder = 2
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = 'MS Sans Serif'
TitleFont.Style = []
end
object ADODataSet1: TADODataSet
Parameters = <>
Left = 32
Top = 16
end
object ADODataSet2: TADODataSet
Parameters = <>
Left = 32
Top = 208
end
object DataSource1: TDataSource
DataSet = ADODataSet1
Left = 136
Top = 16
end
object DataSource2: TDataSource
DataSet = ADODataSet2
Left = 136
Top = 200
end
end
 
就是统计每个人在某个月的每天做了几个单子,每天得了多少钱,然后打印出来,
其中:接件单表--(对应接件单号)--接件人员表--(人员编码)--部门人员表
SQL写了很长一段,很麻烦的
 
有一个简单的办法,利用交叉表查询或者嵌套查询生成需要的查询结果再打印就可以了
 
你把表结构给出来,说不准能用子查询搞定。
 
接件表:接件单号,接见日期(日期时间型),费用等
接件人员表:接件单号人员编码等
部门人员:人员姓名,人员编号
我写的SQL类似于:
select 人员姓名,
接件日期=convert(VARCHAR(10),接见日期),
接见数量=count(*),
所得费用=(费用/接见人数)
from 接见表,接见人员表,部门人员表
group by convert(VARCHAR(10),接见日期)
报表要求:
人员 1号的数量,1号的费用.........31号的数量,31号的费用 合计
............................................................
总计
其实我已经用EXCEL,做出来了,只是查询和数据转换用的循环太多消耗时间太长,基本上100个人的报表要用30秒,如果有几千个人或者多个用户同时查询的话系统怎么能承担的起哟

 
你可以试试下面的SQL语句(MSSQL7。0或2000)
SQL:
select
人员 = (select 人员姓名 from 部门人员where 人员编号=a.人员编号),
1号的数量=(select count(*) from 接件表 where (接件单号=a.接件单号) and (day(接见日期)=1)),
1号的费用=(select (费用/接见人数) from 接件表 where (接件单号=a.接件单号) and (day(接见日期)=1)),
2号的数量=(select count(*) from 接件表 where (接件单号=a.接件单号) and (day(接见日期)=2)),
2号的费用=(select (费用/接见人数) from 接件表 where (接件单号=a.接件单号) and (day(接见日期)=2)),
.....
31号的数量=(select count(*) from 接件表 where (接件单号=a.接件单号) and (day(接见日期)=31)),
31号的费用=(select (费用/接见人数) from 接件表 where (接件单号=a.接件单号) and (day(接见日期)=31)),
数量合计=(select count(*) from 接件表 where (接件单号=a.接件单号)),
费用合计=(select SUM(费用/接见人数) from 接件表 where (接件单号=a.接件单号))
from 接件人员表 as a group by 人员编号,order by 人员编码
unit select "总计",
号的数量=(select count(*) from 接件表 where (接件单号=a.接件单号) and (day(接见日期)=1)),
1号的费用=(select (费用/接见人数) from 接件表 where (接件单号=a.接件单号) and (day(接见日期)=1)),
2号的数量=(select count(*) from 接件表 where (接件单号=a.接件单号) and (day(接见日期)=2)),
2号的费用=(select (费用/接见人数) from 接件表 where (接件单号=a.接件单号) and (day(接见日期)=2)),
.....
31号的数量=(select count(*) from 接件表 where (接件单号=a.接件单号) and (day(接见日期)=31)),
31号的费用=(select (费用/接见人数) from 接件表 where (接件单号=a.接件单号) and (day(接见日期)=31)),
数量总计=(select count(*) from 接件表 where (接件单号=a.接件单号)),
费用总计=(select SUM(费用/接见人数) from 接件表 where (接件单号=a.接件单号))
from 接件人员表 as a order by 人员编码
 
^_^,这么多啊
 
看来没有人比我更好了,^_^
发分了
 
多人接受答案了。
 

Similar threads

D
回复
0
查看
850
DelphiTeacher的专栏
D
D
回复
0
查看
860
DelphiTeacher的专栏
D
D
回复
0
查看
689
DelphiTeacher的专栏
D
后退
顶部