75

您知道 Excel 中通过公式“计算”唯一值列表的方法吗?

例如:一个垂直范围包含值"red", "blue", "red", "green", "blue", 并且我希望结果是, , , + 最终还有 2 个其他空白单元格。 "black"
"red"blue""green""black"

我已经找到了一种使用 SMALL 或 LARGE 结合 INDEX 来获得计算排序列表的方法,但我也希望在不使用 VBA 的情况下也有这种计算排序。

4

21 回答 21

53

好的,我有两个想法给你。希望他们中的一个能让你到达你需要去的地方。请注意,第一个忽略了将其作为公式执行的请求,因为该解决方案并不漂亮。我想我要确保简单的方法真的不适合你;^)。

使用高级过滤器命令

  1. 选择列表(或将您的选择放在列表中的任何位置,如果对话框出现抱怨 Excel 不知道您的列表是否包含标题,请单击确定)
  2. 选择数据/高级过滤器
  3. 选择“就地过滤列表”或“复制到另一个位置”
  4. 单击“仅唯一记录”
  5. 点击确定
  6. 你完成了。在原地或在新位置创建一个唯一列表。请注意,您可以记录此操作以创建一个单行 VBA 脚本来执行此操作,然后可以推广到其他情况下为您工作(例如,没有上面列出的手动步骤)。

使用公式(请注意,我正在构建 Locksfree 解决方案,最终得到一个没有漏洞的列表)

此解决方案适用于以下注意事项:

  • 列表必须排序(升序或降序无关紧要)。实际上这是非常准确的,因为要求实际上所有类似的项目必须是连续的,但排序是达到该状态的最简单方法。
  • 需要三个新列(两个新列用于计算,一个新列用于新列表)。第二列和第三列可以合并,但我将把它作为练习留给读者。

    以下是解决方案的摘要:

    1. 对于列表中的每个项目,计算其上方的重复项数。
    2. 对于唯一列表中的每个位置,计算下一个唯一项的索引。
    3. 最后,使用索引创建一个只有唯一项目的新列表。

    这是一个分步示例:

    1. 打开一个新的电子表格
    2. 在 a1:a6 中输入原始问题中给出的示例(“red”、“blue”、“red”、“green”、“blue”、“black”)
    3. 对列表进行排序:将所选内容放入列表中,然后选择排序命令。
    4. 在 B 列中,计算重复项:
      1. 在 B1 中,输入“=IF(COUNTIF($A$1:A1,A1) = 1,0,COUNTIF(A1:$A$6,A1))"。请注意,单元格引用中的“$”非常重要,因为它将使下一步(填充列的其余部分)更加容易。“$”表示绝对引用,因此当单元格内容被复制/粘贴时,该引用不会更新(与将更新的相对引用相反)。
      2. 使用智能复制填充 B 列的其余部分:选择 B1。将鼠标移到选区右下角的黑色方块上。单击并向下拖动到列表底部 (B6)。当您发布时,公式将被复制到 B2:B6 中,并更新相关引用。
      3. B1:B6 的值现在应该是“0,0,1,0,0,1”。请注意,“1”条目表示重复。
    5. 在 C 列中,创建唯一项的索引:
      1. 在 C1 中,输入“=Row()”。你真的只是想要 C1 = 1 但使用 Row() 意味着即使列表不是从第 1 行开始,这个解决方案也可以工作。
      2. 在 C2 中,输入“=IF(C1+1<=ROW($B$6), C1+1+INDEX($B$1:$B$6,C1+1),C1+1)”。当索引到达列表末尾时,“if”用于停止生成#REF。
      3. 使用智能副本填充 C3:C6。
      4. C1:C6 的值应该是“1,2,4,5,7,8”
    6. 在 D 列中,创建新的唯一列表:
      1. 在 D1 中,输入“=IF(C1<=ROW($A$6), INDEX($A$1:$A$6,C1), "")"。并且,当索引超出列表末尾时,“if”用于停止#REF 情况。
      2. 使用智能副本填充 D2:D6。
      3. D1:D6 的值现在应该是 "black","blue","green","re​​d","",""。

    希望这可以帮助....

  • 于 2009-09-17T01:04:31.223 回答
    29

    这是一个老歌,有一些解决方案,但我想出了一个比我遇到的任何其他公式更短、更简单的公式,它可能对路过的任何人都有用。

    我已经命名了颜色列表Colors(A2:A7),放在单元格C2中的数组公式是这样的(固定的):

    =IFERROR(INDEX(Colors,MATCH(SUM(COUNTIF(C$1:C1,Colors)),COUNTIF(Colors,"<"&Colors),0)),"")
    

    用于在C2Ctrl+Shift+Enter中输入公式,并将 C2 复制到C3:C7

    用样本数据解释 {"red"; “蓝色的”; “红色的”; “绿色”; “蓝色的”; “黑色的”}:

    1. COUNTIF(Colors,"<"&Colors)返回一个数组 (#1),其值的计数小于数据 {4;1;4;3;1;0} 中的每个项目(黑色=0 个较小的项目,蓝色=1 个项目,红色=4 个项目)。这可以转换为每个项目的排序值。
    2. COUNTIF(C$1:C...,Colors)为已在排序结果中的每个数据项返回一个数组 (#2),其中 1。在 C2 中它返回 {0;0;0;0;0;0} 而在 C3 中返回 {0;0;0;0;0;1} 因为“黑色”在排序中排在第一位,在数据中排在最后。在 C4 {0;1;0;0;1;1} 中,它表示“黑色”,并且所有出现的“蓝色”都已经存在。
    3. SUM返回第k排序值,通过计算所有已经出现的较小值(数组 #2 的总和)。
    4. MATCH查找第 k 个排序值的第一个索引(数组 #1 中的索引)。
    5. 仅当排序的唯一列表完成时IFERROR隐藏#N/A底部单元格中的错误。

    要知道你有多少独特的物品,你可以使用这个常规公式

    =SUM(IF(FREQUENCY(COUNTIF(Colors,"<"&Colors),COUNTIF(Colors,"<"&Colors)),1))
    
    于 2015-05-11T04:09:36.383 回答
    22

    解决方案

    我在 VBA 中为您创建了一个函数,因此您现在可以轻松地执行此操作。如本教程所示
    ,创建一个 VBA 代码模块(宏)。

    1. Alt+F11
    2. 点击Module进入Insert
    3. 粘贴代码。
    4. 如果 Excel 说您的文件格式对宏不友好,则将其另存Excel Macro-EnabledSave As.

    源代码

    Function listUnique(rng As Range) As Variant
        Dim row As Range
        Dim elements() As String
        Dim elementSize As Integer
        Dim newElement As Boolean
        Dim i As Integer
        Dim distance As Integer
        Dim result As String
    
        elementSize = 0
        newElement = True
    
        For Each row In rng.Rows
            If row.Value <> "" Then
                newElement = True
                For i = 1 To elementSize Step 1
                    If elements(i - 1) = row.Value Then
                        newElement = False
                    End If
                Next i
                If newElement Then
                    elementSize = elementSize + 1
                    ReDim Preserve elements(elementSize - 1)
                    elements(elementSize - 1) = row.Value
                End If
            End If
        Next
    
        distance = Range(Application.Caller.Address).row - rng.row
    
        If distance < elementSize Then
            result = elements(distance)
            listUnique = result
        Else
            listUnique = ""
        End If
    End Function
    

    用法

    只需进入=listUnique(range)一个单元格。唯一的参数是range一个普通的 Excel 范围。例如:A$1:A$28H$8:H$30

    条件

    • range必须是一列。
    • 调用函数的第一个单元格必须在range开始的同一行中。

    例子

    常规案例

    1. 输入数据和调用函数。
      输入数据和调用函数
    2. 种植它。
      成长它
    3. 瞧。
      瞧

    空电池盒

    它适用于其中包含空单元格的列。此外,如果您将单元格(调用函数)过度缠绕到不应该输出的地方,该函数也不会输出任何内容(不是错误),就像我在上一个示例的“2. Grow it”部分中所做的那样。

    空电池盒

    于 2013-06-27T07:43:02.290 回答
    17

    一种迂回的方法是将您的 Excel 电子表格加载到 Google 电子表格中,使用 Google 的 UNIQUE(range) 函数 - 这正是您想要的 - 然后将 Google 电子表格保存回 Excel 格式。

    我承认这对于 Excel 用户来说不是一个可行的解决方案,但这种方法对于任何想要该功能并能够使用 Google 电子表格的人都很有用。

    于 2013-06-12T18:29:07.637 回答
    3

    注意到这是一个非常古老的问题,但人们似乎仍然无法使用提取独特项目的公式。这是一个返回它们自己的值的解决方案。

    假设您在 A2:A7 列中有“红色”、“蓝色”、“红色”、“绿色”、“蓝色”、“黑色”

    然后将其作为数组公式放入B2并复制下来=IFERROR(INDEX(A$2:A$7;SMALL(IF(FREQUENCY(MATCH(A$2:A$7;A$2:A$7;0);ROW(INDIRECT("1:"&COUNTA(A$2:A$7))));ROW(INDIRECT("1:"&COUNTA(A$2:A$7)));"");ROW(A1)));"")

    那么它应该看起来像这样; 在此处输入图像描述

    于 2014-10-26T01:14:09.297 回答
    3

    即使要获得排序的唯一值,也可以使用公式来完成。这是您可以使用的选项:

    =INDEX($A$2:$A$18,MATCH(SUM(COUNTIF($A$2:$A$18,C$1:C1)),COUNTIF($A$2:$A$18,"<" &$A$2:$A$18),0))
    

    范围数据:A2:A18

    单元格中的公式C2

    这是一个数组公式

    于 2015-09-08T08:19:52.570 回答
    3

    B2在单元格中尝试这个公式

    =IFERROR(INDEX($A$2:$A$7,MATCH(0,COUNTIF(B$1:$B1,$A$2:$A$7),0),1),"")
    

    点击后F2Ctrl+ Shift+Enter

    在此处输入图像描述

    于 2017-07-06T09:33:42.810 回答
    2

    您可以使用 COUNTIF 来获取范围内值的出现次数。因此,如果值在 A3 中,范围为 A1:A6,则在下一列中使用 IF(EXACT(COUNTIF(A3:$A$6, A3),1), A3, "")。对于 A4,它将是 IF(EXACT(COUNTIF(A4:$A$6, A3),1), A4, "")

    这将为您提供一个列,其中所有唯一值都没有任何重复

    于 2009-09-15T22:20:17.743 回答
    2

    假设 A 列包含您要查找的单个唯一实例的值,并且有一个标题行,我使用以下公式。如果您希望它以不可预测的行数进行扩展,您可以用=ADDRESS(COUNTA(A:A),1) 替换 A772(我的数据结束的地方)

    =IF(COUNTIF(A5:$A$772,A5)=1,A5,"")

    这将在列中每个值的最后一个实例处显示唯一值,并且不假定任何排序。它利用缺乏绝对值的优势,本质上减少了要计数的数据“滑动窗口”。当缩小窗口中的 countif 等于 1 时,该行是该列中该值的最后一个实例。

    于 2013-05-22T04:53:13.457 回答
    1

    Drew Sherman 的解决方案非常好,但列表必须是连续的(他建议手动排序,这对我来说是不可接受的)。如果项目数量很大并且不遵守原始列表的顺序,Guitarthrower 的解决方案会有点慢:无论如何它都会输出排序列表。

    我想要项目的原始顺序(按另一列中的日期排序),此外,我想从最终列表中排除一个项目,不仅是重复的,而且还有其他各种原因。

    我的解决方案是对 Drew Sherman 解决方案的改进。同样,此解决方案使用 2 列进行中间计算:

    A栏:

    包含要过滤的重复项和可能空白的列表。我将以 A11:A1100 区间为例,因为我无法将 Drew Sherman 的解决方案移动到它没有在第一行开始的情况。

    B栏:

    如果此行中的值有效(包含非重复值),则此公式将输出 0。请注意,您可以在第一个 IF 或另一个外部 IF 中添加您想要的任何其他排除条件。

    =IF(ISBLANK(A11);1;IF(COUNTIF($A$11:A11;A11)=1;0;COUNTIF($A11:A$1100;A11)))
    

    使用智能复制填充列。

    C栏:

    在第一行中,我们将找到第一个有效行:

    =MATCH(0;B11:B1100;0)
    

    从该位置,我们使用以下公式搜索下一个有效值:

    =C11+MATCH(0;OFFSET($B$11:$B$1100;C11;0);0)
    

    将其放在第二行并使用智能复制来填充该列的其余部分。当没有更多唯一的itens指向时,此公式将输出#N/D错误。我们将在下一个专栏中利用这一点。

    D栏:

    现在我们只需要获取 C 列指向的值:

    =IFERROR(INDEX($A$11:$A$1100; C11); "")
    

    使用智能复制填充列。这是输出唯一列表。

    于 2013-12-20T23:07:47.327 回答
    1

    我在下面的 excel 文件中粘贴了我使用的内容。这会从范围中获取唯一值L11:L300并从 V 列开始填充它们,V11 向前。在这种情况下,我在 v11 中有这个公式并将其向下拖动以获取所有唯一值。

    =INDEX(L$11:L$300,MATCH(0,COUNTIF(V$10:V10,L$11:L$300),0))
    

    或者

    =INDEX(L$11:L$300,MATCH(,COUNTIF(V$10:V10,L$11:L$300),))
    

    这是一个数组公式

    于 2014-03-11T02:53:38.127 回答
    1

    你也可以这样做。

    创建以下命名范围:

    nList = the list of original values
    nRow = ROW(nList)-ROW(OFFSET(nList,0,0,1,1))+1
    nUnique = IF(COUNTIF(OFFSET(nList,nRow,0),nList)=0,COUNTIF(nList, "<"&nList),"")
    

    使用这 3 个命名范围,您可以使用以下公式生成唯一值的有序列表。它将按升序排列。

    IFERROR(INDEX(nList,MATCH(SMALL(nUnique,ROW()-?),nUnique,0)),"")
    

    您需要将唯一有序列表的第一个元素上方的单元格的行号替换为“?” 特点。

    例如。如果您的唯一有序列表从单元格 B5 开始,那么公式将是:

    IFERROR(INDEX(nList,MATCH(SMALL(nUnique,ROW()-4),nUnique,0)),"")
    
    于 2014-04-01T19:22:17.630 回答
    1

    我很惊讶这个解决方案还没有出现。我认为这是最简单的之一

    给您的数据一个标题并将其放入动态命名范围(即,如果您的数据在 col 中A

    =OFFSET($A$2,0,0,COUNTA($A:$A),1)
    

    然后创建一个数据透视表,将源设为您的命名范围。

    只需将标题放入行部分,您将拥有唯一值,使用内置功能以您喜欢的任何方式进行排序。

    于 2014-09-05T09:21:18.427 回答
    1

    诉诸数据透视表可能不算只使用公式,但似乎比迄今为止的大多数其他建议更实用:

    SO1429899 示例

    于 2017-06-08T04:13:34.917 回答
    1

    简单公式解决方案:使用动态数组函数(UNIQUE函数)

    自 2018 年秋季以来,Microsoft Excel(Office 365 / Microsoft 365 应用程序)的订阅版本包含所谓的动态数组函数(在 Office 2016/2019 非订阅版本中尚不可用)。

    独特的功能

    其中一个函数是UNIQUE将为所选范围提供一组唯一值的函数。

    例子

    在以下示例中,输入值在 range 中A1:A6。该UNIQUE函数被输入到 cellC1中。

    =UNIQUE(A1:A6)
    

    使用动态数组函数在 Excel 中显示唯一值的简单解决方案

    如您所见,该UNIQUE函数将自动溢出必要的单元格范围,以显示所有唯一值。这由 周围的细蓝框表示C1:C4

    很高兴知道

    由于该UNIQUE函数会自动溢出必要的行数,因此您应该在C1. 如果没有足够的空间,你会得到一个#SPILL错误。

    动态数组函数:溢出不可能,因为 C3 中的值阻塞了溢出范围

    如果要引用函数的结果UNIQUE只需引用包含UNIQUE函数的单元格并添加井#号即可。

    =C1#
    

    也可以检查多个列中的唯一值。在这种情况下,UNIQUE 函数将传递行内单元格组合唯一的所有行:

    将 UNIQUE 函数应用于多列

    如果您希望显示唯一列而不是唯一行,则必须将[by_col]参数设置为TRUE(默认为FALSE,这意味着您将收到唯一行)。

    您还可以通过将参数设置为来显示仅出现一次的值[exactly_once]TRUE

    =UNIQUE(A1:A6;;TRUE)
    

    显示仅出现一次的唯一值

    于 2020-07-24T12:48:33.753 回答
    0

    我最近遇到了同样的问题,终于弄清楚了。

    使用您的列表,这是我的 Excel 中的粘贴公式。

    我建议将公式写在列表中间的某个位置,例如,在C6我示例的单元格中,然后将其复制并在列上下粘贴,公式应该会自动调整,而无需重新输入。

    唯一具有唯一不同公式的单元格位于第一行。

    使用您的列表(“红色”、“蓝色”、“红色”、“绿色”、“蓝色”、“黑色”);这是结果:(我没有足够高的级别来发布图片,所以希望这个 txt 版本有意义

    • 【A栏:原名单】
    • [B 列:唯一列表结果]
    • [C 列:唯一列表公式]

      1. 红色,红色, =A3
      2. 蓝色,蓝色,=IF(ISERROR(MATCH(A4,A$3:A3,0)),A4,"")
      3. 红色的, , =IF(ISERROR(MATCH(A5,A$3:A4,0)),A5,"")
      4. 绿色,绿色, =IF(ISERROR(MATCH(A6,A$3:A5,0)),A6,"")
      5. 蓝色的, , =IF(ISERROR(MATCH(A7,A$3:A6,0)),A7,"")
      6. 黑色,黑色, =IF(ISERROR(MATCH(A8,A$3:A7,0)),A8,"")
    于 2013-01-03T01:29:17.380 回答
    0

    这仅在值按顺序排列时有效,即所有“红色”都在一起,所有“蓝色”都在一起等。假设您的数据在 A 列中,从 A2 开始 - (不要从第 1 行开始)在B2 输入 1 在 b3 中输入 =if(A2 = A3, B2,B2+1) 向下拖动公式直到数据结束 所有“红色”将是 1,所有“蓝色”将是 2 所有“绿色”将是 3 等

    在 C2 中输入 1, 2 ,3 等,沿着列向下在 D2 = OFFSET($A$1,MATCH(c2,$B$2:$B$x,0),0) - 其中 x 是最后一个单元格 向下拖动,只会出现唯一值。-- 进行一些错误检查

    于 2014-05-09T11:55:18.533 回答
    0

    对于适用于多行和多列中的值的解决方案,我发现以下公式非常有用,来自http://www.get-digital-help.com/2009/03/16/unique-values-from-multiple- get-digital.help.com 上的 columns-using-array-formulas/ Oscar 甚至通过可视化示例一步一步地完成了它。

    1) 给值的范围标注标签 tbl_text

    2) 在这种情况下,使用 CTRL + SHIFT + ENTER 将以下数组公式应用于单元格 B13。更改 $B$12:B12 以引用您输入此公式的单元格上方的单元格。

        =INDEX(tbl_text, MIN(IF(COUNTIF($B$12:B12, tbl_text)=0, ROW(tbl_text)-MIN(ROW(tbl_text))+1)), MATCH(0, COUNTIF($B$12:B12, INDEX(tbl_text, MIN(IF(COUNTIF($B$12:B12, tbl_text)=0, ROW(tbl_text)-MIN(ROW(tbl_text))+1)), , 1)), 0), 1)
    

    3) 复制/向下拖动,直到获得 N/A。

    于 2016-01-23T02:12:38.007 回答
    0

    如果将所有数据放在同一列中并使用以下公式示例公式:=IF(C105=C104,"Duplicate","Not a Duplicate")

    脚步

    1. 对数据进行排序
    2. 为公式添加列
    3. 检查单元格是否等于其上方的单元格
    4. 然后过滤Not a Duplicate
    5. 可选:复制由公式列计算的数据并仅粘贴为值(这样,如果您开始删除数据,就不会开始出错
    6. 注意/警告:这仅在您首先对数据进行排序时才有效

    示例公式:=IF(C105=C104,"Duplicate","Not a Duplicate")

    于 2016-03-03T16:52:55.477 回答
    0

    优化的 VBScript 解决方案

    我使用了 totymedli 的代码,但在使用大范围时发现它陷入困境(正如其他人所指出的那样),所以我稍微优化了他的代码。如果有人对使用 VBScript 获取唯一值感兴趣,但在更新时发现 totymedli 的代码很慢,试试这个:

        Function listUnique(rng As Range) As Variant
            Dim val As String
            Dim elements() As String
            Dim elementSize As Integer
            Dim newElement As Boolean
            Dim i As Integer
            Dim distance As Integer
            Dim allocationChunk As Integer
            Dim uniqueSize As Integer
            Dim r As Long
            Dim lLastRow  As Long
    
            lLastRow = rng.End(xlDown).row
    
            elementSize = 1
            unqueSize = 0
    
            distance = Range(Application.Caller.Address).row - rng.row
    
            If distance <> 0 Then
                If Cells(Range(Application.Caller.Address).row - 1, Range(Application.Caller.Address).Column).Value = "" Then
                    listUnique = ""
                    Exit Function
                End If
            End If
    
            For r = 1 To lLastRow
                val = rng.Cells(r)
                If val <> "" Then
                    newElement = True
                    For i = 1 To elementSize - 1 Step 1
                        If elements(i - 1) = val Then
                            newElement = False
                            Exit For
                        End If
                    Next i
                    If newElement Then
                        uniqueSize = uniqueSize + 1
                        If uniqueSize >= elementSize Then
                            elementSize = elementSize * 2
                            ReDim Preserve elements(elementSize - 1)
                        End If
                        elements(uniqueSize - 1) = val
                    End If
                End If
            Next
    
    
            If distance < uniqueSize Then
                listUnique = elements(distance)
            Else
                listUnique = ""
            End If
        End Function
    
    于 2016-04-13T00:53:18.187 回答
    -1

    选择具有重复值的列,然后转到数据选项卡,然后数据工具选择删除重复选择 1)“继续当前选择”2)单击删除重复...按钮 3)单击“全选”按钮 4)单击好的

    现在你得到了唯一值列表。

    于 2014-06-03T10:03:25.343 回答