私は CSDN で有名なヒーローの記事をよく読んでいて、とても役に立ちました。最近、プロジェクトに取り組んでおり、レポートにクロス集計を使用する必要がありましたが、顧客はそれをグリッド上で操作できるようにしたいと要望しました。クロス集計を実現するためのコードを自分で書くしかありませんでしたので、他の人にインスピレーションを与えることを願ってアップロードしました。有名な英雄からアドバイスをもらいました。
関数 CreateTmptab(const AFieldDefs:TFieldDefs):TDataSet;
変数
TempTable:TatClientDataSet;
始める
TempTable:=nil;
結果:=nil;
AFieldDefs<>nil の場合
始める
試す
TempTable:=TatClientDataSet.Create(アプリケーション);
TempTable.FieldDefs.Assign(AFieldDefs);
TempTable.CreateDataSet;
結果:=(TDataSet としての TempTable);
を除外する
TempTable<>nil の場合
TempTable.Free;
結果:=nil;
上げる;
終わり
終わり;
終わり;
{
SouDataset ソース データ セット
ColField クロス集計の動的列フィールド
RowField クロス集計行フィールド
DataFieldデータフィールド
}
関数 GenCrossTable(SouDataset:tdataset;ColField,RowField,DataField:string):tdataset;
変数
Vdataset:tdataset;
tmpdataset:tatclientdataset;
データソース:tdatasource;
tmpstrs:tstrings;
rowval、colval、dataval:文字列;
i,j:整数;
データ型:TFieldType;
データサイズ:整数;
始める
結果:=nil;
if (ColField='') または (RowField='') または (DataField='')
showmessage('すべてのフィールドは NULL ではありません!')
それ以外
始める
if (ColField=RowField)
or(ColField=データフィールド)
or(RowField=DataField) then
showmessage('すべてのフィールドが等しくありません!')
それ以外
if (self.SouDataSet.FieldByName(ColField).DataType=ftString)
または (self.SouDataSet.FieldByName(ColField).DataType<>ftwideString)
または (self.SouDataSet.FieldByName(ColField).DataType<>ftFixedChar)
または (self.SouDataSet.FieldByName(ColField).DataType<>ftMemo)
または (self.SouDataSet.FieldByName(ColField).DataType<>ftFmtMemo) その後
始める
試す
tmpstrs:=tstringlist.Create;
Vdataset:=SouDataSet;
Vdataset.First;
for i:=0 から Vdataset.RecordCount-1 まで
始める
if (varisnull(SouDataSet.FieldValues[colfield])=false) および (SouDataSet.FieldValues[colfield]<>'') then
if tmpstrs.IndexOf(SouDataSet.FieldValues[colfield])=-1 then
始める
tmpstrs.Add(SouDataSet.FieldValues[colfield]);
終わり;
Vdataset.Next;
終わり;
//動的な列タイトルを生成する
tmpdataset:=TClientDataSet.Create(Self);
tmpdataset.FieldDefs.Add(rowfield,ftstring,50,False);
for i:=0 から tmpstrs.Count-1 まで
始める
tmpdataset.FieldDefs を使用すると、
始める
Add(tmpstrs.Strings[i],ftInteger,0,False);
終わり;
終わり;
tmpdataset.FieldDefs.Add('Sum',ftInteger,0,False);
DataSource:=tdatasource.Create(self);
DataSource.DataSet:=tmpdataset;
データソースを使用して行う
始める
dataset:=Createtmptab(tmpdataset.FieldDefs);
データセットを開く;
終わり;
//一時テーブルを作成する
Vdataset.First;
for i:=0 から Vdataset.RecordCount-1 まで
始める
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
始める
DataSource.DataSet.Edit;
DataSource.DataSet.FieldByName(colval).AsString:=dataval;
DataSource.DataSet.FieldByName('Sum').AsInteger:=
DataSource.DataSet.FieldByName('Sum').AsInteger+strtoint(dataval);
DataSource.DataSet.Post;
終わり
それ以外
始める
DataSource.DataSet.Append;
DataSource.DataSet.FieldByName(rowfield).AsString:=rowval;
for j:=1 から DataSource.DataSet.Fields.Count-1 まで
DataSource.DataSet.Fields[j].AsCurrency:=0;
DataSource.DataSet.FieldByName(colval).AsString:=dataval;
DataSource.DataSet.FieldByName('Sum').AsString:=dataval;
DataSource.DataSet.Post;
終わり;
Vdataset.Next;
終わり;
結果:=DataSource.DataSet;
//クロス集計データセットを生成する
tmpstrs.無料。
を除外する
終わり;
終わり
それ以外
showmessage('ColField は文字列型である必要があります!') ;
終わり;
終わり;
上記のコードは、D7 および SQL Server 7.0/2000 でのテストに合格しました。