RECHERCHEV : le piège des doublons (et comment l'éviter)

Comment détecter ce problème avant qu'il ne fausse un résultat, et une manière différente d'y penser avec Python.

5 min de lecture

Quand la colonne utilisée comme clé de recherche dans une RECHERCHEV contient des doublons, la formule renvoie tout de même un résultat : celui de la première ligne correspondante, sans jamais signaler qu'il existait plusieurs correspondances possibles. Pas de message d'erreur, pas de cellule qui change de couleur, juste un chiffre qui a l'air juste et qui, en réalité, peut ne pas l'être.

Ce n'est pas la formule qui est fautive : c'est l'hypothèse implicite qu'elle porte, une clé de recherche unique, qui n'est jamais vérifiée. Voici comment détecter ce problème avant qu'il ne fausse un résultat, et une manière différente d'y penser avec Python.

Le piège, concrètement

Imaginez une table de fournisseurs avec un identifiant, un nom et un délai de paiement négocié. Suite à la fusion de deux bases, une base historique et une base reprise après un rachat, l'identifiant F1032 se retrouve associé à deux lignes : Fournisseur A avec un délai de 30 jours, Fournisseur B avec un délai de 60 jours.

Une RECHERCHEV sur F1032, dans une table de commandes, renvoie systématiquement 30 jours, y compris pour les commandes qui concernent en réalité le Fournisseur B. Le tableau final est complet, sans cellule vide ni erreur visible : toutes les commandes ont un délai assigné. Certains sont simplement faux, et rien dans l'affichage ne permet de le deviner.

Pourquoi ça arrive plus souvent qu'on ne le pense

Les doublons de clé sont traîtres, car les causes les plus fréquentes sont discrètes :

Comment repérer les doublons avant de faire confiance à sa RECHERCHEV

Quelques réflexes simples, à appliquer sur la colonne clé avant tout rapprochement :

Ces trois vérifications prennent quelques minutes et évitent de découvrir le problème bien plus tard, une fois le rapport diffusé.

Avec Python, le problème peut être rendu explicite plutôt qu'invisible

Voici, à titre d'exemple, comment on rapprocherait les mêmes tables avec pandas :

python
import pandas as pd

commandes = pd.read_excel("commandes.xlsx")
fournisseurs = pd.read_excel("fournisseurs.xlsx")

rapprochement = commandes.merge(
    fournisseurs,
    on="id_fournisseur",
    how="left",
    validate="many_to_one",
)

Le paramètre validate="many_to_one" indique à pandas l'hypothèse posée : un même fournisseur peut apparaître plusieurs fois dans le fichier des commandes (many) mais chaque fournisseur doit porter un identifiant unique dans le fichier des fournisseurs (one). Si id_fournisseur contient un doublon côté fournisseurs, pandas lève immédiatement une erreur (MergeError), avant même de produire un résultat, évitant toute erreur silencieuse.

C'est une précaution importante : sans ce paramètre, un merge sur une clé dupliquée ne se comporte pas comme une RECHERCHEV. Il ne choisit pas non plus une seule ligne au hasard : il crée une ligne pour chaque correspondance trouvée, ce qui peut faire gonfler silencieusement le nombre de lignes du résultat. C'est un problème différent de celui de RECHERCHEV, mais tout aussi invisible sans vérification. Le paramètre validate transforme ces deux comportements silencieux, valeur potentiellement fausse d'un côté, lignes dupliquées de l'autre, en une erreur explicite et bien visible, à corriger avant de continuer.

L'équivalent du NB.SI existe aussi nativement, pour vérifier l'hypothèse avant même de lancer le rapprochement : fournisseurs["id_fournisseur"].duplicated().any() renvoie directement s'il existe un doublon dans la colonne.

En résumé

Ce réflexe de vérification avant tout rapprochement est le même qui distingue Python d'un tableur au sens large : notre comparatif Python vs VBA et notre Python vs Power Query creusent deux angles complémentaires à celui-ci. Retrouvez aussi l'ensemble de nos articles sur Python pour les métiers.

Questions fréquentes
Non. Elle renvoie simplement la valeur de la première correspondance trouvée, sans aucun avertissement.
NB.SI (=NB.SI(A:A;A2)>1) ou la mise en forme conditionnelle "Valeurs en double" permettent de les repérer facilement, avant tout rapprochement.
Non. Par défaut, il duplique les lignes correspondantes au lieu de n'en garder qu'une seule, ce qui est un problème différent mais tout aussi silencieux sans le paramètre validate.
Quatre valeurs sont possibles : "one_to_one" (aucune des deux clés ne doit être dupliquée), "one_to_many", "many_to_one" (comme dans l'exemple ci-dessus, seule la clé du fichier respectivement de gauche ou de droite doit être unique), et "many_to_many" (aucune vérification n'est appliquée, c'est le comportement par défaut sans ce paramètre).

Vous avez déjà eu un doute sur un chiffre issu d'une RECHERCHEV, sans jamais avoir pu le vérifier vraiment ?

Découvrir Python pour les métiers →