在 SUMPRODUCT 内部使用时,使用电子表格函数更改数组维度

Change array dimensions, using spreadsheet functions, when used inside SUMPRODUCT

我对包含在单个单元格公式中的展开sheet 函数感兴趣,而不是 VBA 解决方案。

[A1:A15 包含 1 到 127 的数值,B1:B15 包含 1 到 7 的设置除数的整数。]

给定函数:

=SUMPRODUCT(MOD(FREQUENCY(A1:A15;A1:A15);B1:B15))

FREQUENCY(A1:A15;A1:A15) 给出 15+1 行的 1 列数组,而第二部分 (B1:B15) 是 15 行的 1 列数组。

我想将 FREQUENCY 给出的结果数组(仅在内存中 - 在 sheet- 中不明确)从 1 列 16 行数组更改为 1 列 15 行数组,第一个该数组的 15 个单元格值。

[FREQUENCY 文档:https://support.office.com/en-us/article/FREQUENCY-function-44e3be2b-eca0-42cd-a3f7-fd9ea898fdb9 注意:对于 Excel,第二个注释说明了依赖于 bins_array 的元素数量。 ]

我将不胜感激。

因此,MOD 中的两个数组将具有相同的维度,并且 SUMPRODUCT 不会找到具有错误值的单元格。我可以在 SUMPRODUCT 中使用 IF 和 ISERROR 忽略错误值,但如果可能的话,我宁愿忽略 FREQUENCY 结果数组中不相关的部分。

人们认为使其更具体可能更有帮助,因此已对其进行了大量缩减和简化。

在外部帮助下,我已经能够微调一种方法来解决我在数组公式模式下使用 INDEX 的问题。我发布答案以防对其他人有帮助。

一种方法:将 FREQUENCY(A1:A15;A1:A15) 或任何生成多单元格数组的公式放在 INDEX 中,并将第二个 and/or 第三个参数作为连续值的数组,表示 rows/columns.

INDEX(FREQUENCY(A1:A15;A1:A15);ROW(INDIRECT("1:" & ROWS(FREQUENCY(A1:A15;A1:A15)-1));1)

INDEX 中的第一个参数是来自要缩小的公式(从 16x1 到 15x1)的结果数组,如果明确输入,这将是一个多单元格数组公式;第二个参数是数组 1..15,行号从 1 到 "array from formula to shrink" 的总行数减去 1:公式中数组中的前 15 个(共 16 个)值;第三个参数是收缩数组的列(如果需要,可以使用与第二个参数类似的方法选择多个)。

在 FREQUENCY 的特殊情况下,因为已知我们对函数的 "bins" 部分感兴趣,所以可以通过包含 "bins"/ 的总行数来简化公式"intervals" FREQUENCY 中的数组(它的第二个参数)。我们会有

INDEX(FREQUENCY(A1:A15;A1:A15);ROW(INDIRECT("1:" & ROWS(A1:A15)));1)

完整的公式将变为

SUMPRODUCT(MOD(INDEX(FREQUENCY(A1:A15;A1:A15);ROW(INDIRECT("1:" & ROWS(A1:A15)));1);B1:B15))

现在,MOD 的被除数和除数具有完全相同的维度 (15x1),并且因为 B1:B15 包含大于 0 的整数,所以没有错误。

感谢大家帮助我使问题更简洁、格式更好。

附加信息:正如 XOR LX 在评论中正确指出的那样,这似乎不适用于广受欢迎的电子表格软件 Excel。它是为 SUMPRODUCT 中的 INDEX 函数开发的,如 Open Office Calc 中所用,我曾错误地认为 100% 等同于 Excel 的版本。可能使用其他功能的更完整的答案将不胜感激。

在之前的回答中,XOR LX 非常正确地指出,由于 row_num/column_num 参数行为,此公式无法在 Excel 中工作。非常友好的异或 LX 向我展示了这种方法是如何工作的,也感谢并感谢您提供了一个好的答案:"INDEX can be used to redimension array (even dynamically created ones) if the row_num/column_num array is coerced to take an arbitrary array with the right dimensions, as shown on this blog entry " 下面的公式已在 Excel 2010年并取得预期成果:

SUMPRODUCT(MOD(INDEX(FREQUENCY(A1:A15,A1:A15),N(INDEX(ROW(INDIRECT("1:" & ROWS(A1:A15))),,)),1),B1:B15))

注意:第一个 INDEX 的 row_num 参数,一个 ROW 生成的辅助数组,已嵌套在 N(INDEX([...],)) 中;至少需要一个逗号来说明嵌套索引的两个参数最小值。讨论通常适用于 INDEX 的参数和其他需要强制采用数组的函数(参见 XOR LX 博客上的 here and here)本身就很有趣。对于 Open Office 用户,可能值得强调一下博客中提出的观点

Unlike OFFSET, (...) for which the first parameter must be a reference (...) in the worksheet, INDEX can also accept – and manipulate – for its reference arrays which consist of values generated e.g. via other subfunctions within the formula. XOR LX's blog

在这个问题中更改数组中的维度确实是这种情况,但在反转或置换数组中的值等方面也很有用。 Open Office 接受数组 row_num/column_num,因此不需要强制转换,一些公式依赖于此,但如果没有它,这些公式在 Excel.

中打开文件时不太可能起作用

遗憾的是,这种类型的强制转换没有正确传递给 Open Office,并且公式需要 "decoerced" 才能工作,至少在我的临时测试中是这样。

为了使用在两个电子表格程序中都适用的缩短数组的公式,我唯一做到的是以下内容(要求:数组必须是单列)

SUMPRODUCT(
(COLUMN(INDIRECT("R1C1:R"& ROWS(vals_to_mod) &"C"& ROWS(FREQUENCY(vals_for_freq,vals_for_freq)),FALSE))
-ROW(COLUMN(INDIRECT("R1C1:R"& ROWS(vals_to_mod) &"C"& ROWS(FREQUENCY(vals_for_freq,vals_for_freq)),FALSE))
=0)
*MOD(TRANSPOSE(FREQUENCY(vals_for_freq,vals_for_freq)),vals_to_mod)
)

(它 "shortens" 一个数组到最短的一对,通过创建一个辅助数组,在从左上角开始的对角线上 TRUE/1s 和其他地方的 FALSE/0s ,因此忽略所有在数组的正方形部分之外定义值。因此,SUMPRODUCT 添加正方形部分对角线内的值,这些值是相应值的乘积,直到较短数组的最后一个值。)