在Excel中计算唯一值

我需要在Excel中计算范围(C2:C2080)中的唯一值。 Google配方:

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

返回不正确的值。

UPD:Lame解决scheme:

 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 

 =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

你也可以编写一个VBAmacros(不知道这是你之后的事情)。

一些事情的影响(给定一个电子表格A1-A11填充和B1-B11空):

 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 

这是一个适用于我的VBA函数。

您可以将其用作工作表函数 ,引用任何范围,例如“= CountUnique(N8:O9)”

它处理文本和数字值,并将空白单元格视为一个值

它不需要处理数组函数。

它需要参考Microsoft Scripting Library的字典对象 。

  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 

尝试:

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

编辑:上面处理列中的空白条目

JustinG的function工作得很好(和快速),直到唯一项目的数量超过32,767由于在Excel中的某种types的限制。

我发现如果你修改他的代码

 Public Function CountUnique(rng As Range) As Integer 

并作为…

 Public Function CountUnique(rng As Range) As Long 

它会处理更多独特的项目。

对于任何仍在尝试使用@ JustinG的字典方法的人,如果您使用的是较新版本的VBA,则需要稍微修改代码。

您需要引用“Microsoft Scripting Runtime”,并使用ScriptingDictionary术语作为前缀,如下所示:

 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 

您也可以简单地使用一个filter来临时显示唯一的值 ,并计算过滤的值。

该公式适用于我。 有几件事情可能会导致这种情况无法正常工作。 首先,所有目标单元格都必须有一个值。 另一个可能不起作用的例子是,如果你有一个单元格的值为31,另一个单元格的文本值为“31”。 它会认识到这些不同的价值观。

你可以试试这个:

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

这是一个数组公式。 而不是点击进入确认,你必须按Ctrl + Shift + Enter。

哪个来自:

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

在阅读完本文之后再进一步调查之后,我发现了一个比我看到的更好的东西:

arraysinput:
(Ctrl + Shift + Enter,不包括大括号)

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

或者在VBA中:

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

它适用于数字和文本,处理空白单元格,处理引用单元格中的错误,并在VBA中工作。 这也是我见过的最紧凑的解决scheme之一。 在VBA中使用它,它显然自动处理需要是一个数组公式。

请注意,它处理错误的方式是简单地将它们包括在独特的计数中。 例如,如果您有两个单元格返回#DIV / 0! 和三个单元格返回#VALUE !,这5个单元格将添加2到唯一值的最终计数。 如果您想完全排除错误,则需要对其进行修改。

在我的testing中,这个来自雅各布的只能用于数字而不是文本,并且不处理引用单元格中的错误(如果任何引用的单元格返回错误,则返回错误):

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

这可能是处理大量行的更有效的方法。 这使用内置的AdvancedFilter命令,而不是一次循环遍历每个单元格。

 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 

另一种方法是这样的:

 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 

您只需要将活动单元格放在您正在计算的列的第1行上。