在Delphi中自己建立交叉表 (转)

在Delphi中自己建立交叉表 (转)[@more@]

  经常在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测试通过


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752043/viewspace-959344/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10752043/viewspace-959344/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值