13

我需要在excel中计算范围(C2:C2080)中的唯一值。谷歌公式:

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

返回不正确的值。

UPD:蹩脚的解决方案:

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
4

12 回答 12

26

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

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

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

它不需要处理数组函数。

对于字典对象,它需要对 Microsoft 脚本库的引用。

    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
于 2013-07-25T11:55:09.423 回答
9

=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
于 2009-11-04T19:54:57.407 回答
8

尝试:

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

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

于 2009-11-04T19:47:29.840 回答
7

JustinG 的函数运行得非常好(而且速度很快),直到由于 Excel 中的某种类型的限制,唯一项目的数量超过 32,767。

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

Public Function CountUnique(rng As Range) As Integer

并使其成为...

Public Function CountUnique(rng As Range) As Long

然后它将处理更多独特的项目。

于 2014-02-04T21:11:08.537 回答
6

对于仍在尝试使用@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
于 2016-03-18T11:18:01.047 回答
2

您也可以简单地使用过滤器来临时显示唯一值,并对过滤后的值进行计数。

于 2009-11-05T19:14:23.580 回答
2

在阅读完本文然后进一步调查之后,我得到了一个比我在这里看到的任何东西都更适合我的东西:

Array-enter:
(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 添加到唯一值的最终计数中。如果您希望完全排除错误,则需要对其进行修改。

在我的测试中,上面 Jacob 的这个仅适用于数字,不适用于文本,并且不处理引用单元格中的错误(如果任何引用的单元格返回错误,则返回错误):

=SUM(IF(FREQUENCY(G4:G29,G4:G29)>0,1))
于 2015-03-20T23:11:15.530 回答
2

查看https://excelchamps.com/blog/count-unique-values-excel/。有你的答案。

您需要输入的公式是:

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

当您将此公式作为数组输入时,它将如下所示:

{=SUMPRODUCT(1/COUNTIF(C2:C2080,C2:C2080))}
于 2019-02-26T13:35:16.903 回答
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 来确认,而不是按 Enter 键。

来自:

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

于 2009-11-04T19:45:18.510 回答
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
于 2016-05-30T04:22:03.477 回答
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 行。

于 2017-04-18T13:29:22.750 回答
1

自 2018 年秋季以来,可以使用新的动态数组函数更轻松地解决此问题(目前仅适用于 Office 365 客户端- 此解决方案不适用于 Excel 2016 / 2019):

=COUNTA(UNIQUE(C2:C2080))

UNIQUE函数将产生一个范围内唯一值的数组,可以使用COUNTA.

如果您的范围中有空格,您可以使用以下FILTER函数将它们过滤掉:

=COUNTA(UNIQUE(FILTER(C2:C2080,C2:C2080<>"")))
于 2020-07-20T21:54:55.370 回答