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

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

例如:范围包含"red""blue""red""green""blue""black"
而我希望结果是"red"blue""green""black" +最终2个其他空白单元格。

我已经find了一种方法来得到一个计算的sorting列表使用SMALL或LARGE结合INDEX,但我想有这种计算sorting,以及没有使用VBA。

这是一位老人,这里有几个解决scheme,但是我想出了比我遇到的任何其他解决scheme都更短,更简单的公式 ,对于任何路过的人来说都是有用的。

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

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

使用Ctrl+Shift+EnterC2中input公式,然后将C2复制到C3:C7

样本数据说明{“red”; “蓝色”; “红”; “绿色”; “蓝色”; “黑色”}:

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

要知道你有多less独特的项目可以使用这个正则expression式

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

好的,我有两个想法给你。 希望他们中的一个能把你带到你需要去的地方。 请注意,第一个忽略了做这个公式的请求,因为这个解决scheme并不漂亮。 我想我确定简单的方法真的不适合你; ^)。

使用高级筛选器命令

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

使用公式(请注意,我build立在Locksfree解决scheme上,最终得到一个没有漏洞的列表)

此解决scheme将与以下警告一起工作:

  • 该列表必须sorting(升序或降序无关紧要)。 其实这是相当准确的,因为要求是所有类似项目必须是连续的,但sorting是达到这个状态最简单的方法。
  • 需要三个新列(两个新列用于计算,一个新列用于新列表)。 第二和第三栏可以合并,但我会把这个作为练习留给读者。
  • 以下是解决scheme的总结:

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

    这里是一个一步一步的例子:

    1. 打开一个新的电子表格
    2. 在a1:a6中input原始问题(“红色”,“蓝色”,“红色”,“绿色”,“蓝色”,“黑色”)中给出的示例
    3. 对列表进行sorting:将select放在列表中,然后selectsorting命令。
    4. 在B栏中,计算重复项:
      1. 在B1中,input“= IF(COUNTIF($ A $ 1:A1,A1)= 1,0,COUNTIF(A1:$ A $ 6,A1))”。 请注意,单元格引用中的“$”非常重要,因为它将使下一步(填充列的其余部分)变得更容易。 “$”表示绝对引用,以便当单元格内容被复制/粘贴时,引用不会更新(相对于将更新的相对引用)。
      2. 使用智能副本填充列B的其余部分:selectB1。 将鼠标移到选区右下angular的黑色方块上方。 点击并拖动到列表的底部(B6)。 当您释放时,公式将被复制到B2:B6中并更新相对引用。
      3. B1:B6的值现在应该是“0,0,1,0,0,1”。 注意“1”表示重复。
    5. 在列C中,创build唯一项目的索引:
      1. 在C1中,input“= Row()”。 你真的只想C1 = 1,但是使用Row()意味着即使列表没有在第一行开始,这个解决scheme也能工作。
      2. 在C2中,input“= 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列中,创build新的唯一列表:
      1. 在D1中,input“= IF(C1 <= ROW($ A $ 6),INDEX($ A $ 1:$ A $ 6,C1),”“)”“。 而且,当索引超出列表的末尾时,“if”被用于停止#REF情况。
      2. 使用智能副本填充D2:D6。
      3. 现在D1:D6的值应该是“黑色”,“蓝色”,“绿色”,“红色”,“”,“”。

    希望这可以帮助….

    我在VBA中为你创build了一个函数,所以你现在可以用一个简单的方法来实现这个function。
    创build一个VBA代码模块(macros),你可以在本教程中看到。

    1. 按下Alt + F11
    2. 点击Insert Module
    3. 粘贴代码。
    4. 如果Excel表示您的文件格式不是macros观友好的,则将其Save AsExcel Macro-Enabled

    源代码

     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 

    用法

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

    条件

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

    经常案例

    1. input数据和呼叫function。
      输入数据和呼叫功能
    2. 增长它。
      增长它
    3. 瞧。
      瞧

    空的情况下

    它在有空单元格的列中工作。 而且,如果将单元格(调用函数)放到不应该输出的地方,则函数不会输出任何内容(不是错误),就像我在前面的示例“2. Grow it”部分中所做的一样。

    空的情况下

    一个迂回的方法是将您的Excel电子表格加载到Google电子表格中,使用Google的UNIQUE(范围)function(完全按照您的要求),然后将Google电子表格保存为Excel格式。

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

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

    假设你在A2栏中有“红”,“蓝”,“红”,“绿”,“蓝”,“黑”:A7

    然后把它作为一个数组公式,并复制下来=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)));"")

    那么它应该看起来像这样; 在这里输入图像说明

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

    这会给你一个所有唯一值没有任何重复的列

    假设列A包含要查找单个唯一实例的值,并且具有标题行,则使用以下公式。 如果你想用不可预知的行数进行扩展,你可以使用= ADDRESS(COUNTA(A:A),1)replaceA772(我的数据结束处

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

    这将显示列中每个值的LAST实例的唯一值,并且不承担任何sorting。 它利用了绝对数量的缺乏,从而实质上减less了数据的“滑动窗口”。 当缩小窗口中的countif等于1时,那么该行就是该列中该值的最后一个实例。

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

     =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单元格中

    这是一个arrays式

    德鲁谢尔曼的解决scheme是非常好的,但名单必须是连续的(他build议手动sorting,这是不能接受的)。 Guitarthrower的解决scheme有点慢,如果项目的数量很大,并不尊重原始列表的顺序:无论输出一个sorting列表。

    我想要项目的原始顺序(在另一列按datesorting),另外我想从最终列表中排除一个项目,不仅如果它是重复的,而且由于各种其他原因。

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

    A栏:

    与重复的列表,也许空白,你想过滤。 我将把它定位在A11:A1100间隔中,因为我把Drew Sherman的解决scheme移到了第一行没有开始的情况下是有困难的。

    B栏:

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

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

    使用智能副本填充列。

    C列:

    在第一行中,我们将find第一个有效的行:

     =MATCH(0;B11:B1100;0) 

    从那个位置,我们用下面的公式search下一个有效值:

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

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

    D栏:

    现在我们只需要得到列C指向的值:

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

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

    你也可以这样做。

    创build以下命名范围:

     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个命名范围,您可以使用下面的公式生成唯一值的有序列表。 它将按升序sorting。

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

    您将需要replace您的唯一有序列表的第一个元素上方的单元格的行号为'?' 字符。

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

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

    我很惊讶这个解决scheme还没有出来。 我认为这是最简单的一个

    给你的数据一个标题,并把它放到一个dynamic命名的范围内(即如果你的数据是col A

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

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

    只需将标题放入行部分,就可以获得唯一的值,按内置function的任何方式进行sorting。

    我已经粘贴了我在下面的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),)) 

    这是一个数组公式

    使用数据透视表可能不会被视为只使用公式,但似乎更实际的,到目前为止,大多数其他build议:

    SO1429899的例子

    B2单元格中试试这个公式

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

    点击F2并按下Ctrl + Shift + Enter

    在这里输入图像说明

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

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

    我build议在列表中间的某个地方编写公式,例如,在我的示例的单元格C6中,然后将其复制并粘贴到列上,公式应该自动调整,而不需要重新input。

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

    使用您的列表(“红色”,“蓝色”,“红色”,“绿色”,“蓝色”,“黑色”); 这里是结果:( 我没有足够高的水平发布图像,所以希望这个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,"")

    这只适用于数值是否正确的情况,即所有的“红”都在一起,所有的“蓝”在一起等等。假设你的数据是在A2列开始的 – (不要从第一行开始) B2types1在b3types= if(A2 = A3,B2,B2 + 1)拖动公式直到数据结束所有“红色”将是1,所有“蓝色”将是2所有“绿色”将是3等

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

    对于适用于多行和多列值的解决scheme,我发现以下公式非常有用,从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以引用您input此公式的单元格上方的单元格。

      =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的。

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

    脚步

    1. 对数据进行sorting
    2. 为公式添加列
    3. 检查单元格是否等于它上面的单元格
    4. 然后过滤Not a Duplicate
    5. 可选:复制公式列计算的数据并仅粘贴为值(如果您开始删除数据,则不会开始出错
    6. 注意/警告:这仅适用于先sorting数据的情况

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

    优化的VBScript解决scheme

    我使用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 

    select具有重复值的列,然后进入数据选项卡,然后数据工具select删除重复select1)“继续使用当前select”2)单击删除重复….button3)单击“全选”button4)单击好

    现在你得到唯一的价值清单。