第一个问题倒是可以用crosstab来解决,但是用crosstab免不了遇到问题2,就有点棘手第三个问题看起来不是问题,分组报表应该是可以的,可以看下fr的demo

解决方案 »

  1.   


    你说的第三个问题 fr 的demo中有解决吗???我看Demo中的报表也没有解决这个问题呀,它也把一个组的内容分在二页中显示了呀!
      

  2.   

    真的用使用FastReprot五六年?建立测试数据:CREATE TABLE tb([班级名称] nvarchar(20),[报刊名称] nvarchar(50),[订阅期限] nvarchar(20),[金额] float,[数量]int,[学生姓名] nvarchar(10),[学校名称] nvarchar(50))INSERT tb SELECT '601',N'中国卡通(故事版)','半年',36,1,'伊晰','新建区小学'UNION ALL SELECT '601','天天数学','半年',24,1,'黄胜旺','新建区小学' UNION ALL SELECT '601','天天语文','半年',29,1,'王婧','新建区小学' UNION ALL SELECT '601','小记者', '半年', 30 ,1,'邵韵','新建区小学' UNION ALL SELECT '601','小记者','半年',30 ,1,'李佳欣','新建区小学' UNION ALL SELECT '601','少年文摘','半年',48 ,1,'王娟','新建区小学' UNION ALL SELECT '601','少年文摘','半年',48,1,'严小青','新建区小学' UNION ALL SELECT '601','少年文摘','半年',48,1,'路瑶','新建区小学' UNION ALL SELECT '601','我们爱科学(中高年级)','半年',50,1,'黄河森','新建区小学' UNION ALL SELECT '601','我们爱科学(中高年级)','半年',50,1,'吕邦衍','新建区小学' UNION ALL SELECT '601','读书与作文','半年',27,1,'伊晰','新建区小学' UNION ALL SELECT '601','读书与作文','半年',27,1,'王俐','新建区小学' UNION ALL SELECT '601','读书与作文','半年',27,1,'邵韵','新建区小学' UNION ALL SELECT '601','趣味科学','半年',40,1,'吕邦衍','新建区小学' UNION ALL SELECT '602','天天数学','半年',24,1,'徐盈','新建区小学' UNION ALL SELECT '602','天天语文','半年',29,1,'徐盈','新建区小学' UNION ALL SELECT '602','小记者','半年',30 ,1,'蔡浩能','新建区小学' UNION ALL SELECT '602','红树林','半年',36,1,'吴子贤','新建区小学' UNION ALL SELECT '602','读书与作文','半年',27,1,'杨禀','新建区小学' UNION ALL SELECT '教导处','儿童文学','半年',66,1,'陈主任','新建区小学' UNION ALL SELECT '教导处','儿童文学','半年',66,1,'叶主任','新建区小学' UNION ALL SELECT '教导处','少年文摘','半年',48,1,'叶主任','新建区小学' UNION ALL SELECT '教导处','我们爱科学(中高年级)','半年',50,1,'陈主任','新建区小学'----取结果
    select '学校:'+' '+[学校名称]+' '+'班级:'+[班级名称] as ly,[报刊名称],[订阅期限],[金额],[数量],[学生姓名] from tb ORDER BY ly 
      

  3.   

    主要是将:'学校:'+' '+[学校名称]+' '+'班级:'+[班级名称] as ly 合成一个字段,排好序,在FastReprot如何做分组报表,你应该会的了.
      

  4.   

    如果要统计出各人共订了几本书可以这样:select a.ly as '学校加班级',a.l_name as '学生姓名',a.[报刊名称],a.[订阅期限],a.[金额],a.[数量],b.l_sum as '订刊数量' from
    (select '学校:'+' '+[学校名称]+' '+'班级:'+[班级名称] as ly,
    [报刊名称],[订阅期限],[金额],[数量],[学生姓名] as l_name from tb) a,
    (select '学校:'+' '+[学校名称]+' '+'班级:'+[班级名称] as ly,
    [学生姓名] l_name,sum(数量) l_sum from tb GROUP BY '学校:'+' '+[学校名称]+' '+'班级:'+[班级名称],[学生姓名]) b where a.ly=b.ly and a.l_name=b.l_name
    ---------结果
      

  5.   

    以上的忘了在最后加一句排序,如果不排序FastReprot中分组就实现不了.ORDER BY a.ly
      

  6.   

    不好意思,刚重新看了楼主的意思,以上的代码还能实现楼主的要求,更改以下代码可以实现了:
    分为三步:
    第一:在你的表中建一个字段名为:ly,期实就是用来记录:'学校:'+' '+[学校名称]+' '+'班级:'+[班级名称],作为FastReprot的依据
         到时你在FastReprot里就用字段LY为分条件.
    第二步:在SQL里建立一个自定义函数: CREATE FUNCTION dbo.f_str(@id nvarchar(50),@lvname nvarchar(50),@vvname nvarchar(50))RETURNS varchar(8000)ASBEGIN    DECLARE @r varchar(8000)    SET @r = ''    SELECT @r = @r + ',' + [学生姓名]    FROM tb------------------------------------注意你的表名及相关字段    WHERE ly=@id and [报刊名称]=@lvname and [班级名称]=@vvname    RETURN STUFF(@r, 1, 1, '')
    END
    第三:DELPHI入面的代码:  with adoquery1  do begin
     close;
     sql.Text:='update tb set ly=''学校:''+'' ''+[学校名称]+'' ''+''班级:''+[班级名称]';
     ExecSQL;
     close;
     sql.Text:='select ly,[报刊名称],[订阅期限],[金额],dbo.f_str(ly,[报刊名称],[班级名称]) as ''学生姓名'',count(*) as ''报刊合计'' from tb GROUP BY ly,[报刊名称],[订阅期限],[金额],dbo.f_str(ly,[报刊名称],[班级名称])';
     open;
     end;
    第四:adoquery1最后得到的数据集以下:/*学校: 新建区小学 班级:601 读书与作文                半年 27.0 伊晰,王俐,邵韵 3
    学校: 新建区小学 班级:601 趣味科学                         半年 40.0 吕邦衍          1
    学校: 新建区小学 班级:601 少年文摘                         半年 48.0 王娟,严小青,路瑶 3
    学校: 新建区小学 班级:601 天天数学                         半年 24.0 黄胜旺          1
    学校: 新建区小学 班级:601 天天语文                         半年 29.0 王婧          1
    学校: 新建区小学 班级:601 我们爱科学(中高年级)      半年 50.0 黄河森,吕邦衍 2
    学校: 新建区小学 班级:601 小记者                         半年 30.0 邵韵,李佳欣 2
    学校: 新建区小学 班级:601 中国卡通(故事版)              半年 36.0 伊晰          1
    学校: 新建区小学 班级:602 读书与作文                半年 27.0 杨禀          1
    学校: 新建区小学 班级:602 红树林                         半年 36.0 吴子贤          1
    学校: 新建区小学 班级:602 天天数学                         半年 24.0 徐盈          1
    学校: 新建区小学 班级:602 天天语文                         半年 29.0 徐盈          1
    学校: 新建区小学 班级:602 小记者                         半年 30.0 蔡浩能          1
    学校: 新建区小学 班级:教导处儿童文学                         半年 66.0 陈主任,叶主任 2
    学校: 新建区小学 班级:教导处 少年文摘                半年 48.0 叶主任          1
    学校: 新建区小学 班级:教导处 我们爱科学(中高年级) 半年 50.0 陈主任          1*/
      

  7.   

    很感谢你的回答,我理解你的意思,你是将SQL语句将表进行转换后再进行Fastreport 报表的制作,这样做报表时就不用考虑这么复杂了,但我用的Access数据表,有些语句无法使用!能改动些代码实现吗??
      

  8.   

    用DELPHI方式的实现:
    1.新建一个表,表名(TBB),数据结构如下:
    ly 文本型(用来记录由学校名称加上班级名称组成的内容)
    报型名称
    订阅期限
    金额(即报刊的价钱)
    学生姓名
    报刊合计(即有多少人订了这个报刊)
    2.delphi中用三个adoquery控件,设置如下:  adoquery1的SQL.TEXT是:select [学校名称],[班级名称],[报刊名称],[订阅期限],[金额] from tb GROUP BY [学校名称],[班级名称],[报刊名称],[订阅期限],[金额]  adoquery2的SQL.TEXT是:select [学校名称],[班级名称],[报刊名称],[订阅期限],[金额],[学生姓名] from 
    tb  where [学校名称]=:a 
    and [班级名称]=:b 
    and [报刊名称]=:c 
    and [订阅期限]=:d
    and [金额]=:e
    GROUP BY [学校名称],[班级名称],[报刊名称],[订阅期限],[金额],[学生姓名] 
      
      adoquery3的SQL.TEXT是:select * from tbb 3.delphi 的代码:
    procedure TForm1.Button1Click(Sender: TObject);
    var
    str:string;
    sname:widestring;
    begin
     with adoquery1 do begin
      if not Active then Active:=true;
      if not IsEmpty then begin {有资料的情况下}
        adoquery3.Open;
      while not eof do begin
         with adoquery2 do begin
          Close;
          with Parameters do begin
           ParamValues['a']:=adoquery1.FieldValues['学校名称'];
           ParamValues['b']:=adoquery1.FieldValues['班级名称'];
           ParamValues['c']:=adoquery1.FieldValues['报刊名称'];
           ParamValues['d']:=adoquery1.FieldValues['订阅期限'];
           ParamValues['e']:=adoquery1.FieldValues['金额'];
          end;
          open;
          if not isempty then begin
            str:='学校:'+' '+FieldValues['学校名称']+' '+'班级:'+FieldValues['班级名称'];
            while not eof do begin
            sname:=sname+widestring(FieldValues['学生姓名'])+widestring(',');
            next;
            end;
            First;
             adoquery3.Append;
             adoquery3.FieldValues['ly']:=str;
             adoquery3.FieldValues['报刊名称']:=FieldValues['报刊名称'];
             adoquery3.FieldValues['订阅期限']:=FieldValues['订阅期限'];
             adoquery3.FieldValues['金额']:=FieldValues['金额'];
             sname:=copy(sname,1,length(WideString(sname))-1);
             adoquery3.FieldValues['学生姓名']:=sname;
             adoquery3.FieldValues['报刊合计']:=RecordCount;
             adoquery3.Post;
            sname:='';
          end;
          close;
         end;
       next;
      end;
      end;
     end;
    end;
    4:报表的数据源连接新表tbb.
     建议报表中的姓名还要用表格形式,用如:邵韵,王俐,伊晰,一但人数太多时,表格太多一张纸显示不了这么多,而邵韵,王俐,伊晰这样可以折行显示.