在不使用VBA的情况下,通过循环将n 个命名区域堆叠起来
我正在寻找一种方法,能够把数组(也就是存放在Excel表中的按名称命名的区域)堆叠起来,方法是利用另一个表中存放的表名。实际目标不仅是把两个区域堆叠起来,而是要堆叠更多的区域。
请参阅我的数据作为起点
.
我知道以下这些会得到相同的结果:
=VSTACK(rangeA;rangeB)
=VSTACK(INDIRECT("range" & XLOOKUP(1;info[ID];info[Name])); INDIRECT("range" & XLOOKUP(2;info[ID];info[Name])))
同样地,
=LET(id;A1;INDIRECT("range" & XLOOKUP(id;info[ID];info[Name])))
返回(单元格 A1 的内容为1 或2 时)某一个命名区域,我原本以为/希望
=VSTACK(LET(id;SEQUENCE(2);INDIRECT("range" & XLOOKUP(id;info[ID];info[Name]))))
能够达成效果,但并没有。我感觉用某种方式 BYROW(SEQUENCE(x);LAMBDA(id;...)) 可能是正确的做法,但到目前为止我的尝试都产生了各种错误信息(也不清楚应该把堆叠公式放在哪里)。
数据
| ID | 名称 |
|---|---|
| 1 | A |
| 2 | B |
rangeA
| ID | 值 |
|---|---|
| 1 | x11 |
| 2 | x12 |
rangeB
| ID | 值 |
|---|---|
| 3 | y11 |
| 4 | y12 |
解决方案
在这里尝试使用 REDUCE() 函数:
=DROP(REDUCE("", XLOOKUP(SEQUENCE(2),
Info[ID],
"range"&Info[Name], ""),
LAMBDA(x,y, VSTACK(x, INDIRECT(y)))), 1)
以上公式把一组命名区域堆叠成一个列表。它先从查找表构建范围名称,然后把它们聚拢一起。逐步解释如下:
SEQUENCE(2)--> 这会生成{1; 2},用于从 Info 表中提取前两个IDXLOOKUP(SEQUENCE(2), Info[ID], "range"&Info[Name], "")--> 这会在 Info[ID] 中查找 1 和 2,并返回将 "range" 与在 Info[Name] 的每个匹配项拼接的结果- 输出将是
{"rangeA"; "rangeB"} - 为空字符串的引号只是为了应对没有匹配的情况。
REDUCE("", ..., LAMBDA(x, y, VSTACK(x, INDIRECT(y))))--> 这从一个空值开始,然后遍历来自XLOOKUP()函数的每一个名称INDIRECT()函数在每次迭代时把文本 "rangeA" 转换成实际的区域VSTACK()函数在先前的基础上不断把每个区域追加,最终把所有内容堆叠成一列DROP(..., 1)--> 由于REDUCE()是从空值开始,因此顶部会出现一行空白,这一步把第一行删去,只保留真正的数据。
为了更易读一些,可以尝试:
=LET(
_a, Info,
_b, SEQUENCE(ROWS(_a)),
_c, XLOOKUP(_b, Info[ID], "range"&Info[Name], ""),
REDUCE({"ID","Value"}, _c, LAMBDA(x,y,
VSTACK(x, INDIRECT(y)))))
其中 Info 是包含ID及其对应Names的表的名称。
或者,使用Power Query:
要使用Power Query,请按以下步骤:
- 首先把源区域转换成表并按相应名称命名,在本例中我将其命名为
Info
- 接下来,在 Data(数据) 选项卡里打开一个空白查询 --> Get & Transform Data --> Get Data --> From Other Sources --> Blank Query
- 上述步骤会打开 Power Query 窗口,现在在 Home(主页) 选项卡中点击 Advanced Editor(高级编辑器) --> 将下面的 M-Code 粘贴进去(删除你看到的现有文本)并点击 Done(完成)
let
Source = Excel.CurrentWorkbook(){[Name="Info"]}[Content],
DataType = Table.TransformColumnTypes(Source, {{"ID", Int64.Type}, {"Name", type text}}),
JoinRangeName = Table.AddColumn(DataType, "RangeName", each "range" & [Name], type text),
AddTableContents = Table.AddColumn(JoinRangeName, "TableContent", each
let
RangeName = [RangeName],
MatchingTable = Excel.CurrentWorkbook(){[Name = RangeName]}[Content]
in
MatchingTable),
RemovedOtherCols = Table.SelectColumns(AddTableContents,{"TableContent"}),
Answer = Table.ExpandTableColumn(RemovedOtherCols, "TableContent", {"ID", "Value"}, {"ID", "Value"})
in
Answer
- 最后,要把结果导回 Excel --> 点击 Close & Load 或 Close & Load To --> 第一个会创建一个带有所需输出的新工作表,后者会弹出一个窗口让你选择放置结果的位置。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

