在Delphi中自己建立交叉表

2016-02-19 18:25 24 1 收藏

想不想get新技能酷炫一下,今天图老师小编就跟大家分享个简单的在Delphi中自己建立交叉表教程,一起来看看吧!超容易上手~

【 tulaoshi.com - 编程语言 】

 

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

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  
  function CreateTmptab(const AFieldDefs:TFieldDefs):TDataSet;
  var
  TempTable:TatClientDataSet;
  begin
  TempTable:=nil;
  Result:=nil;
  if AFieldDefsnil then
  begin
      try
          TempTable:=TatClientDataSet.Create(Application);
          TempTable.FieldDefs.Assign(AFieldDefs);
          TempTable.CreateDataSet;
          Result:=(TempTable as TDataSet);
      Except
      if TempTablenil 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).DataTypeftWideString)
      or (self.SouDataSet.FieldByName(ColField).DataTypeftFixedChar)
      or (self.SouDataSet.FieldByName(ColField).DataTypeftMemo)
      or (self.SouDataSet.FieldByName(ColField).DataTypeftFmtMemo)  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;
  

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

来源:https://www.tulaoshi.com/n/20160219/1617584.html

延伸阅读
Delphi中,用interbase控件访问InterBase数据库,并设置Dialect 3模式访问时,SQL语句中引用的 字符型字段 需要放在单引号(')内,如要在Delphi的IBQuery中实现该操作: select * from MyTable where name='zmxjh' 可以这样做:  SQL := 'select * from MyTable where name= '; &nbs...
                                         在Delphi7中调试COM+          &nb...
标签: Delphi
  资源是存放在扩展名.RES的文件里的二进制数据结构,在DELPHI中资源文件可以使用图象编辑器来制作(IMAGEEDITOR),或者使用其他的工具。如:BORLAND公司提供的RADPACKFORDELPHI中的RESOURCEWORKSHOP来创建。资源文件中通常存放的是应用程序可以随时存取的一些对象,包括:ICON、CURSOR、BITMAP、FONT等近十种。大部分的资源在通常的...
标签: Delphi
    一.DLL 库内存共享机制   从使用效果看,DLL和unit 很像,它们都可以被别的工程模块所调用,但二者在内部的实现机制上确存在着差别。如果一个程序模块中用uses语句引用了某个unit,编译程序在编译该模块时,便会连同unit一起编译,并把编译后的可执行代码链接到本程序模块中,这就是一个程序模块能够调用所引用unit中过程...
在Delphi中,要调用Chm文件可以通过引用HHctrl.ocx文件的函数HtmlHelpA实现。 不过在这里,我们也可以使用API函数ShellExecute来打开Chm帮助文件。 在网上找到的资料,通常以 ShellExecute(self.Handle,'open','help.chm','', '',SW_SHOW);? 的方式来实现。 但有个不足,就是不能打开指定的帮助页面,所...

经验教程

458

收藏

20
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部