web-dev-qa-db-fra.com

Compter les valeurs uniques dans Excel

Je dois compter des valeurs uniques dans la plage (C2: C2080) dans Excel. Formule googlé:

=SUM(IF(FREQUENCY(MATCH(C2:C2080;C2:C2080;0);MATCH(C2:C280;C2:C2080;0))>0;1)) 

retourne une valeur incorrecte.

UPD: Lame solution: 

Sub CountUnique()

Dim i, count, j As Integer

count = 1
For i = 1 To 470
    flag = False
    If count > 1 Then
        For j = 1 To count
            If Sheet1.Cells(i, 3).Value = Sheet1.Cells(j, 11).Value Then
                flag = True
            End If
        Next j
    Else
        flag = False
    End If

    If flag = False Then
        Sheet1.Cells(count, 11).Value = Sheet1.Cells(i, 3).Value
        count = count + 1
    End If

Next i

Sheet1.Cells(1, 15).Value = count

End Sub
11
dayan

=SUM(IF(FREQUENCY(IF(LEN(A2:A10)>0,MATCH(A2:A10,A2:A10,0),""), IF(LEN(A2:A10)>0,MATCH(A2:A10,A2:A10,0),""))>0,1)) 

http://office.Microsoft.com/en-us/Excel/HP030561181033.aspx

Vous pouvez également écrire une macro VBA (vous ne savez pas si c'est ce que vous cherchez).

Quelque chose à l'effet de (donné une feuille de calcul avec A1-A11 rempli et B1-B11 vide):

Sub CountUnique()

Dim count As Integer
Dim i, c, j As Integer

c = 0
count = 0
For i = 1 To 11
    Sheet1.Cells(i, 2).Value = Sheet1.Cells(i, 1).Value
    c = c + 1
    For j = 1 To c
        If CDbl(Sheet1.Cells(i, 1).Value) = CDbl(Sheet1.Cells(j, 2).Value) Then
            c = c - 1
            Exit For
        End If
    Next j
Next i

' c now equals the unique item count put in the 12'th row
Sheet1.Cells(12, 1).Value = c

End Sub
8
user113476

Voici une fonction VBA qui fonctionne pour moi.

Vous pouvez l'utiliser comme fonction de feuille de travail , référençant n'importe quelle plage, par exemple «= CountUnique (N8: O9)».

Il gère les valeurs textuelles et numériques et traite les cellules vides comme une valeur unique.

Il ne nécessite pas de traiter avec des fonctions de tableau.

Il nécessite une référence à la bibliothèque de scripts Microsoft pour l'objet dictionnaire .

    Public Function CountUnique(rng As Range) As Integer
        Dim dict As Dictionary
        Dim cell As Range
        Set dict = New Dictionary
        For Each cell In rng.Cells
             If Not dict.Exists(cell.Value) Then
                dict.Add cell.Value, 0
            End If
        Next
        CountUnique = dict.Count
    End Function
23
JustinG

Essayer:

=SUM(IF(FREQUENCY(C2:C2080,C2:C2080)>0,1))

EDIT: Le ci-dessus traitera les entrées vides dans la colonne

7
Jacob

La fonction de JustinG fonctionne très bien (et rapidement) jusqu'à ce que le nombre d'éléments uniques dépasse 32 767 en raison d'un type de limite défini dans Excel. 

J'ai trouvé si vous modifiez son code

Public Function CountUnique(rng As Range) As Integer

et le faire comme ...

Public Function CountUnique(rng As Range) As Long

Il gérera ensuite des objets uniques.

6
Jim D

Pour ceux qui essaient encore d'utiliser la méthode du dictionnaire @ JustinG, vous devrez légèrement modifier le code si vous utilisez une version plus récente de VBA. 

Vous devez faire référence à 'Microsoft Scripting Runtime' et préfixer les termes Dictionary avec Scripting, comme suit:

Public Function CountUnique(rng As Range) As Long
    Dim dict As Scripting.Dictionary
    Dim cell As Range
    Set dict = New Scripting.Dictionary
    For Each cell In rng.Cells
         If Not dict.Exists(cell.Value) Then
            dict.Add cell.Value, 0
        End If
    Next
    CountUnique = dict.Count
End Function
4
Jordan

Vous pouvez aussi simplement utiliser un filtre pour afficher temporairement des valeurs uniques et compter les valeurs filtrées.

3
Mathias

Cela pourrait être un moyen plus efficace de traiter un grand nombre de lignes. Cela utilise la commande AdvancedFilter intégrée au lieu de parcourir chaque cellule à la fois.

Public Function UniqueValues(oRange As Range) As Variant

' Uses the built-in AdvancedFilter Excel command to return the unique values onto the Worksheet
' and then populate and retuns an array of unique values

' Note:  The index:0 element in the returned array will be the header row.
'        You can ignore this element unless the first row in your oRange is a unique value
'        in which case the header will be that value.

Dim oTarget As Range
Dim r As Long, numrows As Long
Dim vs1, vs2 As Variant

' Get the first unused cell on the first row where the unique vaues will be temporarily populated
   Set oTarget = oRange.SpecialCells(xlLastCell) ' the last cell on the worksheet
   Set oTarget = oTarget.Parent.Cells(1, oTarget.Column + 1) ' the first unused cell on the first row

' Copy the unique values from your oRange to the first unused cell on row 1
   oRange.AdvancedFilter Action:=xlFilterCopy, CopyToRange:=oTarget, Unique:=True

' Get the number of rows including the first row which is the header
   numrows = WorksheetFunction.CountA(oTarget.EntireColumn)

' create an 2-dim array of the rows
   vs1 = oTarget.Resize(numrows)

' Prepare a second 1-dim array for the result
   ReDim vs2(numrows)

' Transfer the 2-dim array into the 1-dim array
   For r = 1 To UBound(vs1, 1)
      vs2(r - 1) = vs1(r, 1)
   Next

' Return the 1-dim array as the function result
   UniqueValues = vs2

' Clean up the extra column on the worksheet
   oTarget.EntireColumn.Delete

End Function
1
Neil

Regardez https://excelchamps.com/blog/count-unique-values-Excel/ . Voilà votre réponse.

La formule à saisir est la suivante:

=SUMPRODUCT(1/COUNTIF(C2:C2080,C2:C2080))

Lorsque vous entrez cette formule sous forme de tableau, cela ressemble à ceci:

{=SUMPRODUCT(1/COUNTIF(C2:C2080,C2:C2080))}
1
Kleberson Felix Silva

Après avoir lu ceci et étudié plus en profondeur, j'en ai un qui fonctionne mieux pour moi que tout ce que je vois ici:

Tableau-entrer:
(Ctrl + Maj + Entrée, et n'incluez pas les accolades)

{=SUM(IFERROR(1/COUNTIF(C2:C2080,C2:C2080),0))}

Ou en VBA:

MyResult = MyWorksheetObj.Evaluate("=SUM(IFERROR(1/COUNTIF(C2:C2080,C2:C2080),0))")

Il fonctionne à la fois pour les nombres et le texte, il gère les cellules vides, les erreurs dans les cellules référencées et VBA. C'est aussi l'une des solutions les plus compactes que j'ai jamais vues. En l'utilisant dans VBA, il gère apparemment automatiquement le besoin d'être une formule matricielle.

Notez que les erreurs sont gérées simplement en les incluant dans le nombre de personnes uniques. Par exemple, si vous avez deux cellules renvoyant # DIV/0! et trois cellules renvoyant #VALUE !, ces 5 cellules ajouteraient 2 au nombre final de valeurs uniques. Si vous voulez exclure complètement les erreurs, il faudra le modifier pour cela.

Dans mes tests, celui de Jacob ci-dessus ne fonctionne que pour les nombres, pas le texte, et ne gère pas les erreurs dans les cellules référencées (renvoie une erreur si l'une des cellules référencées renvoie une erreur):

=SUM(IF(FREQUENCY(G4:G29,G4:G29)>0,1))
1
Greg Lovern

La formule fonctionne pour moi. Il y a quelques choses qui pourraient faire que cela ne fonctionne pas. Premièrement, toutes les cellules cibles doivent avoir une valeur. Cela pourrait également ne pas fonctionner si vous avez une cellule avec la valeur 31 et une autre cellule avec une valeur de texte de "31". Il reconnaîtra ces valeurs comme étant différentes.

Vous pouvez essayer ceci:

=SUM(IF(FREQUENCY(IF(LEN(B2:B11)>0,MATCH(B2:B11,B2:B11,0),""), IF(LEN(B2:B11)>0,MATCH(B2:B11,B2:B11,0),""))>0,1))

Ceci est un tableau formule. Au lieu d'appuyer simplement sur entrée pour la confirmer, vous devez appuyer sur Ctrl + Maj + Entrée.

Qui est de:

http://www.cpearson.com/Excel/Duplicates.aspx

1
Dan

Une autre façon de faire est la suivante:

Sub CountUnique()
    Dim Count, x, a, lastRow, Values(), StringValues
    a = ActiveCell.Column
    a = GetLetterFromNumber(a)
    lastRow = Range(a & Rows.Count).End(xlUp).row
    Count = 0
    For Each c In Range(Range(a & "1"), Range(a & Rows.Count).End(xlUp))
        If c.row = 1 Then
            ReDim Values(lastRow)
            Values(Count) = c.Value
            Count = Count + 1
        End If
        StringValues = Join(Values, "#")
        StringValues = "#" + StringValues
        If InStr(1, StringValues, c.Value) = 0 Then
            Values(Count) = c.Value
            Count = Count + 1
        End If
    Next c
    MsgBox "There are " & Count & " unique values in column " & a
End Sub

Il suffit que la cellule active soit sur la ligne 1 de la colonne que vous comptez.

1
Mike