数组公式返回没有重复项的ARRAY,没有VBA

时间:2017-11-14 19:49:51

标签: arrays excel excel-formula array-formulas

我想知道是否可以从单个单元格公式返回一个数组,该公式经过筛选以删除重复项,并且完全基于Excel公式构建。

我知道返回值的列表的方法,其中删除了重复项(请参阅this question),其中列表分布在多个单元格中。但是我特别想要返回一个数组中间体。

E.g。对于A1:A5中的列表,我可以获得一个值{0.1,0.2,0.2,0.7,0.3}的数组,我想从中获取第二个数组{0.1,0.2,0.7,0.3},作为数组公式中的中间值。 Current approaches使用单端锚定范围(如C$1:C1)以几何方式迭代数组中的项目(通过向下拖动列C)。我想在公式中对数组进行非迭代。然后,我可以像操纵任何其他数组一样操纵它。

如果可能,所有这些都应该在一个单元格中进行。

NB

MacroMarc'sBarry Houdini's答案都是完全有效的,我对每个答案都进行了速度检查 - 差异可以忽略不计(任何差异都小于测试运行之间的差异)。得分均为~1.0±0.2 ms

3 个答案:

答案 0 :(得分:4)

我已经为Range(A1:A5)使用了一个已定义的名称,并将其命名为myList。您可以这样做,或者如果您愿意,可以在地址$ A $ 1:$ A $ 5中替换:

{=INDEX(myList, N(IF({1}, MODE.MULT(IF(MATCH(myList, myList, 0) = ROW(myList), ROW(myList)*{1,1})))), 1)}

编辑:如果列表位于工作表的下方,则上述处理不健全,并且由OP提供较短的minrow例程:

{=INDEX(myList, N(IF({1}, MODE.MULT(IF(MATCH(myList, myList, 0)=ROW(myList)-MIN(ROW(myList))+1, (ROW(myList)-MIN(ROW(myList))+1)*{1,1})))), 1)}

这对你来说应该没问题。不用说,这些是数组公式..

答案 1 :(得分:3)

此公式将返回一个没有重复的排序数组,例如为你的例子

=SMALL(IF(MATCH(A1:A5,A1:A5,0)=ROW(A1:A5)-ROW(A1)+1,A1:A5),ROW(INDIRECT("1:"&SUM(0+(0<(FREQUENCY(A1:A5,A1:A5)))))))

=INDEX(A1:A5,N(IF({1},SMALL(IF(MATCH(A1:A5,A1:A5,0)=ROW(A1:A5)-ROW(A1)+1,ROW(A1:A5)-ROW(A1)+1),ROW(INDIRECT("1:"&SUM(0+(0<(FREQUENCY(A1:A5,A1:A5))))))))))

使用 CTRL + SHIFT + ENTER确认

......或者此版本将保留订单

class SchoolViewSet(viewsets.ViewSet): serializer_class = SchoolSerializer queryset = School.objects.all()

答案 2 :(得分:1)

使用此数组公式求和唯一,它需要使用TEXTJOIN(),它仅适用于Office 365 Excel:

=SUM( IF(ISERROR(FIND(TRIM(MID(TEXTJOIN(REPT(" ",999),TRUE,A:A),(ROW(INDIRECT("1:" & COUNTA(A:A)))-1)*999+1,999)),MID(TEXTJOIN(REPT(" ",999),TRUE,A:A),1,(ROW(INDIRECT("1:" & COUNTA(A:A)))-1)*999))),--TRIM(MID(TEXTJOIN(REPT(" ",999),TRUE,A:A),(ROW(INDIRECT("1:" & COUNTA(A:A)))-1)*999+1,999))))

作为一个数组公式,需要在退出编辑模式时使用Ctrl-Shift-Enter而不是Enter来确认。

您可以使用许多不同的公式替换SUM。

enter image description here

如果没有Office 365 Excel,则vba和/或辅助列是唯一可用的方法。

编辑:

要从数组中删除False并返回数组中的第3个非副本,我们可以将其包装在另一个TEXTJOIN中:

=--TRIM(MID(TEXTJOIN(REPT(" ",999),TRUE,IF(ISERROR(FIND(TRIM(MID(TEXTJOIN(REPT(" ",999),TRUE,A:A),(ROW(INDIRECT("1:" & COUNTA(A:A)))-1)*999+1,999)),MID(TEXTJOIN(REPT(" ",999),TRUE,A:A),1,(ROW(INDIRECT("1:" & COUNTA(A:A)))-1)*999))),--TRIM(MID(TEXTJOIN(REPT(" ",999),TRUE,A:A),(ROW(INDIRECT("1:" & COUNTA(A:A)))-1)*999+1,999)),"")),(3-1)*999,999))

3中的(3-1)*999可以替换为返回所需索引编号的任何内容。

仍然是需要Ctrl-Shift-Enter的数组公式。

![enter image description here

如果要返回相对位置,请使用此数组:

=AGGREGATE(15,6,ROW(INDIRECT("1:" & COUNTA(A:A)))/(--TRIM(MID(TEXTJOIN(REPT(" ",999),TRUE,IF(ISERROR(FIND(TRIM(MID(TEXTJOIN(REPT(" ",999),TRUE,A:A),(ROW(INDIRECT("1:" & COUNTA(A:A)))-1)*999+1,999)),MID(TEXTJOIN(REPT(" ",999),TRUE,A:A),1,(ROW(INDIRECT("1:" & COUNTA(A:A)))-1)*999))),--TRIM(MID(TEXTJOIN(REPT(" ",999),TRUE,A:A),(ROW(INDIRECT("1:" & COUNTA(A:A)))-1)*999+1,999)),"")),(ROW(INDIRECT("1:" & COUNTA(A:A)))-1)*999,999))=B1),1)

enter image description here

我给了你很长的公式来创建数组,但总和:

=SUMPRODUCT(A1:A5/COUNTIF(A1:A5,A1:A5)) 

就足够了。

对于平均值:

=SUMPRODUCT(A1:A5/COUNTIF(A1:A5,A1:A5))/SUMPRODUCT(1/COUNTIF(A1:A5,A1:A5))

如果你知道自己想要什么,有许多工作更短更好。