如何使用VSTACK将由用户自定义的LAMBDA函数返回的、行数不定的列数组堆叠起来?是否有替代方案?
首先,对在提问时还在使用Android版 Excel表示抱歉。

我的目标:
从 B3 与 B11 的文本出发,我想创建一个 数组,其中每个元素代表合并文本中的一行,且排除空行。
预期结果:
在 B3 处,总共有7 行(其中有文本的有5 行,空行2 行),在 B11 处同样也是7 行(有文本的为5 行,空行2 行)。因此我的数组应该有 5 + 5 = 10行。
我得到的结果:
正如你在单元格 E19 看见的,我得到的数组只有2 个元素,只包含 B3 与 B11 的第一行内容。
我的代码:
=LET(itr,LAMBDA(LP,res,arr,i,IF(i=3,res,LET(ele,INDEX(arr,i),nx,LP(LP,res,arr,i+1),IF(ele=0,nx,LET(ele_process,TEXTSPLIT(ele,,CHAR(10)),ele_filter,FILTER(ele_process,NOT(REGEXTEST(ele_process,"^\s*$")),0),IF(ele_filter=0,nx,LP(LP,IF(INDEX(res,1)=0,ele_filter,VSTACK(res,ele_filter)),arr,i+1))))))),itr(itr,{0},VSTACK(B3,B11),1))
说明:
变量 / 函数参数:
- itr - 它是用于生成数组的lambda函数。它接收 LP、res、arr 和 i 作为参数
- LP - 用于循环调用该函数或创建递归
- res - 每次调用后数组提供的结果
- arr - 将文本使用VSTACK合并后得到的数组,然后传给函数
- i - arr 中元素的索引
- ele - 表示 arr 在索引 i 处的元素;若对应的文本框(B3或 B11)为空,则它可以是0
- nx - 用于将 itr 函数递归的冗长代码简化为仅通过增加参数i 来处理 arr 的下一个元素
- ele_process - 保存表示 ele 文本每一行(包括空行)的数组
- ele_filter - 从 ele_process 中去除所有空行;如果 ele 只包含空行,则它可以是0
函数逻辑:
如果与该函数实例相关的文本框为空,ele 会自动变为0,函数会移动到数组 arr 的下一个元素;否则,它会创建一个包含文本 ele 每一行的数组(ele_process)。接着,从 ele_process 中过滤掉所有空行(ele_filter)。如果 ele_filter 的结果为0,意味着 ele 只包含空格,那么函数会像 ele 自身为0 时一样跳到 arr 的下一个元素。否则,函数会继续移动到 arr 的下一个元素,但这时它通过检查现有 res 的第一项来更新结果 res。如果它为0(因为Excel不支持空数组的概念,我在作为参数传给函数时使用 {0}),那么就用 ele_filter 替换它;否则就把 ele_filter 追加到已有的 res 末尾(这意味着现有的 res 已经包含前一个 ele 的每一行)。
我该如何实现我期望的结果数组?需要避免使用VSTACK吗?
提前感谢!
解决方案
=LET(x,CHAR(10),TEXTJOIN(x,,TEXTSPLIT(CONCAT(B3:B11&x),x,,1)))
Or more specific to given cells:
=LET(x,CHAR(10),TEXTJOIN(x,,TEXTSPLIT(CONCAT(VSTACK(B3,B11)&x),x,,1)))
备选方案
仅使用 TEXTSPLIT 和 TEXTJOIN,若先将列拼接再拆分,则这是在指定列中的动态公式。
=TEXTSPLIT(TEXTJOIN(CHAR(10),TRUE,B1:B20),,CHAR(10),TRUE)
如果工作表上仅有相关数据,B:B 范围可以用来实现全局灵活性。否则可能会涉及到最大列范围。(例如 B3:B127)
