在 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 添加正方形部分对角线内的值,这些值是相应值的乘积,直到较短数组的最后一个值。)
我对包含在单个单元格公式中的展开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 添加正方形部分对角线内的值,这些值是相应值的乘积,直到较短数组的最后一个值。)