De l'utilité des agrégats avec Delphi

Alphomega

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.

- Titre : De l'utilité des agrégats avec Delphi

- Auteur : Alphomega

- Parution : 13 février 2004

- Mise à jour : 5 janvier 2020

- Licence : Ce document est issu de https://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.

Sommaire

- Avant-propos

- I. Solutions diverses

- I-A. Solution 1

- I-B. Solution 2

- I-C. Solution 3 : les agrégats

- II. Qu'est-ce qu'un agrégat maintenu ?

- III. Création d'un agrégat

- IV. Les agrégats par l'exemple

Avant-propos

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.

I - Solutions diverses

Voici trois 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 agrégats maintenus.

I-A - Solution 1

La première solution consiste à désolidariser la grille de données de la table des données par la 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.

I-B - Solution 2

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-C - Solution 3 : les agrégats

Dans les versions D5 Entreprise puis D6 Pro de Delphi, Borland nous a fourni des composants permettant de faciliter la manipulation de ces données : TClientDataset et TAggregateField. Ce dernier gère ce qu'on appelle un agrégat maintenu.

II - Qu'est-ce qu'un agrégat maintenu ?

Un agrégat maintenu est un résumé de données automatiquement mises à 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 agrégats vont donc nous permettre de multiples choses.

III - Création d'un agré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 dits 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 agrégat, et le type de champ statistique. La validation de la boite de dialogue de création de champs 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; // Pour afficher le résumé de toutes les lignes de la table
GroupingLevel := 1; // Pour obtenir le résumé sur le champ indexé Numero.

Nous verrons cela plus en détail dans l'exemple suivant.

IV - Les agrégats par l'exemple

Pour illustrer ce document, je vous propose la réalisation pas à pas d'une gestion (simplifiée) de factures. À la fin de cet exercice, vous serez à même de réaliser des applications utilisant les agrégats avec Delphi.

Vous êtes prêt ? Alors, en route pour le Tutoriel.