Méthode publique · ORM_CSHX2 · Agrégats

mth_SommeValeurs

Calcule la somme des valeurs d'un membre numérique de la classe sur l'ensemble des tuples chargés en mémoire. Équivalent WLangage de la fonction d'agrégation SQL SUM(), appliqué au jeu d'objets déjà en mémoire — aucune requête SQL n'est émise.

PUBLIQUE AGRÉGAT EN MÉMOIRE
01

📋 Description

mth_SommeValeurs parcourt l'ensemble des tuples chargés dans la classe et additionne les valeurs d'un membre numérique désigné par son nom. C'est l'équivalent WLangage de la fonction d'agrégation SQL SUM(), appliqué au jeu d'objets déjà en mémoire dans la classe.

La méthode opère uniquement sur les tuples présents en mémoire — aucune requête SQL n'est émise vers le moteur. Pour les besoins de calcul sur l'ensemble des données de la base, la stratégie usuelle consiste à charger d'abord le jeu pertinent via mth_ChargerSelonClauseWhere, puis à invoquer cette méthode.

🎯 Quand utiliser cette méthode

1. Calculer un total après chargement filtré. Cas le plus fréquent : on a chargé en mémoire un sous-ensemble de tuples (commandes du mois, lignes d'une facture, mouvements d'un compte) et on veut le total d'un montant. La somme se calcule sans aller-retour supplémentaire vers la base.

2. Afficher des indicateurs IHM à partir des données déjà chargées dans une table ou une fenêtre — total facturé, durée cumulée, quantité totale. La méthode lit ce qui est déjà en mémoire, donc l'opération est instantanée même sur de grands jeux.

3. Calculs de contrôle ou de validation avant un enregistrement par lot — vérifier que la somme des lignes est cohérente avec un total attendu, par exemple.

ℹ️ En mémoire — pas de SQL

La méthode opère uniquement sur les tuples déjà chargés en mémoire dans la classe. Aucune requête SQL n'est émise, aucun aller-retour réseau, pas d'impact sur la base. C'est une opération en O(n) sur le nombre de tuples chargés.

02

🔑 Signature

Déclaration
PROCÉDURE mth_SommeValeurs(
  LOCAL sMembreClasse est une chaîne
) : Variant
ÉlémentValeur
VisibilitéPUBLIQUE

Paramètres

ParamètreTypeRôle
sMembreClassechaîneNom du membre WLangage à sommer, sous la forme du nom du membre dans la classe (ex : "m_MONTANT_HT", "m_QUANTITE", "m_DUREE_INTERVENTION"). Le membre désigné doit être de type numérique — voir §03.

Valeur de retour

Un Variant contenant la somme calculée. Le type effectif du retour suit le type du membre numérique (entier, réel, monétaire, durée…). En cas de problème (membre inconnu, type non supporté, aucun tuple chargé), la méthode retourne Null — voir §04.

03

🧭 Types de membres supportés

La méthode applique une garde stricte sur le type du membre désigné : seuls les types numériques sont sommables. Pour tout autre type (chaîne, date, booléen, mémo…), la méthode retourne immédiatement Null sans tenter d'addition.

Types acceptés

CatégorieExemples de types WLangage
Entiers signésentier sur 1/2/4/8 octets
Entiers non signésentier non signé sur 1/2/4/8 octets
Réelsréel sur 4/8 octets, réel turbo
Décimauxnumérique (précision arbitraire)
Monétairemonétaire
Duréedurée
Identifiants automatiquesID auto (4 ou 8 octets)

Types refusés

Les types non numériques retournent Null sans erreur : chaîne, mémo texte, date, datetime, heure, booléen, binaire, image, mémo binaire. La garde est silencieuse — pas de message d'erreur, pas d'exception levée.

💡 Comportement sur durée et monétaire

Les types durée et monétaire sont supportés et la somme retournée conserve le type. Pour une durée, le résultat est exprimé en millisecondes (unité interne WLangage) et peut être reformaté côté appelant via DuréeVersChaîne. Pour un montant, le retour conserve la précision monétaire WLangage (4 décimales).

04

⚠️ Cas particuliers et garanties

Comportement selon les cas

CasRetour
Tuples chargés, membre numérique valideSomme calculée (ex : 15234.50, 4287)
Aucun tuple chargé en mémoireNull
Membre désigné inconnu de la classeNull (sans erreur levée)
Membre de type non numérique (chaîne, date, booléen…)Null (garde silencieuse)
Exception interne pendant l'itérationUne boîte d'erreur est affichée à l'utilisateur (cf. note ci-dessous)
⚠️ Comportement actuel sur exception

Contrairement à d'autres méthodes d'agrégat de la même catégorie (par exemple mth_Regroupement qui reste silencieux), mth_SommeValeurs affiche une boîte d'erreur à l'utilisateur en cas d'exception interne — par exemple si une indirection sur le membre échoue.

Une harmonisation de ce comportement entre toutes les méthodes d'agrégat est planifiée dans le journal d'évolution du framework. Dans l'attente, tester systématiquement que le membre désigné existe bien dans la classe et est de type numérique avant l'appel.

Garanties et non-garanties

AspectComportement
Type du retourSuit le type du membre numérique (entier, réel, monétaire, durée). Le Variant retourné encapsule ce type.
Valeurs NULL dans le membreCumulées avec les autres — aucun filtrage particulier.
Tuples marqués supprimés logiquementExclus du calcul — les tuples dont la propriété p_bRecordDeleted vaut Vrai sont ignorés par la méthode. Voir l'encadré dédié dans cette section.
Dépassement de capacitéLe cumul est effectué en interne sur un type numérique de précision étendue ; le risque de débordement reste possible sur des très grands volumes (à apprécier selon le membre cible).
🏷️ Filtrage des tuples marqués supprimés

Les tuples dont la propriété p_bRecordDeleted (alias français : p_bEnregistrementSupprimé) vaut Vrai sont automatiquement exclus du calcul. Cela couvre deux scénarios usuels :

1. Suppression en lot via mth_EnregistrerTableau : un élément du tableau interne dont la PK est passée à une valeur négative est supprimé en base, et le drapeau p_bRecordDeleted est posé à Vrai. L'élément reste dans le tableau en mémoire mais n'est plus pris en compte par les méthodes d'agrégat.

2. Marquage logique applicatif : le code applicatif peut poser p_bRecordDeleted = Vrai sur certains tuples pour les exclure des calculs sans les supprimer en base. Pratique pour des calculs conditionnels sur un sous-ensemble.

La même logique s'applique à mth_ValeurMoyenne, mth_ValeurMaximale, mth_ValeurMinimale, mth_ValeursDistinctes et mth_Regroupement.

ℹ️ Tester avec VariantConverti ou comparaison à Null

Le retour Null couvre plusieurs cas (aucun tuple, membre inconnu, type non supporté). Tester explicitement avant utilisation pour distinguer un total nul (0) d'une absence de calcul (Null) :

SI xRésultat = Null ALORS … // pas de calcul possible
SINON … // somme valide, peut être 0

05

💡 Exemples

Mode 1 — total facturé du mois

Cas d'usage le plus courant : on charge les commandes du mois et on calcule le total facturé pour un tableau de bord.

// ── Étape 1 : charger les commandes facturées du mois ─────────── clCommande:p_sClauseWhere = "MOIS(commandes.DATE_FACTURE) = MOIS(NOW())" clCommande:mth_ChargerSelonClauseWhere() // ── Étape 2 : somme des montants HT ───────────────────────────── xTotalHT est un Variant = clCommande:mth_SommeValeurs("m_MONTANT_HT") SI xTotalHT <> Null ALORS LIB_TotalMois = MonétaireVersChaîne(xTotalHT, "€") SINON LIB_TotalMois = "Aucune commande" FIN

Mode 2 — somme conditionnelle après filtrage en mémoire

Cas d'usage : on a chargé un grand jeu et on veut différents totaux par catégorie sans relancer de requêtes SQL.

// ── Charger toutes les lignes de l'année ──────────────────────── clLigne:p_sClauseWhere = "ANNEE(lignes.DATE_LIGNE) = 2026" clLigne:mth_ChargerSelonClauseWhere() // ── Calculer la somme totale en mémoire ───────────────────────── xQuantiteTotale est un Variant = clLigne:mth_SommeValeurs("m_QUANTITE") Trace("Quantité totale 2026 : " + xQuantiteTotale) // → "Quantité totale 2026 : 12847"

Mode 3 — contrôle de cohérence avant enregistrement

Cas d'usage : avant d'enregistrer un lot de tuples saisis, vérifier que la somme des lignes correspond au total attendu.

// ── Le tableau a été préparé en mémoire (saisie utilisateur) ──── xSommeLignes est un Variant = clLigneFacture:mth_SommeValeurs("m_MONTANT_TTC") xTotalAttendu est un monétaire = SAI_TotalFacture // ── Comparaison avec tolérance d'arrondi ──────────────────────── SI xSommeLignes = Null OU Abs(xSommeLignes - xTotalAttendu) > 0.01 ALORS Erreur("Le total des lignes ne correspond pas au total attendu.") RENVOYER Faux FIN // ── Cohérence OK, on peut enregistrer ─────────────────────────── clLigneFacture:mth_EnregistrerTableau()

Mode 4 — somme d'une durée cumulée

Cas d'usage : interventions de la semaine, total du temps passé par technicien.

// ── Charger les interventions de la semaine ───────────────────── clIntervention:p_sClauseWhere = "interventions.SEMAINE = " + NoSemaine(DateSys()) clIntervention:mth_ChargerSelonClauseWhere() // ── Somme des durées (type "durée" supporté) ──────────────────── xDuréeTotale est un Variant = clIntervention:mth_SommeValeurs("m_DUREE") SI xDuréeTotale <> Null ALORS // xDuréeTotale est en millisecondes — reformatage IHM LIB_TempsCumulé = DuréeVersChaîne(xDuréeTotale, "HH:MM") FIN