web-dev-qa-db-fra.com

Obtenir des valeurs uniques dans Excel en utilisant uniquement des formules

Connaissez-vous un moyen dans Excel de "calculer" par formule une liste de valeurs uniques?

Exemple: une plage contient des valeurs "red", "blue", "red" =, "green", "blue", "black"
et je veux avoir pour résultat "red, "blue", "green" , "black" + éventuellement 2 autres cellules vides.

J'ai déjà trouvé un moyen d'obtenir une liste triée calculée en utilisant SMALL ou LARGE combiné avec INDEX, mais j'aimerais également avoir ce tri calculé, SANS UTILISER VBA.

74
Patrick Honorez

C’est un vieux jeu, et il existe quelques solutions, mais j’ai proposé ne formule plus courte et plus simple que n’importe laquelle d’autres que j’ai rencontrée, et il pourrait être utile à tous ceux qui passent.

J'ai nommé la liste de couleurs Colors (A2: A7), et le formule matricielle mis dans la cellule C2 est-ce que (fixe ):

=IFERROR(INDEX(Colors,MATCH(SUM(COUNTIF(C$1:C1,Colors)),COUNTIF(Colors,"<"&Colors),0)),"")

Utilisez Ctrl+Shift+Enter pour entrer la formule dans C2, et copiez C2 vers C3: C7.

Explication avec des exemples de données {"red"; "bleu"; "rouge"; "vert"; "bleu"; "noir"}:

  1. COUNTIF(Colors,"<"&Colors) renvoie un tableau (# 1) avec le nombre de valeurs plus petites que chaque élément de la donnée {4; 1; 4; 3; 1; 0} (noir = 0 éléments plus petits, bleu = 1 élément , rouge = 4 éléments). Cela peut être traduit en valeur de tri pour chaque élément.
  2. COUNTIF(C$1:C...,Colors) renvoie un tableau (# 2) avec 1 pour chaque donnée figurant déjà dans le résultat trié. Dans C2, il retourne {0; 0; 0; 0; 0; 0} et dans C3 {0; 0; 0; 0; 0; 1} parce que "noir" est le premier dans le tri et le dernier dans les données. En C4 {0; 1; 0; 0; 1; 1}}, il indique "noir" et toutes les occurrences de "bleu" sont déjà présentes.
  3. La SUM renvoie la valeur de tri k-th, en comptant toutes les occurrences de valeurs plus petites déjà présentes (somme du tableau n ° 2).
  4. MATCH trouve le premier index de la k-ième valeur de tri (index dans le tableau n ° 1).
  5. La IFERROR consiste uniquement à masquer l'erreur #N/A dans les cellules du bas lorsque la liste unique triée est terminée.

Pour savoir combien d’éléments uniques vous avez, vous pouvez utiliser ceci formule régulière:

=SUM(IF(FREQUENCY(COUNTIF(Colors,"<"&Colors),COUNTIF(Colors,"<"&Colors)),1))
28
dePatinkin

Ok, j'ai deux idées pour vous. J'espère que l'un d'eux vous mènera là où vous devez aller. Notez que le premier ignore la demande de le faire en tant que formule car cette solution n'est pas jolie. Je pensais m'assurer que la solution de facilité ne fonctionnerait vraiment pas pour vous; ^).

Utilisez la commande Filtre avancé

  1. Sélectionnez la liste (ou placez votre sélection n'importe où dans la liste et cliquez sur OK si la boîte de dialogue s'affiche en se plaignant qu'Excel ne sache pas si votre liste contient des en-têtes ou non)
  2. Choisissez le filtre de données/avancé
  3. Choisissez soit "Filtrer la liste, sur place" ou "Copier vers un autre emplacement"
  4. Cliquez sur "Enregistrements uniques uniquement"
  5. Cliquez sur OK
  6. Vous avez terminé. Une liste unique est créée sur place ou à un nouvel emplacement. Notez que vous pouvez enregistrer cette action pour créer un script VBA sur une ligne, qui pourrait ensuite être généralisé pour fonctionner dans d’autres situations (par exemple, sans les étapes manuelles répertoriées ci-dessus).

Utiliser des formules (notez que je suis en train de construire sur la solution Locksfree pour me retrouver avec une liste sans trous)

Cette solution fonctionnera avec les mises en garde suivantes:

  • La liste doit être triée (par ordre croissant ou décroissant). En fait, c’est assez précis, car il faut en réalité que tous les articles de même nature soient contigus, mais le tri est le moyen le plus simple d’atteindre cet état.
    • Trois nouvelles colonnes sont requises (deux nouvelles colonnes pour les calculs et une nouvelle colonne pour la nouvelle liste). Les deuxième et troisième colonnes pourraient être combinées, mais je laisserai cela au lecteur comme un exercice.

      Voici le résumé de la solution:

      1. Pour chaque élément de la liste, calculez le nombre de doublons au-dessus.
      2. Pour chaque lieu de la liste unique, calculez l'index du prochain article unique.
      3. Enfin, utilisez les index pour créer une nouvelle liste avec uniquement des éléments uniques.

      Et voici un exemple pas à pas:

      1. Ouvrir une nouvelle feuille de calcul
      2. Dans a1: a6 entrez l'exemple donné dans la question initiale ("rouge", "bleu", "rouge", "vert", "bleu", "noir")
      3. Trier la liste: placez la sélection dans la liste et choisissez la commande de tri.
      4. Dans la colonne B, calculez les doublons:
        1. Dans B1, entrez "= IF (COUNTIF ($ A $ 1: A1, A1) = 1,0, COUNTIF (A1: $ A $ 6 $, A1))". Notez que les "$" dans les références de cellules sont très importants car cela facilitera la prochaine étape (remplir le reste de la colonne). Le "$" indique une référence absolue de sorte que lorsque le contenu de la cellule est copié/collé, la référence ne sera pas mise à jour (par opposition à une référence relative qui sera mise à jour).
        2. Utilisez la copie intelligente pour remplir le reste de la colonne B: Sélectionnez B1. Déplacez votre souris sur le carré noir dans le coin inférieur droit de la sélection. Cliquez et glissez vers le bas de la liste (B6). Lorsque vous relâchez, la formule sera copiée dans B2: B6 avec les références relatives mises à jour.
        3. La valeur de B1: B6 devrait maintenant être "0,0,1,0,0,1". Notez que les entrées "1" indiquent des doublons.
      5. Dans la colonne C, créez un index d'éléments uniques:
        1. Dans C1, entrez "= Row ()". Vous voulez vraiment juste C1 = 1 mais utiliser Row () signifie que cette solution fonctionnera même si la liste ne commence pas à la ligne 1.
        2. Dans C2, entrez "= IF (C1 + 1 <= ROW ($ B $ 6)), C1 + 1 + INDEX ($ B $ 1: $ B $ 6 $, C1 + 1), C1 + 1)". Le "si" est utilisé pour empêcher la production d'un #REF lorsque l'index atteint la fin de la liste.
        3. Utilisez la copie intelligente pour remplir C3: C6.
        4. La valeur de C1: C6 doit être "1,2,4,5,7,8"
      6. Dans la colonne D, créez la nouvelle liste unique:
        1. Dans D1, entrez "= IF (C1 <= ROW ($ A $ 6)), INDEX ($ A $ 1: $ A $ 6 $, C1)," ")". Et le "si" est utilisé pour arrêter le cas #REF lorsque l'index dépasse la fin de la liste.
        2. Utilisez la copie intelligente pour remplir D2: D6.
        3. Les valeurs de D1: D6 doivent maintenant être "noir", "bleu", "vert", "rouge", "", "".

      J'espère que cela t'aides....

  • 53
    Drew Sherman

    Solution

    J'ai créé une fonction dans VBA pour vous, de sorte que vous pouvez le faire maintenant de manière simple.
    Créez un module de code VBA (macro) comme vous pouvez le voir dans ce tutoriel .

    1. Presse Alt+F11
    2. Cliquez sur Module dans Insert.
    3. Coller le code.
    4. Si Excel indique que votre format de fichier n’est pas adapté aux macros, sauvegardez-le sous le nom Excel Macro-Enabled dans Save As.

    Code source

    Function listUnique(rng As Range) As Variant
        Dim row As Range
        Dim elements() As String
        Dim elementSize As Integer
        Dim newElement As Boolean
        Dim i As Integer
        Dim distance As Integer
        Dim result As String
    
        elementSize = 0
        newElement = True
    
        For Each row In rng.Rows
            If row.Value <> "" Then
                newElement = True
                For i = 1 To elementSize Step 1
                    If elements(i - 1) = row.Value Then
                        newElement = False
                    End If
                Next i
                If newElement Then
                    elementSize = elementSize + 1
                    ReDim Preserve elements(elementSize - 1)
                    elements(elementSize - 1) = row.Value
                End If
            End If
        Next
    
        distance = Range(Application.Caller.Address).row - rng.row
    
        If distance < elementSize Then
            result = elements(distance)
            listUnique = result
        Else
            listUnique = ""
        End If
    End Function
    

    Usage

    Entrez simplement =listUnique(range) dans une cellule. Le seul paramètre est range c'est une plage Excel ordinaire. Par exemple: A$1:A$28 ou H$8:H$30.

    Conditions

    • La range doit être une colonne.
    • La première cellule dans laquelle vous appelez la fonction doit figurer dans la même ligne que celle où range commence.

    Exemple

    Cas régulier

    1. Entrez les données et appelez la fonction.
      Enter data and call function
    2. Cultivez-le.
      Grow it
    3. Voilà.
      Voilà

    Cellule vide

    Cela fonctionne dans les colonnes qui ont des cellules vides. De plus, la fonction n’affiche rien (pas des erreurs) si vous surchargez les cellules (appelez la fonction) dans des endroits où il n’ya pas de sortie, comme je l’ai fait dans la partie "2. Développez-le" de l’exemple précédent.

    Empty cell case

    22
    totymedli

    Un moyen détourné consiste à charger votre feuille de calcul Excel dans une feuille de calcul Google, à l'aide de la fonction UNIQUE (étendue) de Google - qui fait exactement ce que vous voulez -, puis à enregistrer la feuille de calcul Google au format Excel.

    J'admets que ce n'est pas une solution viable pour les utilisateurs d'Excel, mais cette approche est utile à quiconque souhaite utiliser cette fonctionnalité et est capable d'utiliser un tableur Google.

    17
    yoyo

    Même pour obtenir une valeur unique triée, vous pouvez utiliser une formule. Ceci est une option que vous pouvez utiliser:

    =INDEX($A$2:$A$18,MATCH(SUM(COUNTIF($A$2:$A$18,C$1:C1)),COUNTIF($A$2:$A$18,"<" &$A$2:$A$18),0))
    

    données de plage: A2:A18

    formule dans la cellule C2

    Ceci est une formule de tableau

    3
    new bie

    la question est très ancienne, mais les gens semblent toujours avoir du mal à utiliser une formule pour extraire des objets uniques. voici une solution qui renvoie les valeurs elles-mêmes.

    Disons que vous avez "rouge", "bleu", "rouge", "vert", "bleu", "noir" dans la colonne A2: A7

    puis mettez ceci en B2 sous forme de formule matricielle et recopiez =IFERROR(INDEX(A$2:A$7;SMALL(IF(FREQUENCY(MATCH(A$2:A$7;A$2:A$7;0);ROW(INDIRECT("1:"&COUNTA(A$2:A$7))));ROW(INDIRECT("1:"&COUNTA(A$2:A$7)));"");ROW(A1)));"")

    alors cela devrait ressembler à quelque chose comme ça; enter image description here

    3
    Jimmy

    Essayez cette formule dans la cellule B2

    =IFERROR(INDEX($A$2:$A$7,MATCH(0,COUNTIF(B$1:$B1,$A$2:$A$7),0),1),"")
    

    Après avoir cliqué sur F2 et appuyé sur Ctrl + Shift + Enter

    enter image description here

    3
    Hariharan G R

    Vous pouvez utiliser COUNTIF pour obtenir le nombre d'occurrences de la valeur dans la plage. Donc, si la valeur est en A3, la plage est A1: A6, puis dans la colonne suivante, utilisez un IF (EXACT (COUNTIF (A3: $ A $ 6, A3), 1), A3, ""). Pour le A4, ce serait IF (EXACT (COUNTIF (A4: $ 6 USD, A3), 1), A4, "")

    Cela vous donnerait une colonne où toutes les valeurs uniques sont sans doublon

    2
    Locksfree

    En supposant que la colonne A contienne les valeurs pour lesquelles vous souhaitez rechercher une instance unique unique et comporte une ligne Heading J'ai utilisé la formule suivante. Si vous voulez qu'il se mette à l'échelle avec un nombre imprévisible de lignes, vous pouvez remplacer A772 (où mes données se sont terminées) par = ADDRESS (COUNTA (A: A), 1).

    = IF (COUNTIF (A5: 772 $ A $, A5) = 1, A5, "")

    Cela affichera la valeur unique à la dernière instance de chaque valeur dans la colonne et ne supposera aucun tri. Il faut tirer parti de l’absence d’absolus pour disposer d’une "fenêtre glissante" décroissante des données à compter. Lorsque le nombre de caractères dans la fenêtre réduite est égal à 1, cette ligne est la dernière instance de cette valeur dans la colonne.

    2
    Geoff Still

    Le recours à un tableau croisé dynamique peut ne pas compter comme à l'aide de formules uniquement , mais semble plus pratique que la plupart des autres suggestions jusqu'à présent:

    SO1429899 example

    1
    pnuts

    J'ai collé ce que j'utilise dans mon fichier Excel ci-dessous. Cela prend des valeurs uniques dans la plage L11:L300 et les renseigne à partir de la colonne V, à partir de V11. Dans ce cas, j'ai cette formule dans v11 et faites-la glisser pour obtenir toutes les valeurs uniques.

    =INDEX(L$11:L$300,MATCH(0,COUNTIF(V$10:V10,L$11:L$300),0))
    

    ou

    =INDEX(L$11:L$300,MATCH(,COUNTIF(V$10:V10,L$11:L$300),))
    

    c'est une formule matricielle

    1
    user3404344

    Vous pouvez aussi le faire de cette façon.

    Créez les plages nommées suivantes:

    nList = the list of original values
    nRow = ROW(nList)-ROW(OFFSET(nList,0,0,1,1))+1
    nUnique = IF(COUNTIF(OFFSET(nList,nRow,0),nList)=0,COUNTIF(nList, "<"&nList),"")
    

    Avec ces 3 plages nommées, vous pouvez générer la liste ordonnée de valeurs uniques avec la formule ci-dessous. Il sera trié par ordre croissant.

    IFERROR(INDEX(nList,MATCH(SMALL(nUnique,ROW()-?),nUnique,0)),"")
    

    Vous devrez substituer le nombre de lignes de la cellule juste au-dessus du premier élément de votre liste ordonnée unique par le caractère '?' personnage.

    par exemple. Si votre liste unique ordonnée commence dans la cellule B5, la formule sera la suivante:

    IFERROR(INDEX(nList,MATCH(SMALL(nUnique,ROW()-4),nUnique,0)),"")
    
    1
    dm64

    Je suis surpris que cette solution ne soit pas encore apparue. Je pense que c'est l'un des plus faciles

    Donnez à vos données un en-tête et placez-les dans une plage nommée dynamique (c'est-à-dire si vos données sont en col A)

    =OFFSET($A$2,0,0,COUNTA($A:$A),1)
    

    Et puis créez un tableau croisé dynamique, faisant de la source votre plage nommée.

    En mettant simplement l'en-tête dans la section des lignes et vous aurez les valeurs uniques, triez comme bon vous semble avec la fonctionnalité intégrée.

    1
    CallumDA

    La solution de Drew Sherman est très bonne, mais la liste doit être contiguë (il suggère de trier manuellement, ce qui n'est pas acceptable pour moi). La solution de Guitarthrower est un peu lente si le nombre d'éléments est important et ne respecte pas l'ordre de la liste d'origine: il génère une liste triée quand même.

    Je voulais la commande originale des articles (triés par date dans une autre colonne) et je voulais également exclure un article de la liste finale non seulement s'il était dupliqué, mais aussi pour diverses autres raisons.

    Ma solution est une amélioration de la solution de Drew Sherman. De même, cette solution utilise 2 colonnes pour les calculs intermédiaires:

    Colonne A:

    La liste avec les doublons et peut-être les blancs que vous souhaitez filtrer. Je vais le placer dans l'intervalle A11: A1100 à titre d'exemple, car j'ai eu du mal à déplacer la solution de Drew Sherman dans des situations où elle ne débutait pas dans la première ligne.

    Colonne B:

    Cette formule affichera 0 si la valeur de cette ligne est valide (contient une valeur non dupliquée). Notez que vous pouvez ajouter les autres conditions d'exclusion souhaitées dans le premier SI ou dans un autre SI externe.

    =IF(ISBLANK(A11);1;IF(COUNTIF($A$11:A11;A11)=1;0;COUNTIF($A11:A$1100;A11)))
    

    Utilisez la copie intelligente pour remplir la colonne.

    Colonne C:

    Dans la première ligne, nous trouverons la première ligne valide:

    =MATCH(0;B11:B1100;0)
    

    A partir de cette position, nous recherchons la prochaine valeur valide avec la formule suivante:

    =C11+MATCH(0;OFFSET($B$11:$B$1100;C11;0);0)
    

    Placez-le à la deuxième ligne et utilisez la copie intelligente pour remplir le reste de la colonne. Cette formule générera une erreur # N/D lorsqu'il n'y aura plus d'éléments uniques à pointer. Nous en profiterons dans la colonne suivante.

    Colonne D:

    Il ne reste plus qu'à obtenir les valeurs indiquées par la colonne C:

    =IFERROR(INDEX($A$11:$A$1100; C11); "")
    

    Utilisez la copie intelligente pour remplir la colonne. Ceci est la liste unique en sortie.

    1
    ReneSac

    Pour une solution qui fonctionne pour les valeurs de plusieurs lignes et colonnes, j'ai trouvé la formule suivante très utile, de http://www.get-digital-help.com/2009/03/16/unique-values- from-multiple-columns-using-array-formulas / Oscar de get-digital.help.com le décrit même étape par étape et avec un exemple visualisé.

    1) Donnez à la plage de valeurs l'étiquette tbl_text

    2) Appliquez la formule matricielle suivante avec CTRL + MAJ + ENTRÉE à la cellule B13 dans ce cas. Modifiez $ B $ 12: B12 pour faire référence à la cellule située au-dessus de la cellule dans laquelle vous entrez cette formule.

        =INDEX(tbl_text, MIN(IF(COUNTIF($B$12:B12, tbl_text)=0, ROW(tbl_text)-MIN(ROW(tbl_text))+1)), MATCH(0, COUNTIF($B$12:B12, INDEX(tbl_text, MIN(IF(COUNTIF($B$12:B12, tbl_text)=0, ROW(tbl_text)-MIN(ROW(tbl_text))+1)), , 1)), 0), 1)
    

    3) Copiez/glissez vers le bas jusqu'à ce que vous obteniez des N/A.

    0
    Arthur Yip

    Si l'on met toutes les données dans les mêmes colonnes et utilise la formule suivante Exemple Formule: =IF(C105=C104,"Duplicate","Not a Duplicate")

    Pas

    1. Trier les données
    2. Ajouter une colonne pour la formule
    3. Vérifie si la cellule est égale à la cellule au-dessus
    4. Puis filtrez Not a Duplicate
    5. Facultatif: copiez les données calculées par la colonne de formule et collez-les uniquement en tant que valeurs (ainsi, si vous commencez à supprimer des données, vous ne commencez pas à obtenir d'erreurs.
    6. NOTE/AVERTISSEMENT: cela ne fonctionne que si vous triez d'abord les données

    Exemple de formule: =IF(C105=C104,"Duplicate","Not a Duplicate")

    0
    Joseph A

    Solution VBScript optimisée

    J'ai utilisé le code de totymedli, mais je l'ai trouvé embourbé lorsque j'utilisais de grandes plages (comme l'ont souligné d'autres personnes), j'ai donc optimisé un peu son code. Si quelqu'un souhaite obtenir des valeurs uniques à l'aide de VBScript mais trouve le code de totymedli lent lors de la mise à jour, essayez ceci:

        Function listUnique(rng As Range) As Variant
            Dim val As String
            Dim elements() As String
            Dim elementSize As Integer
            Dim newElement As Boolean
            Dim i As Integer
            Dim distance As Integer
            Dim allocationChunk As Integer
            Dim uniqueSize As Integer
            Dim r As Long
            Dim lLastRow  As Long
    
            lLastRow = rng.End(xlDown).row
    
            elementSize = 1
            unqueSize = 0
    
            distance = Range(Application.Caller.Address).row - rng.row
    
            If distance <> 0 Then
                If Cells(Range(Application.Caller.Address).row - 1, Range(Application.Caller.Address).Column).Value = "" Then
                    listUnique = ""
                    Exit Function
                End If
            End If
    
            For r = 1 To lLastRow
                val = rng.Cells(r)
                If val <> "" Then
                    newElement = True
                    For i = 1 To elementSize - 1 Step 1
                        If elements(i - 1) = val Then
                            newElement = False
                            Exit For
                        End If
                    Next i
                    If newElement Then
                        uniqueSize = uniqueSize + 1
                        If uniqueSize >= elementSize Then
                            elementSize = elementSize * 2
                            ReDim Preserve elements(elementSize - 1)
                        End If
                        elements(uniqueSize - 1) = val
                    End If
                End If
            Next
    
    
            If distance < uniqueSize Then
                listUnique = elements(distance)
            Else
                listUnique = ""
            End If
        End Function
    
    0
    Meir Shachar

    J'ai rencontré le même problème récemment et l'ai finalement compris.

    En utilisant votre liste, voici une pâte de mon Excel avec la formule.

    Je vous recommande d'écrire la formule quelque part au milieu de la liste, comme dans la cellule C6 de mon exemple, puis de la copier et de la coller dans votre colonne, la formule devrait s'ajuster automatiquement sans que vous ayez besoin de le faire. retapez-le.

    La seule cellule qui a une formule unique différente est dans la première ligne.

    Utilisation de votre liste ("rouge", "bleu", "rouge", "vert", "bleu", "noir"); voici le résultat: (Je n'ai pas un niveau assez élevé pour publier une image, alors espérons que cette version txt aura un sens)

    • [Colonne A: Liste originale]
    • [Colonne B: Résultat de liste unique]
    • [Colonne C: Formule à liste unique]

      1. rouge, rouge, =A3
      2. bleu, bleu, =IF(ISERROR(MATCH(A4,A$3:A3,0)),A4,"")
      3. rouge, =IF(ISERROR(MATCH(A5,A$3:A4,0)),A5,"")
      4. vert, vert, =IF(ISERROR(MATCH(A6,A$3:A5,0)),A6,"")
      5. blue, =IF(ISERROR(MATCH(A7,A$3:A6,0)),A7,"")
      6. noir, noir, =IF(ISERROR(MATCH(A8,A$3:A7,0)),A8,"")
    0
    Chris Reedy

    Cela ne fonctionne que si les valeurs sont dans l’ordre, c’est-à-dire que tous les "rouges" sont ensemble et tous les "bleus" sont ensemble, etc. supposons que vos données se trouvent dans la colonne A commençant en A2 - (ne commencez pas à la ligne 1). Type B2 dans 1 Dans type b3 = si (A2 = A3, B2, B2 + 1) Faites glisser la formule jusqu'à la fin de vos données. Tous les "rouges" seront 1, tous les "bleus" seront 2, tous les "verts" être 3 etc.

    Dans C2, tapez 1, 2, 3, etc., en bas de la colonne. Dans D2 = OFFSET ($ A $ 1, MATCH (c2, $ B $ 2: $ B $ x, 0), 0) - où x est la dernière cellule. Faites glisser vers le bas. , seules les valeurs uniques apparaîtront. - mettre en quelque vérification d'erreur

    0
    Brian