Toutes les notes

Données · Excel · 9 min

Transformer des règles métier en statistiques Excel reproductibles

Turning business rules into reproducible Excel statistics

Le défi n'est pas d'écrire des cellules. C'est de garantir que la même population et les mêmes règles produisent le même résultat, aujourd'hui comme l'an prochain.

Un rapport fiable est une fonction déterministe: une période, un ensemble de dossiers et des règles explicites entrent; un classeur vérifiable sort.

Définir la population avant de compter

Une statistique n'a de sens que si l'on sait quels dossiers peuvent y contribuer. Pour un rapport annuel, l'application sélectionne les dossiers dont la date du premier appel se trouve entre la date de début et la date de fin inclusivement. Les dossiers anonymisés sont exclus. Le tri par date d'appel, nom et prénom rend aussi l'onglet de vérification stable d'une exécution à l'autre.

clients = (
    Client.objects.exclude(status=ANONYMIZED)
    .filter(date_appel__gte=date_debut, date_appel__lte=date_fin)
    .order_by("date_appel", "nom", "prenom")
)

Cette définition doit vivre près du code de génération, pas seulement dans une note de réunion. Sinon deux rapports portant le même nom peuvent compter des populations différentes.

Écran fictif de génération du rapport annuel Excel
La période est un paramètre visible. L'export journalise l'opération et annonce les sept onglets produits.

Rendre chaque dénominateur explicite

Une colonne de pourcentage cache toujours une question: pourcentage de quoi? Dans le rapport, les répartitions globales utilisent le nombre total de dossiers inclus sur la période. Les sections Hommes et Femmes recalculent leur propre total avant de produire leurs pourcentages. Une fonction commune gère aussi le cas d'un dénominateur nul et retourne zéro plutôt qu'une erreur ou une cellule ambiguë.

Les règles plus complexes deviennent de petits prédicats nommés: absence ou annulation, refus, évaluation non complétée, accepté aux services, référé à l'extérieur. Le nom métier reste visible et la logique peut être testée sans ouvrir Excel.

Distinguer valeur unique et choix multiples

Une langue principale est une catégorie unique; une source de référence ou une problématique peut contenir plusieurs choix. Les compter avec la même fonction produirait des résultats faux. Le code possède donc une stratégie pour les champs simples et une autre pour les listes JSON. Dans le second cas, un même dossier peut contribuer à plusieurs catégories, ce qui signifie que la somme des pourcentages peut dépasser 100 %. Cette propriété doit être assumée et expliquée.

Traiter les données manquantes comme un résultat

Ignorer silencieusement les champs vides donne un rapport propre, mais trompeur. Les répartitions ajoutent une ligne « Non renseigné » lorsque nécessaire. Le classeur contient aussi un onglet Contrôles qui liste les dossiers incomplets et les champs à vérifier.

Cette couche est importante pour l'adoption. Elle transforme l'export en outil d'amélioration de la saisie plutôt qu'en simple photographie des erreurs existantes.

Produire un classeur qui explique son propre résultat

Le fichier contient sept onglets: Résumé annuel, Hommes, Femmes, Global, Reddition annuelle, Dossiers inclus et Contrôles. Les cinq premiers présentent les statistiques. Les deux derniers permettent de retracer exactement la population utilisée et les anomalies de qualité.

Les en-têtes, largeurs de colonnes, retours à la ligne et volets figés sont générés de manière uniforme. Ce sont de petits détails, mais un rapport annuel est aussi un produit utilisé par des humains. La reproductibilité ne doit pas produire un fichier pénible à lire.

Ne pas oublier qu'Excel exécute des formules

Une valeur textuelle commençant par =, +, - ou @ peut être interprétée comme une formule par Excel. Avant d'écrire un texte provenant de la base, la génération préfixe ces valeurs avec une apostrophe. C'est une défense simple contre l'injection de formule dans les colonnes de détails.

def safe_excel_value(value):
    if isinstance(value, str) and value.lstrip().startswith(("=", "+", "-", "@")):
        return f"'{value}"
    return value

Tester le fichier comme un artefact, pas comme un effet secondaire

Les tests téléchargent réellement le classeur, l'ouvrent avec openpyxl, vérifient les sept noms d'onglets puis lisent des lignes clés dans Résumé annuel et Global. Cette approche détecte les régressions de structure qu'un test limité aux fonctions de comptage laisserait passer.

On peut ensuite ajouter des cas ciblés: aucune donnée, plusieurs catégories, champ manquant, dossier anonymisé ou texte ressemblant à une formule. Chaque scénario protège un contrat que l'organisation pourra retrouver au prochain cycle annuel.

La méthode en six décisions

  1. Écrire la définition exacte de la population.
  2. Nommer le dénominateur de chaque pourcentage.
  3. Transformer les résultats métier en prédicats testables.
  4. Rendre les valeurs manquantes et contrôles visibles.
  5. Inclure la liste des dossiers qui justifie le rapport.
  6. Ouvrir et vérifier le classeur dans les tests automatisés.

Le bouton d'export est la dernière étape visible. Le vrai travail consiste à rendre toutes les décisions qui le précèdent explicites, stables et vérifiables.