De l'utilité des aggrégats avec Delphi
Date de publication :
13/02/2004
Date de mise a jour :
13/02/2004
Par
Alphomega (http://alphomega.developpez.com/)
Une question souvent posée sur les forums Delphi concerne la réalisation de la somme des champs d'une grille
de données (TDBGrid). Dans l'exemple courant de la réalisation d'un programme de facturation, on voudrait pouvoir afficher facilement le total de la facture X pour le client Y.
Avant-propos
I. Solutions diverses
I-1. Solution 1
I-2. Solution 2
I-3. Solution 3 : les aggrégats
II. Qu'est-ce qu'un aggrégat maintenu ?
III. Création d'un aggrégat
IV. Les aggrégats par l'exemple
Une question souvent posée sur les forums Delphi concerne la réalisation de la somme des champs
d'une grille de données (TDBGrid). Dans l'exemple courant de la réalisation d'un programme de
facturation, on voudrait pouvoir afficher facilement le total de la facture X pour le client Y.

Plusieurs solutions existent pour arriver à ce résultat. Au niveau programmation, la plus efficace est certainement l'utilisation des TAggregateField proposés par la version Pro de Delphi.
Voici 3 solutions possibles pour arriver à nos fins !
Les deux premières solutions exploitent l'événement OnStateChange du composant TDataSource fournissant les données à la grille.
La troisième utilise les aggrégats maintenus.
La première solution consiste à désolidariser la grille de données de la table des données par
le méthode Table.DisableControls. On place ensuite un bookmark sur l'enregistrement en cours,
puis on positionne le curseur sur le premier champ de la table. On balaye la table jusqu'au
dernier enregistrement en additionnant les valeurs du champ dont on veut trouver la somme.
Enfin on se repositionne sur le Bookmark défini précédemment et on réactive la grille de données
avec la méthode Table.EnableControls. Tout cela est un rien compliqué, et gourmand en temps de
traitement. Cette solution ne sera pas utilisable sur une grande quantité de lignes de données.
La seconde solution utilisera un TQuery pour calculer et afficher au moment voulu la somme des
valeurs concernées. On utilisera alors une requète comme celle-ci:
SELECT SUM(MontantLigne) FROM LignesFactures WHERE Facture = :Numero
Le paramètre :Numero étant le numéro de la facture en cours de traitement. Là encore, même si
le traitement par SQL est plus rapide, la solution impose certaines contraintes. Par exemple,
on doit vérifier avant chaque calcul que le Datasource fournissant les données ne soit pas en
mode dsEdit ou dsInsert pour ne pas fausser les calculs.
I-3. Solution 3 : les aggrégats
Dans les versions D5 Entreprise puis D6 Pro de Delphi, Borland nous a fournit des composants
permettant de faciliter la manipulation de ces données: TClientDataset et TAggregateField. Ce dernier gère ce qu'on appelle un aggrégat maintenu.
II. Qu'est-ce qu'un aggrégat maintenu ?
Un aggrégat maintenu est un résumé de données automatiquement mis à jour au fur et à mesure que sont
modifiées les données dans l'ensemble de données. Le résumé le plus simple sera la somme de toutes
les valeurs d'une colonne d'une table de données, mais d'autres types de résumés sont permis. Voici
ces types de résumés dans un extrait de l'aide Borland.
Opérateur Rôle
Sum : Somme des valeurs d'un champ numérique ou d'une expression
Avg : Valeur moyenne d'un champ numérique ou date/heure ou d'une expression
Count : Spécification du nombre de valeurs exprimées pour un champ ou pour une expression
Min : Valeur minimale d'un champ chaîne, numérique ou date/heure ou d'une expression
Max : Valeur maximale d'un champ chaîne, numérique ou date/heure ou d'une expression
Ces aggrégats vont donc nous permettre de multiples choses.
III. Création d'un aggrégat
Un champ de type TAggregateField se crèe dans un TClientDataset, fourni seulement avec la version
Pro de Delphi. Rappelons qu'un TClientDataSet est un composant orienté données qui conserve l'ensemble
des enregistrements créés soit directement, soit provenant d'une source de données quelconque"
(certains composants orientés données sont dit de type unidirectionnel car justement ils n'ont pas
cette capacité de bufferisation).

Pour créer un TAggregateField, on utilise l'éditeur de champs du composant TClientDataset, exactement
comme pour ajouter un champ du Dataset source ou pour créer un champ calculé.

Le type choisi est aggrégat, et le type de champ statistiques. La validation de la boite de dialogue
de création de champ ajoute le champ créé dans la zone inférieure de l'éditeur.

Une fois le champ créé, on va pouvoir définir le calcul qu'il devra réaliser pour nous grâce à la propriété
Expression du composant. Par exemple:
Expression := 'SUM(Quantite * PrixUnitaire)';
nous fournira le résumé (constamment mis à jour) définissant le total des lignes calculées de notre
facture. Les propriétés les plus importantes de TAggregateField proposées par l'explorateur d'objet
sont les suivantes:

L'importance de GroupingLevel
Une propriété très importante du composant TAggregateField est la propriété GroupingLevel qui,
comme son nom l'indique, permet des regroupements de données selon certains niveaux. Prenons l'exemple
d'une table Lignes qui contient toutes les lignes de toutes les factures de la base. Chaque ligne est
rattachée à une facture par un numéro. En utilisant un index basé sur ce numéro, on peut définir:
GroupingLevel := 0;
GroupingLevel := 1;
Nous verrons cela plus en détail dans l'exemple suivant.
IV. Les aggrégats par l'exemple
Pour illustrer ce document, je vous propose la réalisation pas à pas d'une gestion (simplifiée)
de factures. A la fin de cet exercice, vous serez à même de réaliser des applications utilisant
les aggrégats avec Delphi.
Vous êtes prèt ? Alors, en route pour le Tutoriel.
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur.
La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
|