Ima*_*889 2 arrays excel concatenation excel-formula
我正在尝试创建一个公式,该公式返回两个不同长度的数组的串联。我需要将此串联用于另一个公式的一部分,如果可能的话,我希望避免使用“帮助”行。
参见下面的示例数据。
目的是使输出为{10;11;12;13;20;21;22}。当然,可以很容易地将其硬编码到公式中,但是这些值是动态的,因此不是一种选择。
我尝试了以下方法:
{A1:A4;B1:B3}
Run Code Online (Sandbox Code Playgroud)
但这显然不是有效的Excel语法。
有解决方案吗?
小智 20
如果您只需要连接两个数组并且您有最新版本的 Excel,我相信这是保持数组原始顺序的最短答案。
该答案循环遍历s数组(这是两个目标数组的组合长度),并使用 if 语句来确定是输出数组a 的元素还是数组b 的元素。
要将此公式复制并粘贴到工作簿中,您只需将A2#和B2#的值更改为您想要连接的两个数组。
多线版本
=LET(
a, A2#,
b, B2#,
s, SEQUENCE(ROWS(a) + ROWS(b)),
IF(s > ROWS(a),
INDEX(b, s - ROWS(a)),
INDEX(a, s)
))
Run Code Online (Sandbox Code Playgroud)
缩小版:
=LET(a,A2#,b,B2#,s,SEQUENCE(ROWS(a)+ROWS(b)),IF(s>ROWS(a),INDEX(b,s-ROWS(a)),INDEX(a,s)))
Run Code Online (Sandbox Code Playgroud)
Excel无法按照您描述的方式直接串联数组(即,简单地将它们背靠背组合在一起)。但是,有一个(复杂的)解决方案,无需使用辅助函数即可解决此问题。
本质上,您需要做的是将转换{10;11;12;13}为{10;11;12;13;0;0;0}并转换{20;21;22}为{0;0;0;0;20;21;22}。得到该结果后,可以将长度为7的两个数组加在一起以获得所需的结果。
那么如何将零添加到数组的开头或结尾?
答案是MMULT巧妙地使用矩阵乘法(Excel内置函数)。
我不会解释所有数学原理,为什么会这样,因为我认为编程太离题了,但最终以下矩阵乘法方程式为您提供了理想的结果:
[1 0 0 0] [10] [10]
[0 1 0 0] * [11] = [11]
[0 0 1 0] [12] [12]
[0 0 0 1] [13] [13]
[0 0 0 0] [ 0]
[0 0 0 0] [ 0]
[0 0 0 0] [ 0]
Run Code Online (Sandbox Code Playgroud)
或者在Excel中,您可以键入以下内容来获得结果:(我添加了换行符以提高可读性。)
= MMULT({1,0,0,0;
0,1,0,0;
0,0,1,0;
0,0,0,1;
0,0,0,0;
0,0,0,0;
0,0,0,0},A1:A4)
Run Code Online (Sandbox Code Playgroud)
如果您在单元格中突出显示此公式并按F9键,则应注意它将为您提供所需的结果{10;11;12;13;0;0;0}。
同样,以下公式将为您提供所需的结果{0;0;0;0;20;21;22}:
= MMULT({0,0,0;
0,0,0;
0,0,0;
0,0,0;
1,0,0;
0,1,0;
0,0,1},B1:B3)
Run Code Online (Sandbox Code Playgroud)
将这两个值加在一起将得到所需的最终结果{10;11;12;13;20;21;22}。
注意
在这一点上,这可能足以满足您的需求。但是,对于大型数组,将这些1和0的矩阵硬编码到公式中可能太麻烦了。如果是这种情况,请继续阅读以了解如何自动生成这些1和0的矩阵,而不是对其进行硬编码。
我们如何自动生成上面显示的1和0的大型矩阵?
同样,由于我认为讨论将变得太长且太离题了,因此在这里没有解释很多“为什么”,下面是一个公式,该公式生成上面的1和0的第一个矩阵:
= (ROW(INDIRECT(ADDRESS(1,1)&":"&ADDRESS(ROWS(A1:A4)+ROWS(B1:B3),1)))
=COLUMN(INDIRECT(ADDRESS(1,1)&":"&ADDRESS(1,ROWS(A1:A4)))))+0
Run Code Online (Sandbox Code Playgroud)
1和0的第二矩阵的公式略有不同:
= (ROW(INDIRECT(ADDRESS(1,1)&":"&ADDRESS(ROWS(A1:A4)+ROWS(B1:B3),1)))
=(COLUMN(INDIRECT(ADDRESS(1,1)&":"&ADDRESS(1,ROWS(B1:B3))))+ROWS(A1:A4)))+0
Run Code Online (Sandbox Code Playgroud)
最终公式
连接两个(垂直)数组的最终公式如下:(添加了多个换行符以提高可读性)
= MMULT(
(ROW(INDIRECT(ADDRESS(1,1)&":"&ADDRESS(ROWS(A1:A4)+ROWS(B1:B3),1)))
=COLUMN(INDIRECT(ADDRESS(1,1)&":"&ADDRESS(1,ROWS(A1:A4)))))+0,
A1:A4)
+MMULT(
(ROW(INDIRECT(ADDRESS(1,1)&":"&ADDRESS(ROWS(A1:A4)+ROWS(B1:B3),1)))
=(COLUMN(INDIRECT(ADDRESS(1,1)&":"&ADDRESS(1,ROWS(B1:B3))))+ROWS(A1:A4)))+0,
B1:B3)
Run Code Online (Sandbox Code Playgroud)
最后的笔记/思想
使用此公式的优点是它允许在不使用VBA的情况下串联数组。缺点是这种用于连接数组的方法仅适用于数字,不适用于文本。(这是因为MMULT需要数字。)
就其价值而言,这是一个连接两个任意两个垂直数组的解决方案(没有数据必须是数字的限制)。
这是数组公式:(例如组合A1:A4和C7:C9)
= INDEX(CHOOSE({1,2},A1:A4,C7:C9),
N(IF({1},ROW(INDEX($A:$A,1):INDEX($A:$A,ROWS(A1:A4)+ROWS(C7:C9)))-IF(
ROW(INDEX($A:$A,1):INDEX($A:$A,ROWS(A1:A4)+ROWS(C7:C9)))<=ROWS(A1:A4),0,ROWS(A1:A4)))),
N(IF({1},2-(ROW(INDEX($A:$A,1):INDEX($A:$A,ROWS(A1:A4)+ROWS(C7:C9)))<=ROWS(A1:A4)))))
Run Code Online (Sandbox Code Playgroud)
这是组合两个水平数组的数组公式(例如A1:D1和C3:E3)
= INDEX(CHOOSE({1;2},A1:D1,C3:E3),
N(IF({1},2-(COLUMN(INDEX($1:$1,1):INDEX($1:$1,COLUMNS(A1:D1)+COLUMNS(C3:E3)))
<=COLUMNS(A1:D1)))),N(IF({1},COLUMN(INDEX($1:$1,1):INDEX($1:$1,COLUMNS(A1:D1)+
COLUMNS(C3:E3)))-IF(COLUMN(INDEX($1:$1,1):INDEX($1:$1,COLUMNS(A1:D1)+COLUMNS(C3:E3)))
<=COLUMNS(A1:D1),0,COLUMNS(A1:D1)))))
Run Code Online (Sandbox Code Playgroud)
小智 5
如果您有动态数组版本的 Excel、Excel 365 或 2019 年之后的版本,则答案要短得多。如果一列被命名Foo而另一列被命名Bar,则您的公式将是:
=SMALL((Foo,Bar),SEQUENCE(ROWS(Foo)+ROWS(Bar)))
这里,SEQUENCE返回一个数组,其序列为 1 到 Foo 和 Bar 的总行数。SMALL为序列中的每个值返回适当的值。然后 Excel 将结果“溢出”到公式下方所需的行数中。
感谢该线程之前的贡献者,我了解到附加数组数据的解决方案在于使用相等长度的数组。
该解决方案适用于文本和数字,但我使用了文本。
在下面的示例中,我加入了 3 个命名范围(分别命名为 Range1、Range2 和 Range3)。我还确保每个范围中的项目顺序保持不变,尽管这可能不是必要的。
我使用了Excel 365的LET函数来方便阅读。该范围只是溢出到输入公式的空白列中。
=LET(
TotRows,ROWS(Range1)+ROWS(Range2)+ROWS(Range3),
A,INDEX(Range1,SEQUENCE(TotRows)),
B,INDEX(Range2,SEQUENCE(TotRows,,-ROWS(Range1)+1,1)),
C,INDEX(Range3,SEQUENCE(TotRows,,-ROWS(Range1)-ROWS(Range2)+1,1)),
X,IFERROR(IFERROR(A,B),C),
X)
Run Code Online (Sandbox Code Playgroud)
更多范围可以轻松添加为 D、E、F 等。然后只需在末尾包装更多 IFERROR() 函数即可。我返回 X,但您当然可以将其包装到 UNIQUE() 中以提取唯一列表,或者您可以对其进行 SORT() 等。
当您稍微修改它以组合溢出范围时,事情会变得更加有趣和动态(即,命名范围被对溢出范围的引用替换(有关示例和使用的公式,请参阅随附的屏幕截图)
我的输入和结果如下所示:数据和公式输出的屏幕截图
祝你好运。