在Delphi中自己建立交叉表

原创 2003年08月04日 10:05:00

    经常在CSDN上查阅名位大侠的文章,得益不少,近期因做一个项目,需要用到交叉表,报表上倒是有,但客户要求在Grid上能操作,没有办法,只好自己写了一段代码用于普通查询到交叉表的实现,不敢独享,故上传,望能抛砖引玉,请名位大侠不吝指教。


function CreateTmptab(const AFieldDefs:TFieldDefs):TDataSet;
var
TempTable:TatClientDataSet;
begin
TempTable:=nil;
Result:=nil;
if AFieldDefs<>nil then
begin
    try
        TempTable:=TatClientDataSet.Create(Application);
        TempTable.FieldDefs.Assign(AFieldDefs);
        TempTable.CreateDataSet;
        Result:=(TempTable as TDataSet);
    Except
    if TempTable<>nil then
        TempTable.Free;
        Result:=nil;
        raise;
    end
end;
end;
{
SouDataset源数据集
ColField交叉表动态列字段
RowField交叉表行字段
DataField数据字段
}
function GenCrossTable(SouDataset:tdataset;ColField,RowField,DataField:string):tdataset;
var
Vdataset:tdataset;
tmpdataset:tatclientdataset;
DataSource:tdatasource;
tmpstrs:tstrings;
rowval,colval,dataval:string;
i,j:integer;
datatype:TFieldType;
DataSize:integer;
begin
result:=nil;
if (ColField='') or(RowField='')or(DataField='') then
  showmessage('All Field not be NULL!')
else
begin
  if (ColField=RowField)
      or(ColField=DataField)
      or(RowField=DataField) then
    showmessage('All Field not be Equ!')
  else
  if (self.SouDataSet.FieldByName(ColField).DataType=ftString)
    or (self.SouDataSet.FieldByName(ColField).DataType<>ftWideString)
    or (self.SouDataSet.FieldByName(ColField).DataType<>ftFixedChar)
    or (self.SouDataSet.FieldByName(ColField).DataType<>ftMemo)
    or (self.SouDataSet.FieldByName(ColField).DataType<>ftFmtMemo)  then
  begin
  try
    tmpstrs:=tstringlist.Create;
    Vdataset:=SouDataSet;
    Vdataset.First;
    for i:=0 to Vdataset.RecordCount-1 do
    begin
      if (varisnull(SouDataSet.FieldValues[colfield])=false) and (SouDataSet.FieldValues[colfield]<>'') then
        if tmpstrs.IndexOf(SouDataSet.FieldValues[colfield])=-1 then
        begin
          tmpstrs.Add(SouDataSet.FieldValues[colfield]);
        end;
      Vdataset.Next;
    end;
    //生成动态列标题
    tmpdataset:=TClientDataSet.Create(Self);
    tmpdataset.FieldDefs.Add(rowfield,ftstring,50,False);
    for i:=0 to tmpstrs.Count-1 do
    begin
      with tmpdataset.FieldDefs do
      begin
        Add(tmpstrs.Strings[i],ftInteger,0,False);
      end;
    end;
    tmpdataset.FieldDefs.Add('Sum',ftInteger,0,False);
    DataSource:=tdatasource.Create(self);
    DataSource.DataSet:=tmpdataset;
    with DataSource do
    begin
      dataset:=Createtmptab(tmpdataset.FieldDefs);
      dataset.Open;
    end;
    //建立临时表
    Vdataset.First;
    for i:=0 to Vdataset.RecordCount-1 do
    begin
      rowval:=SouDataSet.fieldbyname(rowfield).AsString;
      colval:=SouDataSet.fieldbyname(colfield).AsString;
      dataval:=SouDataSet.fieldbyname(datafield).AsString;
      if dataval='' then dataval:='0';
      if DataSource.DataSet.Locate(rowfield,rowval,[loPartialKey]) then
      begin
        DataSource.DataSet.Edit;
        DataSource.DataSet.FieldByName(colval).AsString:=dataval;
        DataSource.DataSet.FieldByName('Sum').AsInteger:=
          DataSource.DataSet.FieldByName('Sum').AsInteger+strtoint(dataval);
        DataSource.DataSet.Post;
      end
      else
      begin
        DataSource.DataSet.Append;
        DataSource.DataSet.FieldByName(rowfield).AsString:=rowval;
        for j:=1 to DataSource.DataSet.Fields.Count-1 do
          DataSource.DataSet.Fields[j].AsCurrency:=0;
        DataSource.DataSet.FieldByName(colval).AsString:=dataval;
        DataSource.DataSet.FieldByName('Sum').AsString:=dataval;
        DataSource.DataSet.Post;
      end;
      Vdataset.Next;
    end;
    result:=DataSource.DataSet;
    //生成交叉表数据集
    tmpstrs.Free;
  except
  end;
  end
  else
    showmessage('ColField Must be of Type String!') ;
end;
end;

以上代码在D7和SQL Server 7.0/2000测试通过

交叉表实例

交叉表实例  建表:  在查询分析器里运行:  CREATE TABLE [Test] (  [id] [int] IDENTITY (1, 1) NOT NULL ,  [name] [nvarch...
  • jing12
  • jing12
  • 2008年02月22日 13:44
  • 307

如何利用FastReport创建交叉报表?

转自:http://www.fastreportcn.com/Article/92.html 本文我们将创建一个交叉报表,用于显示员工四年中的工资。要创建交叉报表,我们需要使用到Fa...
  • cw370008359
  • cw370008359
  • 2014年12月11日 13:24
  • 1118

MSSQL交叉表查询

交叉表查询
  • EFU0387
  • EFU0387
  • 2017年05月29日 12:41
  • 188

delphi中如何对主从表进行级联删除?

我不知道是不是在sqlserver2000中进行表结构设计时可以做到?还是在代码里直接写?我用的是adotable定位这条记录,然后delete此记录。 以前oracle设计表结构时好像可以做到另外,...
  • zhangbo_amy
  • zhangbo_amy
  • 2005年08月17日 23:02
  • 1329

关于Delphi内存表的使用说明

关于Delphi内存表的使用说明: 1.建立临时表    数据输入是开发数据库程序的必然环节。在Client/Server结构中,客户端可能要输入一批数据后,再向服务器的后台数据库提交,这就需...
  • yanjinrong
  • yanjinrong
  • 2014年09月18日 20:21
  • 469

ReportStudio入门教程(三十) - 交叉表

我们前面的例子都是使用列表,
  • jolingogo
  • jolingogo
  • 2014年04月16日 13:55
  • 2366

javascript实现多表头分类交叉报表:html表格

DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> HTML> HEAD> HEAD> BODY> div id...
  • KimmKing
  • KimmKing
  • 2007年10月21日 23:03
  • 7631

9、spss做交叉表检验和对应分析

前边我们已经讲过很多内容了。回顾一下,主要有相关分析,假设检验,和各种回归。以及因子分析。我们知道,对于两组连续变量,我们可以通过假设检验来判断他们的分布是否相同,差异时候存在。不知道大家想过没有,如...
  • NIeson2012
  • NIeson2012
  • 2015年04月15日 15:35
  • 3079

Delphi自定义类

重温Delphi之:如何定义一个类 先谈谈工具问题: 虽然d7很经典,但毕竟是02年出的开发工具了,对于习惯了vs2008被微软宠坏的.net程序员来讲,重返d7已经有点找不着感觉了(...
  • Yoryky
  • Yoryky
  • 2014年11月20日 12:56
  • 633

SQL动态生成交叉表应用范例

交叉表的应用较为丰富,应用的方式与范围也是十分丰富。
  • qiushuisen
  • qiushuisen
  • 2014年10月17日 07:26
  • 1187
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:在Delphi中自己建立交叉表
举报原因:
原因补充:

(最多只允许输入30个字)