频率()与数组:添加一个元素返回数组

我使用以下公式作为命名公式(通过名称pipe理器)。 然后它被用在一个更大的sumproduct()中。 我们的目标是确保在使用数组计算的情况下,对于某些特定的行只计算一次(例如,对于A类,您有相同的数据在多行中重复。我只需要知道A类中有多less人)。

=IF(FREQUENCY(IF(LEN(tdata[reportUUID])>0,MATCH(tdata[reportUUID], tdata[reportUUID],0),0),IF(LEN(tdata[reportUUID])>0,MATCH(tdata[reportUUID], tdata[reportUUID],0),0))>0,TRUE) 

让我们用Excel中的评估公式一步一步浏览结果。 抱歉的截图,但Excel不允许复制真实的数据的实际步骤….

按照步骤顺序:

Step1,数组中有6个项目

还有6个项目

还是6

还是6,一切都好

谁最后命令了第七项?

在最后的图片中,我的数组中有第7个项目。 我只有6行数据,因此为什么在前面的步骤中,我只有6个项目在数组中,正如所料。

这是搞乱了我的计算,因为从这个函数的返回数组乘以其他所有有6项(或无论是我有数据行数)的数组。

这是什么第七项,我怎么能得到它或防止它返回错误?

我曾尝试将一些公式包装到iferror()或ifna()中,但是它并不干净。 我觉得这可能会适得其反,并不是一个强有力的办法。 我宁愿把它在源头….

编辑:例如用于其他数组:

 {=SUMPRODUCT(--IFERROR(((tdata[_isVisible]=1)*(f_uniqueUUIDfactor),0))} 

其中f_uniqueUUIDfactor是来自初始文章的公式。 tdata [_isVisible] = 1用于过滤仪表板上的数据(例如通过下拉菜单,用户可以设置date范围,使用VBA将原始数据中的行隐藏在范围内)。

重点是sumproduct()最终将每个原始数据行thothheter乘以0和1秒,以便只有满足所有标准的人才能返回。 上面的IFERROR()是frequency()引入的额外数组元素的解决方法。 它的工作原理,但如果一个更清洁的方式存在,我更喜欢这一点。 我也会热衷于理解为什么这些元素被添加。

这是一个很好的例子,为什么当根据多个条件计算数组时,最好使用多个recursionIF语句,而不是形成这些数组的产物。

首先,在说明理由之前,我应该指出一些小的技术上的不准确/缺陷。

1)通过在作为FREQUENCYdata_arraybins_arrayparameter passing的构造中包含一个value_if_false子句,可能会导致错误的结果,因为零是FREQUENCY考虑的有效数字,而布尔FALSE (这将是等效条目在结果数组中,你完全省略了value_if_false子句)被这个函数忽略。

2) MATCH一个精确的(即0或者FALSEMATCH参数是一个相对资源较重的结构,特别是如果要考虑的范围相当大。 因此,由于没有必要将这种结构用于FREQUENCYbins_array参数,所以最好使用更高效的:

ROW(tdata[reportUUID])-MIN(ROW(tdata[reportUUID]))+1

此外,请注意,在第二个参数中重复IF(LEN构造也是不必要的。

总之,那么:

IF(FREQUENCY(IF(LEN(tdata[reportUUID])>0,MATCH(tdata[reportUUID],tdata[reportUUID],0)),ROW(tdata[reportUUID])-MIN(ROW(tdata[reportUUID]))+1)>0,TRUE)

比你给出的版本更严格和更有效率。

为了回答你的主要问题, FREQUENCY总是返回一个数组,其条目数大于传递的bins_array数

正如我在对你的post的评论中所提到的那样,你所面临的问题的解决在很大程度上取决于你对最终arrays的进一步操纵。

但是,为了说明起见,我们假设您只是希望将您的FREQUENCY构造所产生的数组与您表中的某个其他列相乘, tdata [Column2]说,然后对结果进行求和。

和…之间的不同:

=SUM(IF(FREQUENCY(IF(LEN(tdata[reportUUID])>0,MATCH(tdata[reportUUID],tdata[reportUUID],0)),ROW(tdata[reportUUID])-MIN(ROW(tdata[reportUUID]))+1)>0,TRUE)*tdata[Column2])

即使用两个数组的乘法,并且:

=SUM(IF(FREQUENCY(IF(LEN(tdata[reportUUID])>0,MATCH(tdata[reportUUID],tdata[reportUUID],0)),ROW(tdata[reportUUID])-MIN(ROW(tdata[reportUUID]))+1)>0,tdata[Column2]))

即使用一个简单的IF子句,在这里是至关重要的。

事实上,前者总是会返回一个错误,而后者通常不会。

原因是前者会解决(假设你的表有例如10行的数据,假设一些随机的布尔结果用于FREQUENCY结构):

=SUM(IF({TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE},TRUE)*tdata[Column2])

这是因为value_if_true子句在这里是多余的:

=SUM({TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE}*tdata[Column2])

而我给予的第二个build设将解决:

=SUM(IF({TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE},tdata[Column2]))

两者可能看起来完全相同,但前者使用乘法来parsing数组,而后者不是这样的事实是关键的区别。

尽pipe在这两种情况下由FREQUENCY构造产生的arrays,即:

{TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE}

包含11个条目(即,比第二个数组中的条目数目多1个),不同之处在于,当您试图将11元素数组与10元素数组(即tdata [Column2]相乘时 , Excel不是完全禁止这样的操作,而是人为地重新调整两个arrays中较小的一个,使其与较大的尺寸匹配。

但是,在此过程中,任何附加条目都会自动设置为#N/A错误值。

那么有效的呢,

=SUM({TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE}*tdata[Column2])

解决为:

=SUM({TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE}*{38;67;49;3;10;11;97;20;3;57;#N/A})

即如上所述,第二个10元素的arrays被重新调整到11个元素之一,以试graphics成合法的操作。 而且还提到,第11个因素是#N/A ,这意味着整个build设也将导致这个价值。

然而,在非乘法版本中,即:

=SUM(IF({TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE},tdata[Column2]))

虽然也发生了同样的重构,但是我们通过使用IF子句来代替乘法来保存,因为上面的解决方法是:

=SUM(IF({TRUE;FALSE;TRUE;FALSE;TRUE;TRUE;TRUE;FALSE;TRUE;FALSE;FALSE},{38;67;49;3;10;11;97;20;3;57;#N/A}))

而这里的第11个位置的布尔FALSE '覆盖'与第二个arrays相同位置的误差值,因为上面解决了:

=SUM({38;FALSE;49;FALSE;10;11;97;FALSE;3;FALSE;FALSE})

问候