Flatten Parent Child Hierarchy in Excel (using formula or VBA)

huangapple go评论69阅读模式
英文:

Flatten Parent Child Hierarchy in Excel (using formula or VBA)

问题

我想在Excel中展平父子层次结构。例如:

如果我的原始数据是蓝色的,我想要更改的目标是橙色区域。
我如何使用VBA或Excel公式来解决这个问题?

提前感谢!

英文:

I want to flatten Parent Child Hierarchy in Excel. For example:

Flatten Parent Child Hierarchy in Excel (using formula or VBA)

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)

Flatten Parent Child Hierarchy in Excel (using formula or VBA)

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 1Col 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)))
    )
)

Flatten Parent Child Hierarchy in Excel (using formula or VBA)

Uses a helper function

hReplace(array,pos,with)

=LET(seq, SEQUENCE(1, COLUMNS(array)), IF(seq = pos, with, array))

huangapple
  • 本文由 发表于 2023年7月6日 17:25:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76627369.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定