仅使用公式在Excel中获取唯一值

时间:2009-09-15 22:12:36

标签: excel excel-formula

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

例如:范围包含值 "red" "blue" "red" "green" "blue" "black"
我希望得到 "red "blue" "green" { {1}} +最终还有2个其他空白单元格。

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

21 个答案:

答案 0 :(得分:53)

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

使用“高级过滤器”命令

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

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

此解决方案适用于以下警告:

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

    以下是解决方案的摘要:

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

    以下是一步一步的例子:

    1. 打开一个新的电子表格
    2. 在a1:a6中输入原始问题中给出的示例(“红色”,“蓝色”,“红色”,“绿色”,“蓝色”,“黑色”)
    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的值现在应为“黑色”,“蓝色”,“绿色”,“红色”,“”,“”。

    希望这会有所帮助......

  • 答案 1 :(得分:28)

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

    我已将颜色列表命名为Colors(A2:A7),而数组公式放入单元格 C2 就是这个(已修复< /强>):

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

    使用Ctrl+Shift+Enter C2 中输入公式,然后将C2复制到 C3:C7

    样本数据的解释{&#34; red&#34 ;; &#34;蓝色&#34 ;; &#34;红色&#34 ;; &#34;绿色&#34 ;; &#34;蓝色&#34 ;; &#34;黑色&#34;}:

    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},因为&#34;黑色&#34;排在第一位,在数据中排在最后。在C4 {0; 1; 0; 0; 1; 1}中,它表示&#34;黑色&#34;以及&#34; blue&#34;的所有事件已经存在。
    3. SUM通过计算已存在的所有较小值的值(数组#2的总和)来返回第k 排序值。
    4. MATCH找到第k个排序值的第一个索引(数组#1中的索引)。
    5. IFERROR仅用于在已排序的唯一列表完成时隐藏底部单元格中的#N/A错误。
    6. 要知道您拥有多少独特商品,可以使用常规公式

      =SUM(IF(FREQUENCY(COUNTIF(Colors,"<"&Colors),COUNTIF(Colors,"<"&Colors)),1))
      

    答案 2 :(得分:22)

    解决方案

    我在VBA中为您创建了一个功能,所以您现在可以轻松地完成这项工作 如this tutorial中所示,创建一个VBA代码模块(宏)。

    1. Alt + F11
    2. 点击Module中的Insert
    3. 粘贴代码。
    4. 如果Excel表示您的文件格式不是宏观友好型,请将其保存为Excel Macro-Enabled中的Save As
    5. 源代码

      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. 输入数据和通话功能 Enter data and call function
      2. 成长。
        Grow it
      3. 瞧。
        Voilà
      4. 空单元格

        它适用于包含空单元格的列。如果你将单元格(调用函数)覆盖到应该没有输出的位置,函数也不会输出任何内容(不是错误),就像我在上一个例子中的“2. Grow it”部分那样。

        Empty cell case

    答案 3 :(得分:17)

    一种迂回的方式是将Excel电子表格加载到Google电子表格中,使用Google的独特(范围)功能 - 这正是您想要的功能 - 然后将Google电子表格保存回Excel格式。

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

    答案 4 :(得分:3)

    B2单元格

    中尝试此公式
    =IFERROR(INDEX($A$2:$A$7,MATCH(0,COUNTIF(B$1:$B1,$A$2:$A$7),0),1),"")
    

    点击F2后按Ctrl + Shift + Enter

    enter image description here

    答案 5 :(得分:3)

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

    让我们说你有&#34;红&#34;,&#34;蓝&#34;,&#34;红&#34;,&#34;绿&#34;,&#34;蓝&#34 ;,&#34;黑色&#34;在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)));"")

    那么它应该看起来像这样; enter image description here

    答案 6 :(得分: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

    中的

    公式

    这是ARRAY FORMULA

    答案 7 :(得分:2)

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

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

    答案 8 :(得分:2)

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

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

    这将显示列中每个值的LAST实例的唯一值,并且不承担任何排序。它利用缺乏绝对性来基本上减少数据的“滑动窗口”。当简化窗口中的countif等于1时,该行就是该列中该值的最后一个实例。

    答案 9 :(得分: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)
    

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

    D栏:

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

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

    使用智能副本填充列。这是输出唯一列表。

    答案 10 :(得分: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),))
    

    这是一个数组公式

    答案 11 :(得分: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)),"")
    

    答案 12 :(得分:1)

    使用数据透视表可能不算作仅使用公式,但到目前为止大多数其他建议似乎更实用:

    SO1429899 example

    答案 13 :(得分:1)

    我很惊讶这个解决方案尚未出现。我认为这是最简单的

    之一

    为您的数据添加标题并将其置于动态命名范围内(即,如果您的数据位于col A

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

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

    只需将标题放入行部分即可获得唯一值,您可以使用内置功能对任何方式进行排序。

    答案 14 :(得分:0)

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

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

    唯一功能

    这些功能之一是UNIQUE函数,它将为所选范围提供一组唯一值。

    示例

    在以下示例中,输入值在A1:A6范围内。 UNIQUE函数被键入到单元格C1中。

    =UNIQUE(A1:A6)
    

    Simple solution to show unique values in Excel using dynamic array functions

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

    很高兴

    由于UNIQUE函数会自动溢出必要的行数,因此您应该在C1下留出足够的空间。如果没有足够的空间,则会出现#SPILL错误。

    Dynamic array functions: Spill not possible because a value in C3 is blocking the spill range

    如果要引用UNIQUE函数的结果,则只需引用包含UNIQUE函数的单元格并添加一个哈希#符号

    =C1#
    

    还可以在几列中检查唯一值。在这种情况下,UNIQUE函数将提供所有行,其中行内单元格的组合是唯一的:

    Applying the UNIQUE function over several columns

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

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

    =UNIQUE(A1:A6;;TRUE)
    

    Show unique values that appear exactly once

    答案 15 :(得分: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
    

    答案 16 :(得分:0)

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

    步骤

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

    答案 17 :(得分:0)

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

    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。

    答案 18 :(得分:0)

    仅当值按顺序排列时才有效,即所有“红色”在一起,所有“蓝色”在一起等。 假设您的数据位于A2中的A列 - (不要从第1行开始) 在B2型中1 在b3中type = 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是最后一个单元格 向下拖动,只会显示唯一值。 - 进行一些错误检查

    答案 19 :(得分:0)

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

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

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

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

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

    • [A栏:原始清单]
    • [B栏:唯一清单结果]
    • [C列:唯一列表公式]

      1. 红色,红色,=A3
      2. 蓝色,蓝色,=IF(ISERROR(MATCH(A4,A$3:A3,0)),A4,"")
      3. red ,, =IF(ISERROR(MATCH(A5,A$3:A4,0)),A5,"")
      4. 绿色,绿色,=IF(ISERROR(MATCH(A6,A$3:A5,0)),A6,"")
      5. blue ,, =IF(ISERROR(MATCH(A7,A$3:A6,0)),A7,"")
      6. 黑色,黑色,=IF(ISERROR(MATCH(A8,A$3:A7,0)),A8,"")

    答案 20 :(得分:-1)

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

    现在您将获得唯一值列表。