我需要在excel中计算范围(C2:C2080)中的唯一值。谷歌搜索公式:
=SUM(IF(FREQUENCY(MATCH(C2:C2080;C2:C2080;0);MATCH(C2:C280;C2:C2080;0))>0;1))
返回错误的值。
UPD: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
答案 0 :(得分:24)
这是一个适合我的VBA功能。
您可以将其用作worksheet function,引用任何范围,例如“= CountUnique(N8:O9)”
它处理文本和数值,并将空白单元格视为一个值
它不需要处理数组函数。
对于dictionary object,需要引用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
答案 1 :(得分:8)
=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
您也可以编写一个VBA宏(不确定这是不是您所追求的。)
产生效果(给定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
答案 2 :(得分:7)
尝试:
=SUM(IF(FREQUENCY(C2:C2080,C2:C2080)>0,1))
编辑:上述将处理列中的空白条目
答案 3 :(得分:6)
JustinG的功能非常好(并且快速),直到由于Excel中的某些类型的限制,唯一项目的数量超过32,767。
我发现你修改了他的代码
Public Function CountUnique(rng As Range) As Integer
并将其设为......
Public Function CountUnique(rng As Range) As Long
然后它会处理更多独特的物品。
答案 4 :(得分:4)
对于仍在尝试使用@ JustinG的字典方法的任何人,如果您使用的是较新版本的VBA,则需要稍微更改一下代码。
您需要参考Microsoft Scripting Runtime'并使用Dictionary
为Scripting
字词添加前缀,如下所示:
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
答案 5 :(得分:3)
您也可以简单地use a filter to temporarily display unique values,并计算过滤后的值。
答案 6 :(得分:1)
该公式适合我。有一些事情可能导致这种情况无效。首先,所有目标细胞必须具有一个值。另一个可能无效的示例是,如果您有一个值为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。
来自:
答案 7 :(得分:1)
通过阅读本文然后进一步调查后,我得到的一个比我在这里看到的任何东西都更好:
阵列的输入:
(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。它也是我见过的最紧凑的解决方案之一。在VBA中使用它,它显然自动处理成为数组公式的需要。
注意,它处理错误的方法是简单地将它们包含在唯一数的计数中。例如,如果您有两个单元格返回#DIV / 0!并且三个单元格返回#VALUE !,这5个单元格将在唯一值的最终计数中加2。如果您希望完全排除错误,则需要对其进行修改。
在我的测试中,上面雅各布的这个仅适用于数字,而不适用于文本,并且不处理引用单元格中的错误(如果任何引用的单元格返回错误,则返回错误):
=SUM(IF(FREQUENCY(G4:G29,G4:G29)>0,1))
答案 8 :(得分: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
答案 9 :(得分:1)
另一种方法是:
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行上。
答案 10 :(得分:1)
查看https://excelchamps.com/blog/count-unique-values-excel/。 有你的答案。
您需要输入的公式是:
=SUMPRODUCT(1/COUNTIF(C2:C2080,C2:C2080))
当您将此公式作为数组输入时,它将看起来像这样:
{=SUMPRODUCT(1/COUNTIF(C2:C2080,C2:C2080))}
答案 11 :(得分:0)
自2018年秋季起,可以使用新的动态数组功能(目前仅适用于Office 365客户端-此解决方案不适用于Excel 2016/2019):
=COUNTA(UNIQUE(C2:C2080))
UNIQUE
函数将产生一个范围内唯一值的数组,可以使用COUNTA
进行计数。
如果范围中有空白,则可以使用FILTER
函数将其过滤掉:
=COUNTA(UNIQUE(FILTER(C2:C2080,C2:C2080<>"")))