2009-11-04 12 views
8

Potrzebuję policzyć unikalne wartości w zakresie (C2: C2080) w programie Excel. Formularz Google:Policz unikalne wartości w Excelu

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

zwraca nieprawidłową wartość.

UPD: rozwiązanie Lame:

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 

Odpowiedz

6

=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

Można również napisać makro VBA (nie wiem, czy to, co jesteś po mimo.)

coś do skutku (dany arkusz z A1-A11 wypełniony i B1-B11 pusty):

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 
+0

nie działa dla mnie, ale udało mi się zrobić dobry jeden z twoich. thanx. – dayan

0

Formuła pracuje dla mnie. Jest kilka rzeczy, które mogą sprawić, że to nie zadziała. Po pierwsze, wszystkie komórki docelowe muszą mieć w nich wartość. Innym przykładem tego, gdzie to może nie działać, jest jedna komórka z wartością 31 i inna komórka z wartością tekstową "31". Rozpozna je jako różne wartości.

Można spróbować to:

=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)) 

To tablica formuła. Zamiast wciskać tylko klawisz Enter, aby to potwierdzić, musisz nacisnąć Ctrl + Shift + Enter.

Który jest od:

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

5

Spróbuj:

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

EDIT: Powyższy będzie obsłużyć puste wpisy w kolumnie

+0

Podczas próby to daje mi 0 dla odpowiedzi – Mike

13

Oto funkcja VBA, która działa dla mnie.

Można go używać jako worksheet function, przedstawieniu dowolnego zakresu, na przykład „= COUNTUNIQUE (N8: O9)”

Obsługuje tekst i wartości numeryczne i traktuje puste komórki jako jednej wartości

Czyni nie wymaga obsługi funkcji tablicowych.

Wymaga odniesienia do Biblioteki Microsoft Scripting Library dla dictionary object.

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 
4

funkcja Justing za działa bardzo dobrze (i szybko), aż liczba unikalnych przedmiotów przekracza 32,767 powodu jakiegoś rodzaju limitu w programie Excel.

znalazłem jeśli modyfikować jego kod

Public Function CountUnique(rng As Range) As Integer 

i zrobić to tak ...

Public Function CountUnique(rng As Range) As Long 

Wtedy obsługiwać więcej unikalne przedmioty.

0

Po przeczytaniu tego i następnie badając dalej, mam taki, który pracuje dla mnie lepiej niż cokolwiek widzę tutaj:

Array wejść:
(Ctrl + Shift + Enter, a nie robić zawierać nawiasy nawiasy)

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

albo w VBA:

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

to działa dla obu liczb i tekstu, obsługuje puste komórki, obsługuje błędy w komórkach referencyjnych i działa w języku VBA. To także jedno z najbardziej kompaktowych rozwiązań, jakie widziałem. Używając go w VBA, najwyraźniej automatycznie obsługuje potrzebę formułowania tablicowego.

Uwaga, sposób, w jaki radzi sobie z błędami, polega na uwzględnieniu ich w liczbie unikalnych. Na przykład, jeśli masz dwie komórki zwracające # DIV/0! a trzy komórki zwróciły #VALUE !, te 5 komórek dodałoby 2 do ostatecznej liczby niepowtarzalnych wartości. Jeśli chcesz, aby błędy zostały całkowicie wykluczone, należy je zmodyfikować.

W moich testach, tym razem z Jakubem powyżej działa tylko dla liczb, a nie tekstu, a nie obsługi błędów w komórkach przywoływanych (zwraca błąd, jeśli któryś z przywoływanych komórek zwraca błąd):

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

Dla każdego, kto wciąż próbuje użyć metody słownikowej @ JustinG, będziesz musiał zmienić kod nieco, jeśli używasz nowszej wersji VBA.

Musisz odwołać „Microsoft Scripting Runtime” i prefiks Dictionary warunki z Scripting, co następuje:

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 
+1

Dla wszystkich, którzy nie wiedzieli: Aby odwołać się do "Microsoft Scripting Runtime", przejdź do swojego VBAProject i kliknij Narzędzia -> odnośniki ... -> zaznacz pole "Microsoft Scripting Runtime" – Axel

0

To może być bardziej skuteczny sposób radzenia sobie z dużą liczbą wierszy. Wykorzystuje to wbudowane polecenie AdvancedFilter zamiast cyklicznie przechodzić przez każdą komórkę.

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 
0

Innym sposobem na to jest taka:

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 

Po prostu trzeba mieć aktywną komórkę być w wierszu 1 kolumny, które liczą.

Powiązane problemy