英文:
Flatten Parent Child Hierarchy in Excel (using formula or VBA)
问题
我想在Excel中展平父子层次结构。例如:
如果我的原始数据是蓝色的,我想要更改的目标是橙色区域。
我如何使用VBA或Excel公式来解决这个问题?
提前感谢!
英文:
I want to flatten Parent Child Hierarchy in Excel. For example:
If my original data is in blue, the destination I want to change is the orange area.
How can I use VBA or Excel formula to resolve it?
Thanks in advance!
答案1
得分: 3
以下是您要翻译的内容:
这个版本仅仅是一个公式:
=DROP(
REDUCE("",
SORT(
REDUCE("",
MAP(UNIQUE(TOCOL(Table3)),
LAMBDA(x,
REDUCE(x,SEQUENCE(ROWS(UNIQUE(Table3[Col 1]))+1),
LAMBDA(a,b,
TEXTJOIN("|",1,a,XLOOKUP(TEXTAFTER(a,"|",-1,,,a),
Table3[Col 2],
Table3[Col 1],
"")))))),
LAMBDA(a,b,
LET(c,TEXTSPLIT(b,"|"),
d,COUNTA(c),
VSTACK(a,TEXTJOIN("|",1,INDEX(c,,SEQUENCE(,d,d,-1)))))))),
LAMBDA(a,b,
LET(c,TEXTSPLIT(b,"|"),
d,COUNTA(c),
IFERROR(
VSTACK(a,
IF(SEQUENCE(,d)=d,INDEX(c,,d),"")),
""))),
2)
它从表格中获取所有唯一的值(在我的示例中是Table3),然后从子列 Col 2
中查找该值的父列 Col 1
,一直查找,直到找不到任何父级为止。
这导致了从子级到主父级的链条。为了能够以适当的方式对结果进行排序,需要反转这个结果(从主父级到最新的子级),然后进行排序。然后只显示每行的最后一个值。
希望这有所帮助。
英文:
Probably less efficient than Jos' version, but I haven't been able to test that yet (not behind a laptop).
This version is solely formula:
=DROP(
REDUCE("",
SORT(
REDUCE("",
MAP(UNIQUE(TOCOL(Table3)),
LAMBDA(x,
REDUCE(x,SEQUENCE(ROWS(UNIQUE(Table3[Col 1]))+1),
LAMBDA(a,b,
TEXTJOIN("|",1,a,XLOOKUP(TEXTAFTER(a,"|",-1,,,a),
Table3[Col 2],
Table3[Col 1],
"")))))),
LAMBDA(a,b,
LET(c,TEXTSPLIT(b,"|"),
d,COUNTA(c),
VSTACK(a,TEXTJOIN("|",1,INDEX(c,,SEQUENCE(,d,d,-1)))))))),
LAMBDA(a,b,
LET(c,TEXTSPLIT(b,"|"),
d,COUNTA(c),
IFERROR(
VSTACK(a,
IF(SEQUENCE(,d)=d,INDEX(c,,d),"")),
"")))),
2)
It takes all unique values from the table (Table3 in my example) and iterates from looking up the value in the child column Col 2
and return it's parent Col 1
and look that result up until it can't find any parent to the value.
This results in a chain from child up to the master parent. To be able to sort the results in a proper manner, this result needs reversed (master parent to latest child) and sort this. Than only show the last value per row.
I hope it helps.
答案2
得分: 2
只返回翻译好的部分:
首先,在您的表格中添加一行附加行,以使Col 1中的每个条目都出现在Col 2中。实际上,这意味着确保即使在层次结构的最顶部的人仍然出现为一个'child',也就是说,他们是他们自己的'经理',如果您喜欢的话。在您的示例中,这将涉及在Col 1和Col 2中都有"a"的附加行。
然后将您的表格添加到数据模型
并打开Power Pivot
。在Power Pivot中创建一个名为Hierarchy的新计算列
,其公式如下:
=PATH(Table1[Col 2],Table1[Col 1])
(假设您添加到数据模型的表格名为Table1)。
然后返回工作表并在某个地方输入以下公式:
=LET( ζ, "ThisWorkbookDataModel", ξ, "[Table1].[Hierarchy].Children", ω, CUBESET(ζ, ξ), φ, CUBERANKEDMEMBER(ζ, ω, SEQUENCE(CUBESETCOUNT(ω))), λ, MAKEARRAY( ROWS(φ), MAX(MAP(φ, LAMBDA(κ, ROWS(TEXTSPLIT(κ, , "|"))))), LAMBDA(α, β, IFERROR(INDEX(TEXTSPLIT(INDEX(φ, α, 1), , "|"), β), "")) ), MAKEARRAY( ROWS(λ), COLUMNS(λ), LAMBDA(δ, ε, LET(μ, INDEX(λ, δ, ε), IF(δ = XMATCH(μ, INDEX(λ, , ε)), μ, ""))) ) )
要查看对Table1所做的任何更改的结果,您需要转到数据/全部刷新
。
英文:
First, add an additional row to your table such that each entry in Col 1 appears in Col 2. Effectively, this means ensuring that even the person at the very top of the hierarchy nevertheless appears as a 'child', i.e., they are their 'own manager', if you like. In your example, this would entail an additional row with "a" in both Col 1 and Col 2.
Then add your table to the Data Model
and open Power Pivot
. Create a new Calculated Column
within Power Pivot, called Hierarchy, with the following formula:
=PATH(Table1[Col 2],Table1[Col 1])
(which assumes that the table you added to the Data Model is named Table1).
You can then return to the worksheet and enter this formula somewhere:
=LET(
ζ, "ThisWorkbookDataModel",
ξ, "[Table1].[Hierarchy].Children",
ω, CUBESET(ζ, ξ),
φ, CUBERANKEDMEMBER(ζ, ω, SEQUENCE(CUBESETCOUNT(ω))),
λ, MAKEARRAY(
ROWS(φ),
MAX(MAP(φ, LAMBDA(κ, ROWS(TEXTSPLIT(κ, , "|"))))),
LAMBDA(α, β, IFERROR(INDEX(TEXTSPLIT(INDEX(φ, α, 1), , "|"), β), ""))
),
MAKEARRAY(
ROWS(λ),
COLUMNS(λ),
LAMBDA(δ, ε, LET(μ, INDEX(λ, δ, ε), IF(δ = XMATCH(μ, INDEX(λ, , ε)), μ, "")))
)
)
To see the results of any changes you make to Table1, you will need to go to Data/Refresh All
.
答案3
得分: 0
以下是翻译好的部分:
"It seemed intuitive to me that there should be a fairly short recursive solution to this but it has taken me a while to puzzle it out. Here is the resulting function:
BOMM(Parent,level,Range1,Range2)
=IF(
COUNTIF(Range1, Parent) = 0,
hReplace({"", "", "", ""}, Level, Parent),
REDUCE(
hReplace({"", "", "", ""}, Level, Parent),
FILTER(Range2, Range1 = Parent),
LAMBDA(a, c, VSTACK(a, BOMM(c, Level + 1, Range1, Range2)))
)
)"
"Uses a helper function
hReplace(array,pos,with)
=LET(seq, SEQUENCE(1, COLUMNS(array)), IF(seq = pos, with, array))"
英文:
It seemed intuitive to me that there should be a fairly short recursive solution to this but it has taken me a while to puzzle it out. Here is the resulting function:
BOMM(Parent,level,Range1,Range2)
=IF(
COUNTIF(Range1, Parent) = 0,
hReplace({"", "", "", ""}, Level, Parent),
REDUCE(
hReplace({"", "", "", ""}, Level, Parent),
FILTER(Range2, Range1 = Parent),
LAMBDA(a, c, VSTACK(a, BOMM(c, Level + 1, Range1, Range2)))
)
)
Uses a helper function
hReplace(array,pos,with)
=LET(seq, SEQUENCE(1, COLUMNS(array)), IF(seq = pos, with, array))
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论