尝试使用索引/匹配来完成SUM

时间:2019-06-14 00:35:12

标签: excel excel-formula

我正在尝试对表中的多行和多列进行求和,具体取决于它们在哪个星期和所在的地区:

Id想将所有数字加总到WK-8,然后根据区域E N S W

下面的图片是数据表的一小部分

enter image description here

1 个答案:

答案 0 :(得分:1)

此解决方案在假设您对地区和星期进行排序的前提下工作。这将导致所有相同区域都在相邻列中,而所有相同星期都在相邻行中。基于此假设,所有需要做的就是定义范围的角(如果需要,可以选择选择框)并将其转储到求和函数中。

有关使用的范围参考,请参见下图,并进行调整以适合您的需求。

为此,以下解决方案将需要使用以下公式:

  • AGGREGATE
  • ROW
  • INDEX
  • 总和

AGGREGATE是归纳为一个函数的一大堆不同公式。它采用以下格式:

AGGREGATE(formula #, Option#,ARRAY/RANGE, Parameter)

此解决方案使用的公式为14和15。这两个特定的公式使AGGREGATE在AGGREGATE函数中执行类似于数组的计算。因此,请避免在AGGREGATE中使用完整的列/行引用,例如A:A或2:2,否则可能会产生大量多余的计算。公式14将数组从最大到最小排序,而公式15将数组从最小到最大排序。

有几个可用的选项#可以告诉AGGREGATE忽略某些条件,例如隐藏的信息或错误值。对于此解决方案,将使用6告诉AGGREGATE忽略所有错误。

将在数组/范围部分中开发出符合我们标准的行号或列号列表。

我们正在使用的公式的参数将告诉AGGREGATE从数组中哪个位置返回一个值。

根据上述信息,此解决方案将使用AGGREGATE确定FIRST和LAST ROW和COLUMN号。将使用4个不同的公式,但它们将非常相似。

因此,公式的基本设置为:

Last ROW/COL
=AGGREGATE(14,6,ARRAY,1)
or
First ROW/COL
=AGGREGATE(15,6,ARRAY,1)

因此,困难的部分将是开发阵列。让我们从列开始,然后遵循相同的方法并获得行。要获取潜在列号的列表,您将需要以下公式:

COLUMN(D4:G4)

这将为您提供所有列号。现在,在这种情况下,您需要添加条件,我们将使用列等于某项的条件。对于其他情况,您可能希望所有列都大于某个日期,或者不等于某个值,这可能会有所不同。在这种情况下,您只需要更改比较运算符即可满足您的需求。因此,这里的关键是当我们匹配所需的内容时,我们将获得TRUE值,而当某些内容不匹配时,您将获得FALSE值。更重要的是,当数学运算符(例如+,-,*,/,^等)对TRUE和FALSE进行操作时,对于TRUE,它们将转换为1;对于FALSE,它们将转换为0。通过诸如SUM之类的函数发送它们并不总是进行转换。因此,这一点很重要的原因是我们希望排除所有与我们所寻找的东西不匹配的东西。它们将返回False的值。我们将根据潜在列号的正确与错误进行划分。这意味着我们将被1和0除。如果被0除,则会生成错误。因为我们在AGGREGATE中选择6来忽略错误,所以这些列号将从排序列表中排除,您将只剩下所需的列号。因此,ARRAY公式部分变为:

COLUMN(D4:G4)/(D4:G4=C14)

现在将其放入AGGREGATE公式中,您将得到:

=AGGREGATE(15,6,COLUMN(D4:G4)/(D4:G4=C14),1)

这将为您提供第一列编号。要获得第一行号,我们只需将数组部分更改为行操作,如下所示:

ROW(C5:C8)/(C5:C8=C13)

然后将其转储到AGGREGATE函数中以获取:

=AGGREGATE(15,6,COLUMN(D4:G4)/(D4:G4=C14),1)

因此,使用以上两个AGGREGATE函数,您现在具有第一列和第一行。为了获得最后一列和最后一行,只需反转数组部分的排序顺序即可,这可以通过将AGGREGATE从使用公式15更改为使用公式14来完成。您的相应公式变为:

=AGGREGATE(14,6,COLUMN(D4:G4)/(D4:G4=C14),1)
=AGGREGATE(14,6,COLUMN(D4:G4)/(D4:G4=C14),1)

因此,现在您有了要求和的区域的左上角和右下角的位置。您可以使用其他方法来定义范围,例如使用OFFSET,但这是一个易失函数。易失性函数将导致工作表/工作簿更改中的任何内容随时重新计算工作表。这会导致很多不必要的计算。而是使用INDEX,这是一个常规函数。仅在影响它的事物发生变化时才重新计算。

大多数人都假设index的结果就是它返回的单元格的值。实际上,索引返回一个单元地址。该单元格地址反过来获取该单元格中的值。这意味着您实际上可以编写具有两个索引函数的范围地址,如下所示:

INDEX(...):INDEX(...)

现在,您只需获取INDEX即可浏览工作表中的所有列和行,并定义您感兴趣的列和行。哪个AGGREGATE为我们确定了。因此左上角单元格的INDEX公式为:

=INDEX(1:1048576,C18,C16)

,右下角单元格的索引是:

=INDEX(1:1048576,C19,C17)

如果您将其输入为公式,您将看到的不是先前讨论的地址,而是该地址的值。可能是验证它是否选择正确值的一种好方法

要定义要取其总和的范围,请采用上述公式,并在它们之间放置一个:,如下所示:

INDEX(1:1048576,C18,C16):INDEX(1:1048576,C19,C17)

上面的内容不能真正在单元格中单独起作用,但是由于它是您想要求和的范围,因此可以将上面的范围放到SUM函数中,得出以下公式:

SUM(INDEX(1:1048576,C18,C16):INDEX(1:1048576,C19,C17))

因此,通过在可能的情况下将公式分解成几个部分,公式很短并且相对容易阅读,因此更易于维护。如果您确实需要将所有内容都放在一个单元格中,则可以将各个公式相互替换,以获取以下冗长,丑陋且难以阅读的公式:

=SUM(INDEX(1:1048576,AGGREGATE(15,6,ROW(C5:C8)/(C5:C8=C11),1),AGGREGATE(15,6,COLUMN(D4:G4)/(D4:G4=C12),1)):INDEX(1:1048576,AGGREGATE(14,6,ROW(C5:C8)/(C5:C8=C11),1),AGGREGATE(14,6,COLUMN(D4:G4)/(D4:G4=C12),1)))

POC