程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 在Delphi中自己建立交叉表

在Delphi中自己建立交叉表

編輯:Delphi

  經常在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;
  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved