Calcul de rang

Comment obtenir le rang de personnes, en tenant compte des ex-æquo ? L’idée étant de classer les participants à une épreuve sportive, ou des élèves à partir de leurs notes…

Le principe

On dispose d’une table simple avec une valeur numérique ou une valeur de temps, qui doit servir à établir un classement. Dans notre exemple (super classique !), il s’agit d’une liste d’élèves avec leur note moyenne. L’objectif est de classer ces élèves en fonction de leur note, et de calculer le rang de chaque élève (du 1er au dernier).

Le principe général consiste à compter, pour chaque élève, combien d’élèves ont une moyenne supérieure. Et à ajouter 1 pour ajuster le rang (le meilleur élève n’a personne au-dessus de lui, il aurait un rang de 0 sinon).

Mais sur Access, ce n’est pas aussi simple que sur Excel !

Méthode 1 : calcul de rang par DCount

Une première solution consiste à utiliser la fonction DCount(), ou CpteDom() en français :

  1. Créez une requête basée sur la table tblElèves.
  2. Ajoutez à votre requête le champ calculé suivant :
    Rang: CpteDom("*";"[tblElèves]";"[Moyenne] > " & [Moyenne]) + 1

Vous obtenez ceci en mode Création (si vous y voyez quelque chose !) :

Une fois exécutée, la requête affiche ceci :

Quelques remarques :

  • Pour l’affichage, vous ajouterez généralement un tri décroissant sur les moyennes (ou croissant sur le rang). Mais ceci n’a pas d’impact sur le calcul lui-même, c’est juste pour faire lisible !
  • Lorsqu’il y a des ex-æquo, on considère ici que l’un des rangs est « brûlé ». Ainsi, comme il y a 2 élèves classés 1, le rang 2 est brûlé. Le troisième élève est donc classé 3. C’est normal, puisqu’on compte toutes les moyennes supérieures : l’élève 3 a bien 2 élèves meilleurs que lui, l’élève 7 a 6 élèves meilleurs que lui.

Méthode 2 : calcul de rang par sous-requête

Les fonctions de domaine – dont DCount() – sont généralement peu performantes. Vous pouvez remplacer le calcul précédent par une sous-requête (ou « subquery »). Le résultat sera le même que précédemment. Le champ calculé devient alors :

Rang: (SELECT Count(*) FROM [tblElèves] AS T2 WHERE T2.[Moyenne] > T1.[Moyenne]) + 1

Note : la table utilisée dans la requête est renommée T1 pour clarifier la syntaxe de la sous-requête. Pour renommer une table (en fait, pour lui donner un « alias »), faites comme ceci :

  1. Cliquez sur la table du bouton droit de la souris (la table placée en haut de la requête).
  2. Cliquez sur l’option Propriétés.
  3. Dans la zone Alias, tapez T1.

Méthode 3 : variante sur la numérotation

Maintenant, je vous vois arriver 🙂 : vous allez vouloir numéroter les élèves sans brûler de numéros. Ça complique un peu la sous-requête, parce qu’il faut :

  1. Extraire les moyennes différentes « au-dessus » d’un élève. La clause SQL DISTINCT est votre amie…
  2. Les décompter.
  3. Ajuster comme plus haut, en ajoutant 1.

Le calcul du rang devient :

On obtient ce résultat :

Variante : calculer un rang basé sur un temps

Si vous devez calculer un rang basé sur le temps, le principe est le même, mais vous changerez 2 choses :

  • Les tris sont inversés (une bonne moyenne est grande, mais un bon temps est petit !).
  • Les signes > deviennent des signes < pour la même raison.

Vous aimerez aussi...

18 réponses

  1. Bakayoko Ladji Moussa dit :

    Merci

  2. Sankara Adama dit :

    Bravo Excellent tuto.

  3. Daniel dit :

    La fonction: Rang: CpteDom(« * »; »[tblElèves] »; »[Moyenne] >  » & [Moyenne]) + 1 marche impeccable, mais je voudrais l’adapter à plusieurs (2 ou 3) critères de classement, du style classement d’un championnat de foot, sur le nombre de points, puis sur le goal-average, puis sur le nombre de buts marqués.
    merci d’avance

    • Hervé Inisan dit :

      A vue de nez (mais je n’ai pas tous les paramètres), il faudrait adapter la dernière partie de la fonction par concaténations. Du style :

      Je suis parti du principe que tous les champs étaient numériques.
      A adapter en fonction des champs de la table Je n’ai pas de quoi vérifier que ça marche, mais c’est déjà une piste… 🙂

  4. Hervé Inisan dit :

    ahmed > Cet autre article du Grenier devrait aider.

  5. ahmed dit :

    merci
    mais j’ai un problème c est que apres le rang comment afficher les 4 meilleurs

  6. Hervé Inisan dit :

    demba > Cet article publié mardi devrait aider.

  7. demba dit :

    Bonjour à tous;

    J’ai essayé l’exemple du site, ma requête affiche un message d’erreur #Erreur avec le 1er enregistrement « Inisan Hervé 8.5 » Mais si j’enlève le décimal, ça passe. Je peux avoir des explications?

  8. Hervé Inisan dit :

    fourchette2 > Il y a 2 manières de traiter ce problème :

    1. Modifier le séparateur décimal de l’ordinateur (dans le Panneau de configuration, formats de dates/heures/nombres). Et faire en sorte que ce soit un point au lieu d’une virgule.
    2. Corriger les données à la volée, de façon à transformer la virgule française en point anglais. Je vais sans doute poster un article là-dessus d’ici quelques jours.

    Ouala !

  9. fourchette2 dit :

    pour le calcul de rang sans critéres lorsque j’ applique la formule acces rang les entiers mais pas les decimaux ou peut-donc se situer le probleme aider mw

  10. Hervé Inisan dit :

    dabafa > Ben… pour le rang, c’est expliqué dans l’article, précisément. 😉

    Pour la moyenne, si elle est non coefficientée, tu peux faire une requête de regroupement sur les notes, avec un calcul de moyenne appliqué au champ Note.

  11. dabafa dit :

    comment calculer le rang et la moyenne de tes notes

  12. Hervé Inisan dit :

    Yedegue > Oui, c’est normal : on calcule un rang numérique. Si tu veux un affichage texte, il est possible de créer une fonction VBA pour ça, ou une table de correspondance (si la liste est limitée seulement). D’autant que ça serait différent en anglais, par exemple : 1st, 2nd, 3rd…

  13. YEDEGUE dit :

    Le sql permet de faire le rang mais, juste ecrire 1;2;3;4… ne permet pas d’ecrire les rangs 1er ; 2ème; 3ème….

  14. Gooos dit :

    merci beaucoup

  15. Hervé Inisan dit :

    paptagne > Exact, les requêtes de l’article ne sont pas prévues pour ce cas de figure. J’ai ajouté un nouvel article qui dit comment faire, c’est par ici :-).

  16. paptagne dit :

    La fonction ne marche pas avec une requête paramétrée « Entrer la classe » par exemple.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *