Do not input private or sensitive data. View Qlik Privacy & Cookie Policy.
Skip to main content

Announcements
Save $650 on Qlik Connect, Dec 1 - 7, our lowest price of the year. Register with code CYBERWEEK: Register
hic
Former Employee
Former Employee

Most hierarchies are dimensional hierarchies. This implies several things: First, you have a many-to-one relationship between the levels: a day belongs to one (and only one) month, a month to one (and only one) quarter, etc. Strictly speaking, it is not a hierarchy unless this condition is fulfilled.

 

Secondly, the hierarchy contains no measures. Instead, numbers are stored in a transactional table that is linked to the dimensional hierarchy.

 

But there is another hierarchy-like structure, the Bill of Materials, the “BoM”. This is a list of items, assemblies and sub-assemblies representing the design of a product or device. Many products are planned and documented with BoMs.

 

A multi-level BoM depicts parent-child relationships and shows the hierarchical structure of the assemblies and their related subcomponents. A multi-level BoM is essentially a nested list whose items are listed to illustrate multiple assemblies within a product.

 

BoM input.png

 

But a BoM is very different from a dimensional hierarchy. It does not have to have a strict many-to-one relationship between the levels. For instance, a specific bearing type can be used in several places. For the BoM, this means that the bearing can have several parents in the hierarchy.

 

Further, each line in the BoM has numbers in it, typically Quantity and Cost. These are measures that should be summed. In a sense, a BoM is more similar to a transaction table than a dimensional table.

 

A BoM can easily be loaded and analyzed with Qlik Sense or QlikView, but there are some challenges: First, the list often lacks a parent reference. Instead, the parent-child relationship is implied by the order of the rows and the Level field, and visualized by indentations.

 

Secondly, aggregating the measures is not straightforward. When summing the costs, the multiplicities of all the nodes above it must be taken into account. In the example in the above table, the wheel assembly uses 2 bearings, and the trailer uses 4 wheel assemblies. Then the trailer obviously needs 8 bearings. In other words: The row for the wheel assembly – and all rows belonging to it – must be looped 4 times when summing the cost.

 

Luckily, both these challenges can be handled in the Qlik script. One possible solution is the following:

 

   Hierarchy ( [Part No], Parent, Description )

   Load *,

       Subfield( Path, '/', Level ) as Parent;

   Load *,

       Left( Peek( Path ), Index( Peek( Path ) & '/', '/', Level ) -1 ) & '/' & [Part No] as Path

       While IterNo() <= Units;

   Load *,

       If( Frac( Quantity)=0, Quantity, 1 ) as Units,

       If( Frac( Quantity)=0, 1, Quantity ) as Amount

       From BoM ;

 

The reference to the parent is created in two steps: First a Path is built using the Level and the Path of the above row. Having the path, it is straightforward to extract the parent id using Subfield().

 

Further, each row is loaded several times using a while loop. Hence, row 16 (the ball bearings) is loaded twice since its Quantity is 2. But it should be loaded 8 times since the Quantity of its parent (row 6, Wheel assembly) is 4. This multiplication is achieved using the Hierarchy prefix.

 

Finally, the above multiplication algorithm only works for integer quantities. For this reason the bottom Load splits the Quantity into two fields: a field Units that is used in the While loop, and an Amount that is used in the aggregation:

 

   Sum( Amount * UnitCost )

 

However, this means that nodes that have non-integer quantities cannot have any children. If they do, the above algorithm cannot be used, and the cost roll-up must be made a different way. Luckily, this is rarely or never the case in real life.

 

Good luck with your Bill of Materials!

 

HIC

 

Further reading related to this topic:

Unbalanced, n-level hierarchies

23 Comments
Anders_Eriksson
Partner - Specialist
Partner - Specialist

The script I'm using looks very similar to yours only I keep the original materials table intact for the joining throughout the loop.

Also in the loop I add a temporary field in the join that I can count. That way I can keep track of how many joins actually occurred during last loop and keep on looping until there were no more joins.

(I do have a maximum also just in case there is some circular reference)

My original table does not contain any level field, I only have a parent-child relation table with quantities and a separate materials table.

Hierarchy I don't use.

4,019 Views
richardouellett
Creator
Creator

Henric

I got the following error after manually building example.  Below error image are the is the copy of the Excel data and the script I used.  Can you take a peek and advise?

BOoMError.jpg

Data that you can paste into Excel:

    

LineNoLevelQuantityItemPartNoUnitCost
111Trailer10420-1001
221Chassis10112-1001
331Woodenboard,15mm,2400X120010409-10011,5
431Paint10111-10091
534Labor10430-100010
624Wheel Assembly10410-1001
732Side Piece10410-1003
842Steel profile 180X810107-10012
941Surface coating10111-10010,5
1041Labor10430-100010
1131Top piece10410-1002
1241Steel profile 180X810107-10010,1
1341Surface coating10111-10010,5
1440,5Labor10430-100010
1541Wheel, 120mm10404-11085
1632Ball bearing10404-11102
1732Bolt, M10x70, Stainless10400-10010,2
1832Washer, M10, Stainless10400-10020,01
1932Nut, M10x30, Stainless10400-10030,05
2031Bolt, M10x30, Stainless10400-1004

0,05

Script:

Hierarchy ( PartNo, Parent, Description )   Load *,

       Subfield( Path, '/', Level ) as Parent;

   Load *,

       Left( Peek( Path ), Index( Peek( Path ) & '/', '/', Level ) -1 ) & '/' & PartNo as Path

       While IterNo() <= Units;

   Load *,

       If( Frac( Quantity)=0, Quantity, 1 ) as Units,

       If( Frac( Quantity)=0, 1, Quantity ) as Amount

FROM

[BoM.xlsx]

(ooxml, embedded labels, table is Sheet1);

0 Likes
4,019 Views
hic
Former Employee
Former Employee

The three first parameters of the Hierarchy prefix must be names of existing fields, and you don't have a field "Description". Try

      Hierarchy ( PartNo, Parent, Item ) ...

instead.

HIC

0 Likes
4,021 Views
richardouellett
Creator
Creator

Henric, that did the trick, thank you!

0 Likes
4,021 Views
asifmaula2015
Contributor
Contributor

Hi Henric ,

Thank you for the explanation above. It was really useful. However I have a requirement which is somewhat different. I don't have to show any measures, instead I have to display all the data in a tree-like structure.


I have to create a dashboard for BOM(Bills of Materials). Let me tell you what BOM is all about. There are some Materials which is having respective Components under it. These Components are further divided into Sub-Components which is under the same field i.e. Material. There is a flag known as Assembly Indicator which signifies if any Components is broken down into Sub-Components or not. The values of this flag are either 'X' or 'Null wherein 'X' tells us that the Components has child components(sub-components).

So my requirement is to publish these lines one after the other. Please see the example below:

MaterialComponentAssembly Indicator
Mat1Comp1X
Mat1Comp2
Mat1Comp3X

Mat2

Comp56

Mat3

Comp87
Mat7Comp6
Comp1SubComp1X
Comp1
SubComp2
SubComp1SubComp76
Comp3SubComp33

So it should look like below table:

Since Material 'Mat1' has Component 'Comp1' and has an Assembly Indicator flag as 'X' so it's component line should be published/displayed soon after this Material 'Mat1' details and so on. It should display all the sub components detail unless it finds a Null flag.

MaterialComponentAssembly Indicator
Mat1Comp1X
Mat1Comp2
Mat1Comp3X
Comp1SubComp1X
Comp3SubComp33

I hope I was able to explain. Eagerly awaiting your reply.

Thanks in advance.

Regards,

Asif

0 Likes
4,021 Views
adiarnon
Creator III
Creator III

the account dimention (hierarcy) looks like-

ACCOUNTACCOUNT parent

weight

X1X2

my fact table-

YEARMONTHACCOUNT parent

AMOUNT

201512X110

the amount of X (PARENT) should be 20 (10*2)

the weight-

the number i need to multiply the amount in the fact if I WANT TO GET THE VALUE OF THE PARENT

to built the account dimention im using the hierarchy and hierarchybelongto

how can i do this logic?

tnx, adi

0 Likes
4,021 Views
Not applicable

Hi Henric

I tried your both BOM scripts. Somehow the results are different or so I think.  I have chosen only labor Item for this mail as a sample.  I have difficulties to understand the results. Somehow I think I understand that Total Quantity is ok ( I calculated it in excel)  in the below table but how upper table equals the below one?

BOM.png

0 Likes
4,021 Views
Not applicable

Hi, How can I do if I no have Level?

My table is:

ID_Parent, ID_Child, Name_Child, Quantity

P0007       A0001       Product 1        1.2

P0007       P0209       Product 2         1

P0209       A0002       Product 3         2

P0209      P0038        Product 4         1

P0038       A0002       Product 5         1.9

0 Likes
4,021 Views
rayzac99
Partner - Contributor II
Partner - Contributor II

I have a similar scenario as well.  Any help would be appreciated. 

0 Likes
3,916 Views
Akbar
Contributor II
Contributor II

Hello Hic, 

Thank you for this blog, its very helpful in understanding the concept and the script. However, when I tried using this same data, I am not able to get the correct output for the unit cost (rolled up sum for Trailer). 

Also, in your script above, the Hierarchy Prefix shows 'Description', which is not in available in the source data. I am assuming that field is 'Item'. 

Could you please provide a solution to show the roll-up cost for Trailer, Chassis and Wheel Assembly

Attached is the image of my outputBom FrontendBom Frontend

Thank you in advance.

 

 

0 Likes
1,353 Views