电脑爱好者,提供IT资讯信息及各类编程知识文章介绍,欢迎大家来本站学习电脑知识。 最近更新 | 联系我们 RSS订阅本站最新文章
电脑爱好者
站内搜索: 
当前位置:首页>> delphi技术>>在Delphi中自己建立交叉表:

在Delphi中自己建立交叉表

来源:www.cncfan.com | 2006-1-10 | (有1796人读过)

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

delphi技术热门文章排行
网站赞助商
购买此位置

 

关于我们 | 网站地图 | 文档一览 | 友情链接| 联系我们

Copyright © 2003-2024 电脑爱好者 版权所有 备案号:鲁ICP备09059398号