Méthode publique · ORM_CSHX2 · Agrégats

mth_ValeursDistinctes

Collecte en mémoire les valeurs distinctes d'un membre sur tous les tuples présents dans m_tabResults et les concatène en une chaîne unique. Le quoting SQL et le séparateur sont paramétrables — la chaîne retournée peut être utilisée directement comme clause IN (...) SQL. Recherche en mémoire — aucune requête SQL n'est émise.

PUBLIQUE AGRÉGAT MySQL · MariaDB · PostgreSQL
01

📋 Description

mth_ValeursDistinctes parcourt l'ensemble du tableau m_tabResults et collecte les valeurs distinctes (sans doublons) d'un membre désigné par son nom, puis les concatène en une chaîne unique avec un séparateur paramétrable. La méthode est l'équivalent en mémoire d'un SELECT DISTINCT colonne SQL, mais appliqué au jeu d'objets déjà chargé.

Le résultat se présente sous forme de chaîne brute ("1,2,3") ou de chaîne quotée pour SQL ("'ART01','ART02'") selon le paramétrage. Cette dernière forme est directement injectable dans une clause IN (...) d'une requête SQL.

🎯 Quand utiliser cette méthode

1. Construire une clause IN (...) SQL pour une requête suivante. On a chargé un premier jeu d'objets et on veut interroger une table liée via les valeurs distinctes d'un attribut — typiquement, charger des commandes puis récupérer les clients distincts associés via SELECT * FROM clients WHERE ID_CLIENT IN (1,5,12,42). Le quoting optionnel rend la chaîne directement utilisable, sans concaténation manuelle.

2. Construire une chaîne d'affichage IHM. Lister les codes, libellés ou catégories distincts d'un jeu d'objets (par exemple « Catégories actives ce mois-ci : ART, SVC, ABO ») dans un libellé, un tableau de bord ou un export.

3. Audit et diagnostic. Voir rapidement quelles valeurs distinctes existent pour un attribut donné dans le jeu chargé — utile pendant le développement ou pour vérifier la qualité des données.

ℹ️ Recherche en mémoire — pas de SQL

La méthode opère uniquement sur le tableau m_tabResults déjà chargé en mémoire. 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 la taille du tableau.

02

🔑 Signature

Déclaration
PROCÉDURE mth_ValeursDistinctes(
  LOCAL sMembreClasse est une chaîne,
  LOCAL bChainesQuotées est un booléen = Faux,
  LOCAL sSéparateur est une chaîne = ","
) : chaîne
ÉlémentValeur
VisibilitéPUBLIQUE

Paramètres

ParamètreTypeDéfautRôle
sMembreClassechaîneNom du membre WLangage à dédoublonner, sous la forme du nom du membre dans la classe (ex : "m_ID_CLIENT", "m_CODE_ARTICLE", "m_VILLE").
bChainesQuotéesbooléenFauxSi Vrai, les valeurs de type chaîne ou date sont quotées au format SQL (ex : "'ART01','ART02'") — directement utilisables dans une clause IN (...). Si Faux, les valeurs sont restituées brutes. Sans effet sur les types numériques.
sSéparateurchaîne","Chaîne insérée entre chaque valeur distincte. Le séparateur par défaut "," convient à la construction d'une clause IN (...) SQL ; on peut au besoin utiliser "; ", " — " ou tout autre séparateur pour un affichage IHM.
03

🧭 Quoting et séparateur

Les deux paramètres optionnels (bChainesQuotées et sSéparateur) déterminent la forme exacte de la chaîne retournée. Selon l'usage prévu (clause SQL, affichage IHM, export), on les ajuste.

Effet du paramètre bChainesQuotées

Le quoting ne s'applique qu'aux valeurs de type chaîne ou date. Pour les types numériques, la valeur est toujours restituée brute.

Type du membrebChainesQuotées = FauxbChainesQuotées = Vrai
Numérique (entier, réel, monétaire…)"1,2,3""1,2,3" (sans effet)
Chaîne (texte, mémo, caractère)"ART01,ART02,ART03""'ART01','ART02','ART03'"
Date / Heure"20260101,20260215""'20260101','20260215'"
💡 Quand activer bChainesQuotées = Vrai

Activer dès qu'on construit une clause IN (...) SQL pour une requête suivante portant sur des chaînes ou des dates. Sans le quoting, une clause comme WHERE CODE IN (ART01,ART02) serait syntaxiquement invalide. Le quoting est géré par le framework, donc cohérent quel que soit le provider (MySQL · MariaDB · PostgreSQL).

Choix du séparateur

Le séparateur par défaut "," est conçu pour la construction de clauses IN (...). D'autres séparateurs courants peuvent être utiles selon le contexte :

SéparateurCas d'usage
"," (défaut)Clause IN (...) SQL, export CSV simple
"; "Énumération lisible en libellé IHM
" — " ou " / "Affichage compact dans un bandeau ou un titre
RC (retour chariot)Liste verticale dans un libellé multiligne
04

📤 Valeur de retour

La méthode retourne une chaîne. Selon les cas :

CasRetour
Tableau peuplé, membre valideValeurs distinctes concaténées avec le séparateur (ex : "1,2,3" ou "'ART01','ART02'")
Membre désigné inconnu de la classe"" (chaîne vide)
m_tabResults est vide"" (chaîne vide)
Tuples marqués supprimés logiquement (p_bRecordDeleted = Vrai)Exclus du calcul (voir l'encadré ci-dessous)
Erreur lors de l'accès au membre (indirection invalide)"" (chaîne vide)
🏷️ 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_SommeValeurs, mth_ValeurMoyenne, mth_ValeurMaximale, mth_ValeurMinimale et mth_Regroupement.

ℹ️ Tester avec SansEspace() <> ""

Le retour "" couvre indifféremment les cas d'absence (membre inconnu, tableau vide, erreur d'accès). Tester SI SansEspace(sValeursDistinctes) <> "" ALORS avant d'utiliser la chaîne dans une clause IN (...) évite de générer du SQL invalide (une clause IN () vide est rejetée par tous les providers).

05

💡 Exemples

Mode 1 — clause IN (...) SQL avec IDs numériques

Cas d'usage le plus courant : on a chargé un premier jeu d'objets et on veut interroger une table liée via une clause IN (...).

// ── Étape 1 : charger les commandes du mois ───────────────────── clCommande:p_sClauseWhere = "MOIS(commandes.DATE_CMD) = MOIS(NOW())" clCommande:mth_ChargerSelonClauseWhere() // ── Étape 2 : récupérer les IDs distincts des clients associés ── sIDsClients est une chaîne = clCommande:mth_ValeursDistinctes("m_ID_CLIENT") // → "12,42,87,103" par exemple // ── Étape 3 : charger les clients distincts en une seule requête ─ SI SansEspace(sIDsClients) <> "" ALORS clClient:p_sClauseWhere = "clients.ID_CLIENT IN (" + sIDsClients + ")" clClient:mth_ChargerSelonClauseWhere() FIN

Mode 2 — clause IN (...) SQL avec valeurs chaîne (quoting activé)

Pour les attributs de type chaîne (codes article, libellés), le quoting est indispensable.

// ── Charger les lignes de commande ────────────────────────────── clLigne:mth_ChargerSelonClauseWhere() // ── Codes article distincts, quotés pour SQL ──────────────────── sCodes est une chaîne = clLigne:mth_ValeursDistinctes("m_CODE_ARTICLE", Vrai) // → "'ART01','ART02','ART15'" // ── Charger les fiches articles correspondantes ───────────────── SI SansEspace(sCodes) <> "" ALORS clArticle:p_sClauseWhere = "articles.CODE IN (" + sCodes + ")" clArticle:mth_ChargerSelonClauseWhere() FIN

Mode 3 — affichage IHM avec séparateur personnalisé

Cas d'usage : afficher les catégories distinctes dans un libellé de tableau de bord.

// ── Charger les produits actifs ───────────────────────────────── clProduit:p_sClauseWhere = "produits.ACTIF = 1" clProduit:mth_ChargerSelonClauseWhere() // ── Catégories distinctes, séparateur lisible IHM ─────────────── LIB_Categories = clProduit:mth_ValeursDistinctes("m_CATEGORIE", Faux, " · ") // → "ART · SVC · ABO"

Mode 4 — diagnostic : valeurs distinctes dans un jeu chargé

Cas d'usage : pendant le développement ou le débogage, voir rapidement les valeurs distinctes d'un attribut pour vérifier la qualité des données.

clCommande:mth_ChargerSelonClauseWhere() // ── Quels statuts apparaissent dans le jeu chargé ? ───────────── sStatuts est une chaîne = clCommande:mth_ValeursDistinctes("m_STATUT", Vrai, ", ") Trace("Statuts présents : " + sStatuts) // → "'EnAttente', 'Validée', 'Livrée', 'Annulée'"