Reputation: 21
In excel I have this table with 2 columns : Table called T_DATA
dataset | datasource |
---|---|
APP1 | DTM1 |
DTM1 | Dataset1 |
DTM1 | Dataset2 |
DTM1 | Dim1 |
DTM1 | Dim2 |
Dataset1 | Raw1 |
Dataset2 | Dataset3 |
Dataset2 | Raw5 |
Dataset3 | Raw2 |
Dim1 | Raw3 |
Dim1 | Raw4 |
Dim2 | Raw5 |
Dim2 | Raw4 |
APP2 | DTM2 |
DTM2 | Dataset4 |
DTM2 | Dim1 |
Dataset4 | Raw6 |
I want to flat the hierarchy based on a value the user populate in cell D1 for example
For example if in D1, I populate : dtm the result expected would be : (row 1) : dtm>fact>raw1 (row 2) : dtm>dim>raw2
if in A1 I populate : Dtm2 the result expected would be : (row 1) : dtm2>raw3
So in summary, each path found must be concatened (separated by a '>'), and there is 1 path by row.
I managed to do it and it works for the 1st path only, with the following recursive function/formula called GetPath:
=LAMBDA(start,LET(
nextItems,FILTER(T_DATA[datasource];T_DATA[dataset]=start);
IF(nextItem="";start;start&">"&GetPath(nextItem))
)
)
and by using it like this : GetPath(D1)
But I cannot figure out a way to get ALL paths based on the criteria searched in A1 I tried other options found on internet, but not satisfying, or even a #N/A result :(
I give a screenshot with excel data, it will be perhaps better to understand:
NB: A solution in Power Query, would be a good option too, but the same. I know power query, but I don't manage to create a valid recursive solution in Power Query, too complex for me.
Upvotes: 2
Views: 77
Reputation: 34355
This is a recursive function (FlatBomm2) based on a previous question :
=IF(
COUNTIF(Range1, Parent) = 0,
Parent,
DROP(
REDUCE(
"",
FILTER(Range2, Range1 = Parent),
LAMBDA(a, c,
IFNA(
VSTACK(
a,
IFNA(HSTACK(Parent, FlatBomm2(c, Level + 1, Range1, Range2)), Parent)
),
""
)
)
),
1
)
)
Called as
=FlatBomm2(A2,1,A2:A18,B2:B18)
Or more specific to OP's output (and level isn't needed):
=IF(
COUNTIF(Range1, Parent) = 0,
Parent,
DROP(
REDUCE(
"",
FILTER(Range2, Range1 = Parent),
LAMBDA(a, c, IFNA(VSTACK(a, Parent & ">" & Flatbomm3(c, Range1, Range2)), ""))
),
1
)
)
called as
=Flatbomm3(A2,A2:A18,B2:B18)
where Flatbomm3 is defined as a lambda with arguments
Parent - the parent value (Dataset)
Range1 - the list of parents (Datasets)
Range2 - the list of children (Datasources)
or you could bundle it into a let statement as
=LET(
Flatbomm4,LAMBDA(Me,Parent,Range1,Range2,
IF(
COUNTIF(Range1, Parent) = 0,
Parent,
DROP(
REDUCE(
"",
FILTER(Range2, Range1 = Parent),
LAMBDA(a,c, IFNA(VSTACK(a, Parent & ">" & Me(Me,c, Range1, Range2)), ""))
),
1
)
)),
Flatbomm4(Flatbomm4,A2,A2:A18,B2:B18))
Output
Output |
---|
APP1>DTM1>Dataset1>Raw1 |
APP1>DTM1>Dataset2>Dataset3>Raw2 |
APP1>DTM1>Dataset2>Raw5 |
APP1>DTM1>Dim1>Raw3 |
APP1>DTM1>Dim1>Raw4 |
APP1>DTM1>Dim1>Raw3 |
APP1>DTM1>Dim1>Raw4 |
APP2>DTM2>Dataset4>Raw6 |
APP2>DTM2>Dim1>Raw3 |
APP2>DTM2>Dim1>Raw4 |
Dataset2>Dataset3>Raw2 |
Dataset2>Raw5 |
Upvotes: 3
Reputation: 11628
=LET(data,A4:B20,
F,LAMBDA(z,FILTER(">"&DROP(data,,1),TAKE(data,,1)=z,"")),
REDUCE("Dataset2",TAKE(data,,1),
LAMBDA(a,b,
DROP(REDUCE("",a,
LAMBDA(x,y,
VSTACK(x,
y&F(TEXTAFTER(y,">",-1,,,y))))),1))))
This starts with declaring data
being the two columns you have.
Next we create a function F
to filter column 2 if column 1 meets a certain conditions z
which will be the input of the function.
Next we use a double REDUCE to add the values matching the previous result ending value
Upvotes: 3