Bac Série H Côte d'Ivoire study materials
Bac Série H Côte d'Ivoire study resources

Du fichier Excel à la base de données : refonte du suivi des livraisons de COOPAD

Bac Série H Côte d'Ivoire · Put your knowledge to work in context.

All case studies

Du fichier Excel à la base de données : refonte du suivi des livraisons de COOPAD

La coopérative COOPAD, qui commercialise du cacao dans la région de Daloa, gère ses livraisons dans un unique fichier tableur nommé Livraisons.xlsx. Chaque ligne contient : numéro de livraison, date, numéro de membre, nom et prénoms du membre, village, téléphone, poids livré en kilogrammes, prix du kilogramme et montant. Le fichier compte 14 800 lignes réparties sur trois campagnes. Deux problèmes sont apparus : le nom du village est saisi de façons différentes (« Daloa », « DALOA », « Daloa-ville ») et plusieurs membres ayant changé de numéro de téléphone apparaissent en doublon. Le comptable doit en outre produire chaque mois un état des membres n'ayant effectué aucune livraison, et la direction veut connaître le poids total livré par membre pour la campagne en cours. Le fichier est stocké sur l'ordinateur personnel du comptable, sans mot de passe ; une coupure de courant a déjà provoqué la perte de deux journées de saisie. La coopérative envisage de passer à une base de données.

1. Analysez les anomalies du fichier actuel et proposez un schéma relationnel normalisé (tables, clés primaires, clés étrangères).

Read the worked answer

1. Anomalies constatées

  • Redondance : le nom, le village et le téléphone du membre sont répétés à chaque livraison (un membre livrant 40 fois par campagne voit ses données saisies 40 fois).
  • Anomalies de mise à jour : un changement de téléphone doit être corrigé sur toutes les lignes ; s'il ne l'est pas, le membre apparaît en doublon.
  • Anomalies d'insertion et de suppression : on ne peut pas enregistrer un membre qui n'a encore rien livré ; supprimer la dernière livraison d'un membre efface son existence.
  • Incohérence des données : trois libellés pour un même village, donc des regroupements faux dans les états statistiques.
  • Champ calculé stocké : montant = poids × prix, recopié à la main, donc source d'erreurs.
  • Absence de clé : numéro de livraison potentiellement dupliqué, aucune contrainte d'intégrité.

2. Schéma proposé (3e forme normale)

  • VILLAGE (CodeVillage *, LibelleVillage) - contrainte UNIQUE sur LibelleVillage.
  • MEMBRE (NumMembre *, Nom, Prenoms, Telephone, CodeVillage #) - NumMembre en clé primaire ; CodeVillage en clé étrangère vers VILLAGE.
  • CAMPAGNE (CodeCampagne *, Libelle, DateDebut, DateFin).
  • LIVRAISON (NumLivraison *, DateLivraison, NumMembre #, CodeCampagne #, Poids, PrixKg) - le montant n'est pas stocké mais calculé (Poids * PrixKg) ou géré par une vue.

3. Règles d'intégrité Intégrité référentielle sur NumMembre et CodeVillage ; Poids > 0 ; DateLivraison comprise dans les bornes de la campagne ; index sur (NumMembre, CodeCampagne) pour accélérer les états mensuels ; liste déroulante ou table de référence pour le village, ce qui élimine définitivement les variantes de saisie.

2. Rédigez les requêtes SQL permettant (a) d'obtenir le poids total livré par membre pour la campagne en cours et (b) de lister les membres n'ayant effectué aucune livraison durant cette campagne.

Read the worked answer

a) Poids total par membre pour la campagne en cours

SELECT m.NumMembre, m.Nom, m.Prenoms,
       SUM(l.Poids) AS PoidsTotal
FROM MEMBRE m
JOIN LIVRAISON l   ON l.NumMembre = m.NumMembre
JOIN CAMPAGNE c    ON c.CodeCampagne = l.CodeCampagne
WHERE c.Libelle = 'Campagne en cours'
GROUP BY m.NumMembre, m.Nom, m.Prenoms
ORDER BY PoidsTotal DESC;

Remarque de conception : le JOIN sur LIVRAISON écarte de fait les membres sans livraison ; c'est volontaire ici, mais il faut le savoir avant d'interpréter le résultat (le total des membres listés ne représente pas l'ensemble des adhérents).

b) Membres sans aucune livraison sur la campagne

SELECT m.NumMembre, m.Nom, m.Prenoms
FROM MEMBRE m
WHERE NOT EXISTS (
    SELECT 1
    FROM LIVRAISON l
    JOIN CAMPAGNE c ON c.CodeCampagne = l.CodeCampagne
    WHERE l.NumMembre = m.NumMembre
      AND c.Libelle = 'Campagne en cours'
);

Variante équivalente avec jointure externe :

SELECT m.NumMembre, m.Nom, m.Prenoms
FROM MEMBRE m
LEFT JOIN LIVRAISON l ON l.NumMembre = m.NumMembre
LEFT JOIN CAMPAGNE c  ON c.CodeCampagne = l.CodeCampagne
                     AND c.Libelle = 'Campagne en cours'
WHERE c.CodeCampagne IS NULL;

Point d'attention : la condition sur la campagne doit figurer dans la clause ON (et non dans le WHERE) pour la version LEFT JOIN, sinon la jointure externe est annulée et la requête renvoie un résultat vide ou faux. La version NOT EXISTS est généralement plus robuste et plus lisible pour un débutant.

3. Proposez les mesures de sécurisation des données et deux améliorations bureautiques immédiates pour la comptable, avant la migration complète.

Read the worked answer

1. Sécurisation (règle 3-2-1)

  • Trois copies des données, sur deux supports différents, dont une hors site : disque du serveur + disque externe hebdomadaire + sauvegarde cloud chiffrée.
  • Sauvegarde quotidienne automatisée en fin de journée, avec test de restauration trimestriel : une sauvegarde jamais testée n'est pas une sauvegarde.
  • Contrôle d'accès : un compte nominatif par utilisateur, mot de passe robuste, droits différenciés (le comptable saisit, la direction consulte, personne ne supprime en masse). Le fichier ne doit pas rester sur un poste personnel.
  • Continuité électrique : onduleur sur le poste de saisie, car la panne de courant est la cause identifiée de perte.
  • Traçabilité : journal des modifications et verrouillage des colonnes calculées.

2. Améliorations bureautiques immédiates

  • Standardiser le village : créer une feuille « Référentiel » listant les villages officiels, puis une validation des données – liste sur la colonne Village. En attendant, corriger en masse avec =MAJUSCULE(SUPPRESPACE(C2)) puis Données > Supprimer les doublons pour recoller les libellés.
  • Sécuriser le montant : remplacer la saisie manuelle par une formule =G2*H2 (poids × prix), et supprimer la saisie du montant.
  • Automatiser les états : =SOMME.SI($C$2:$C$14800;C2;$G$2:$G$14800) pour le poids par membre (le séparateur ; correspond à la configuration francophone d'Excel), un tableau croisé dynamique pour le récapitulatif par campagne, et un publipostage depuis la liste des membres sans livraison pour envoyer une convocation personnalisée (Word relié à la feuille, champs fusionnés Nom et Poids).

3. Après migration Profiter de la base de données pour créer une vue « PoidsParMembre » et un rôle en lecture seule pour la direction, ce qui supprime les manipulations manuelles et les risques d'écrasement de cellules.