The BOM Procedure

Getting Started: BOM Procedure

(View the complete code for this example.)

The ABC Lamp Company product line example from Fogarty, Blackstone, and Hoffmann (1991) illustrates the basic features of PROC BOM. The Part Master data set, PMaster0, displayed in Figure 1, contains the part master records for all items in the company. Each master record contains the part number (denoted by the Part variable) and the part description (denoted by the Desc variable) for an item. It also contains data on unit of measure (denoted by the Unit variable) for the item. The Product Structure data set, ParComp0, displayed in Figure 2, contains all product structure records in the company. Each product structure defines a parent-component relationship. The Parent variable contains the part number for the parent item and the Component variable contains the part number for the component. The QtyPer variable contains the quantity per assembly for the parent-component relationship.

The values for the Parent and Component variables are linked by the value of the Part variable in the Part Master data set to define the parent-component relationship. For example, in the 11th observation of the data set ParComp0 (as displayed in Figure 2), the value '1100' for the Parent variable is linked to the first observation of the data set PMaster0 (as displayed in Figure 1), which provides the part description and unit of measure for the parent item. Similarly, the value of '2100' for the Component variable is linked to the eighth observation of the part master file providing the master data for the component. Therefore, the parent-component relationship that is represented in the 11th observation of the product structure data set, ParComp0, should be interpreted as: each finished shaft uses 26 inches of 3/8 steel tubing.

Figure 1: Part Master File (PMaster0)

ABC Lamp Company
 
Part Master Data Set

ObsPartDescUnit
11100Finished shaftEach
212006-Diameter steel plateEach
31300HubEach
414001/4-20 ScrewEach
51500Steel holderEach
61600One-way socketEach
71700Wiring assemblyEach
821003/8 Steel tubingInches
9220016-Gauge lamp cordFeet
102300Standard plug terminalEach
11A100Socket assemblyEach
12B100Base assemblyEach
13LA01Lamp LAEach
14S100Black shadeEach


Figure 2: Product Structure File (ParComp0)

ABC Lamp Company
 
Product Structure Data Set

ObsParentComponentQtyPer
1LA01B1001
2LA01S1001
3LA01A1001
4B10011001
5B10012001
6B10013001
7B10014004
8A10015001
9A10016001
10A10017001
111100210026
12150014002
131700220012
14170023001


The following code invokes PROC BOM to produce the indented bill of material for the product 'LA01' and the summarized parts list for the production plan in which 1 unit of 'LA01' is planned in the current planning period (period 1).

  /* Create the indented BOM and summarized parts list */
proc bom data=ParComp0 pmdata=PMaster0
         out=IndBOM0 summaryout=SumBOM0;
   structure / part=Part
               parent=Parent
               component=Component
               quantity=QtyPer
               id=(Desc Unit);
run;

The Indented BOM data set, IndBOM0, is displayed in Figure 3. This data set contains the indented bill of material for the product 'LA01'. Each record or observation in this data set contains product structure data: the part number for the parent item is contained in the _Parent_ variable, the part number for the component is contained in the _Part_ variable, and the quantity per assembly is contained in the QtyPer variable. It also contains the part master data (Desc and Unit variables) from the Part Master data set for the component identified by the _Part_ variable. If a component is used in more than one parent item, it appears in multiple records. For example, the item 1/4-20 Screw (part number '1400') is used in both Base assembly (part number 'B100') and Steel holder (part number '1500'); this item occurs in records identified by the values 6 and 10 for the variable Part_ID.

Figure 3: Indented Bill of Material (IndBOM0)

ABC Lamp Company
 
Indented Bill of Material, Part LA01

_Level__Parent__Part_DescQtyPerQty_ProdUnitParen_IDPart_ID_Prod_
0 LA01Lamp LA.1Each.0LA01
1LA01B100Base assembly11Each01LA01
2B1001100Finished shaft11Each12LA01
3110021003/8 Steel tubing2626Inches23LA01
2B10012006-Diameter steel plate11Each14LA01
2B1001300Hub11Each15LA01
2B10014001/4-20 Screw44Each16LA01
1LA01S100Black shade11Each07LA01
1LA01A100Socket assembly11Each08LA01
2A1001500Steel holder11Each89LA01
3150014001/4-20 Screw22Each910LA01
2A1001600One-way socket11Each811LA01
2A1001700Wiring assembly11Each812LA01
31700220016-Gauge lamp cord1212Feet1213LA01
317002300Standard plug terminal11Each1214LA01


As discussed in the section Overview: BOM Procedure, each indented bill of material can be illustrated by a family tree. In fact, each record in the Indented BOM data set corresponds to a node in this tree. Figure 4 displays the tree diagram for the indented bill of material in the IndBOM0 data set. Each tree node or record is uniquely identified by a sequence or ID number that is assigned to it by the procedure. The Part_ID variable contains this ID number for each record. The Paren_ID variable contains the sequence number for the parent node or parent record. A parent record for a given record is the record that defines the parent node of the node defined by the given record. For example, the parent record of record 6 in the data set IndBOM0 is record 1, while record 9 is the parent record of record 10. Record 0 has no parent record.

Figure 4: Tree Diagram for the Bill of Material for LA01

Tree Diagram for the Bill of Material for LA01


The IndBOM0 data set contains other data: The _Level_ variable denotes the indenture level number for each node or record. The root node with the sequence number 0 is at level 0, and the level numbers increase as you look down the tree. The _Prod_ variable contains the part number of the end item. The Qty_Prod variable contains the quantity per product, that is, the quantity of the component identified by the _Part_ variable required to make one unit of the end item 'LA01'. Note that in this particular example, the values of the Qty_Prod variable are identical to the values of the QtyPer variable. This is because the quantities per assembly for all the parent-component relationships are 1, except for relationships 'B100'-'1400', '1100'-'2100', '1500'-'1400', '1700'-'2200'. The components ('1400', '2100', and '2200') of these parent-component relationships do not have any subcomponents themselves.

Figure 3, as well as Figure 4, shows that the Indented BOM data set lists all the records in depth-first order. This scheme lists tree nodes from top to bottom and from left to right. For example, item '1100' is listed directly after its parent, 'B100', and before items 'S100' and 'A100' (the right siblings of item 'B100'). Similarly, item '2100' is listed directly after item '1100' and before items '1200', '1300', and '1400'. Refer to Aho, Hopcroft, and Ullman (1983) for details about depth-first ordering. See the section Indented BOM Data Set for details regarding the records in this data set.

Figure 5: Summarized Parts List (SumBOM0)

ABC Lamp Company
 
Summarized Parts List, Period 1

_Part_Low_CodeGros_ReqOn_HandNet_ReqDescUnit
11002101Finished shaftEach
120021016-Diameter steel plateEach
13002101HubEach
140036061/4-20 ScrewEach
15002101Steel holderEach
16002101One-way socketEach
17002101Wiring assemblyEach
21003260263/8 Steel tubingInches
220031201216-Gauge lamp cordFeet
23003101Standard plug terminalEach
A1001101Socket assemblyEach
B1001101Base assemblyEach
LA010101Lamp LAEach
S1001101Black shadeEach


The Summarized Parts data set, SumBOM0, is displayed in Figure 5. This data set, which has been sorted by the _Part_ variable, has a record for each item in the ABC Lamp Company’s product line. Each record contains the part master data from the Part Master data set, PMaster0. The _Part_, Desc, and Unit variables contain the part number, part description, and unit of measure, respectively, for each item. It also contains some other data: The Low_Code variable denotes the low-level code of the item. The low-level code for an item is a number that indicates the lowest level in any bill of material at which this item appears. For example, item '1400' appears at levels 2 and 3 in this example; thus, its low-level code is 3. The low-level codes are necessary to make sure that the net requirement for a given item is not calculated until all the gross requirements have been calculated down to that level. The On_Hand variable contains the quantity of the item currently on hand. Since the part master file (as shown in Figure 1) does not contain any quantity on hand information, the procedure assumes that this variable is 0 for all items. The Gros_Req and Net_Req variables contain the gross and net requirements, respectively. Again, since the PMaster0 data set does not provide any production plan information, PROC BOM assumes that the final product, 'LA01', is the only master schedule item and the gross requirement for this item is 1 unit. The net requirement for item 'LA01' is the gross requirement (1) minus the quantity on hand (0). The gross and net requirements of the other items are then calculated sequentially:

'B100' Base assembly (1 per lamp)
Gross requirement
(= net requirement of 'LA01' times quantity per assembly) 1 times 1 equals 1
Quantity on hand    negative 0
Net requirement 1
'1100' Finished shaft (1 per base assembly)
Gross requirement
(= net requirement of 'B100' times quantity per assembly) 1 times 1 equals 1
Quantity on hand    negative 0
Net requirement 1
'2100' 3/8 Steel tubing (26 inches per shaft)
Gross requirement
(= net requirement of '1100' times quantity per assembly) 1 times 26 equals 26
Quantity on hand    negative 0
Net requirement 26


If an item (such as item '1400' in this example) is used in more than one assembly, the gross requirement is the total needed in all assemblies where it is used. See the section Summarized Parts Data Set for details about determining the gross and net requirements.

Recall that the Part Master data set (as shown in Figure 1) does not contain any quantity on hand and requirement information, and item 'LA01' is the only final product. Thus, in this example, the summarized parts list (as displayed in Figure 5) is actually the same as the summarized bill of material for item 'LA01', with the gross (or net) requirement representing the total usage of each item.

Last updated: August 24, 2020