J'ai souvent lu des articles de héros célèbres sur CSDN et j'en ai beaucoup profité. Récemment, je travaillais sur un projet et j'avais besoin d'utiliser un tableau croisé dans le rapport, mais le client a demandé qu'il soit exploitable sur la grille. Je n'ai pas eu d'autre choix que de l'écrire moi-même. Un morceau de code est utilisé pour une requête générale pour réaliser le tableau croisé, je n'ose donc pas l'utiliser exclusivement, je le télécharge donc dans l'espoir qu'il puisse inspirer d'autres. quelques conseils de héros célèbres.
fonction CreateTmptab(const AFieldDefs:TFieldDefs):TDataSet;
var
TempTable : TatClientDataSet ;
commencer
TempTable :=néant ;
Résultat :=nul ;
si AFieldDefs<>nil alors
commencer
essayer
TempTable:=TatClientDataSet.Create(application);
TempTable.FieldDefs.Assign(AFieldDefs);
TempTable.CreateDataSet ;
Résultat :=(TempTable en tant que TDataSet);
Sauf
si TempTable<>nil alors
TempTable.Free;
Résultat :=nul ;
augmenter;
fin
fin;
fin;
{
Ensemble de données sources SouDataset
Champ de colonne dynamique de tableau croisé ColField
Champ de ligne du tableau croisé RowField
Champ de données DataField
}
function GenCrossTable(SouDataset:tdataset;ColField,RowField,DataField:string):tdataset;
var
Vdataset : tdataset ;
tmpdataset:tatclientdataset;
Source de données : tsource de données ;
tmpstrs:tstrings;
rowval,colval,dataval:string;
je,j:entier;
type de données : TFieldType ;
Taille des données : entier ;
commencer
résultat :=nul ;
si (ColField='') ou(RowField='')ou(DataField='') alors
showmessage('Tous les champs ne doivent pas être NULL !')
autre
commencer
si (ColField=RowField)
ou(ColField=DataField)
ou(RowField=DataField) alors
showmessage('Tous les champs ne sont pas égaux !')
autre
si (self.SouDataSet.FieldByName(ColField).DataType=ftString)
ou (self.SouDataSet.FieldByName(ColField).DataType<>ftWideString)
ou (self.SouDataSet.FieldByName(ColField).DataType<>ftFixedChar)
ou (self.SouDataSet.FieldByName(ColField).DataType<>ftMemo)
ou (self.SouDataSet.FieldByName(ColField).DataType<>ftFmtMemo) puis
commencer
essayer
tmpstrs:=tstringlist.Create;
Vdataset :=SouDataSet ;
Vdataset.Premier ;
pour i:=0 à Vdataset.RecordCount-1 faire
commencer
si (varisnull(SouDataSet.FieldValues[colfield])=false) et (SouDataSet.FieldValues[colfield]<>'') alors
si tmpstrs.IndexOf(SouDataSet.FieldValues[colfield])=-1 alors
commencer
tmpstrs.Add(SouDataSet.FieldValues[colfield]);
fin;
Vdataset.Suivant ;
fin;
//Générer des titres de colonnes dynamiques
tmpdataset:=TClientDataSet.Create(Self);
tmpdataset.FieldDefs.Add(rowfield,ftstring,50,False);
pour i:=0 à tmpstrs.Count-1 faire
commencer
avec tmpdataset.FieldDefs faire
commencer
Ajouter(tmpstrs.Strings[i],ftInteger,0,False);
fin;
fin;
tmpdataset.FieldDefs.Add('Sum',ftInteger,0,False);
DataSource:=tdatasource.Create(self);
DataSource.DataSet:=tmpdataset;
avec DataSource faire
commencer
dataset:=Createtmptab(tmpdataset.FieldDefs);
ensemble de données.Ouvrir ;
fin;
//Créer une table temporaire
Vdataset.Premier ;
pour i:=0 à Vdataset.RecordCount-1 faire
commencer
rowval:=SouDataSet.fieldbyname(rowfield).AsString;
colval:=SouDataSet.fieldbyname(colfield).AsString;
dataval:=SouDataSet.fieldbyname(datafield).AsString;
si dataval='' alors dataval:='0';
si DataSource.DataSet.Locate(rowfield,rowval,[loPartialKey]) alors
commencer
DataSource.DataSet.Edit ;
DataSource.DataSet.FieldByName(colval).AsString:=dataval;
DataSource.DataSet.FieldByName('Sum').AsInteger:=
DataSource.DataSet.FieldByName('Sum').AsInteger+strtoint(dataval);
DataSource.DataSet.Post ;
fin
autre
commencer
DataSource.DataSet.Append ;
DataSource.DataSet.FieldByName(rowfield).AsString:=rowval;
pour j:=1 à DataSource.DataSet.Fields.Count-1 faire
DataSource.DataSet.Fields[j].AsCurrency:=0;
DataSource.DataSet.FieldByName(colval).AsString:=dataval;
DataSource.DataSet.FieldByName('Sum').AsString:=dataval;
DataSource.DataSet.Post ;
fin;
Vdataset.Suivant ;
fin;
résultat :=DataSource.DataSet ;
//Générer un ensemble de données de tableau croisé
tmpstrs.Gratuit ;
sauf
fin;
fin
autre
showmessage('ColField doit être de type String !') ;
fin;
fin;
Le code ci-dessus a réussi le test sur D7 et SQL Server 7.0/2000