Excel VBA – How to Use While Loop with Variable Loops in Excel Formulas

excelexcel-formulavba

Good evening all,

I have a table in columns "A" and "B". It is known as a BOM (Bill of Material) and column "A" is the parent of column "B" the child. Some Codes have a child which may also have a child etc etc BUT they do not always have the same amount of levels. In my example table A001 has two children of "A005" and "A006", each then has their own MCode child. However, A002 does not have any child ACode and only has the child "M002".

enter image description here

I have tried various loops to convert the table in columns "A" and "B" into the table in columns "D" to "G" but the dynamic levels the children goto means I just cant get it to work. Some investigation suggests a recursive function but am unable to implement despite various attempts.

Any support appreciated (not worried about the formatting in columns "D" to "G" but have put it in to aid understanding). If you have any questions to aid understanding of my request then I am happy to answer any of them.

Many thanks, Alan.

Best Answer

Thanks for the fun challenge (love recursion :)

Recursion in Excel has some limitations, but this might work for your needs.

Please define a named formula (all_my_children) in Name Manager (we need to use it for recursive formulas) in the example I have created a table for the data named Tree.

all_my_children=

=LAMBDA(p, DROP(REDUCE("r", p, LAMBDA(acc,cur, LET(c, FILTER(Tree[Child], Tree[Parent] = cur), VSTACK(acc, IF(AND(ISERROR(c)), cur, HSTACK(cur, VSTACK(all_my_children(c)))))))), 1))
=LAMBDA(p,
    DROP(
        REDUCE(
            "r",
            p,
            LAMBDA(acc, cur,
                LET(
                    c, FILTER(Tree[Child], Tree[Parent] = cur),
                    VSTACK(
                        acc,
                        IF(AND(ISERROR(c)), cur, HSTACK(cur, VSTACK(all_my_children(c))))
                    )
                )
            )
        ),
        1
    )
)

And then to get the result, (entered in E1 in the example):

=LET(
    first_level, UNIQUE(
        FILTER(Tree[Parent], MAP(Tree[Parent], LAMBDA(a_, AND(a_ <> Tree[Child]))))
    ),
    result, IFNA(all_my_children(first_level), ""),
    VSTACK("Level " & SEQUENCE(, COLUMNS(result)), result)
)

Please let know know if any explanation is needed. Formula and result