Chapter Contents
Chapter Contents
Previous
Previous
Next
Next
The BOM Procedure

Getting Started

The example of the ABC Lamp Company product structure example from Fogarty, Blackstone, and Hoffmann (1991) illustrates the basic features of PROC BOM. The single-level bill of material data are depicted in Figure 1.1. These consist of a list of each part in the product structure, the components that are directly used in the part, and the quantity of each component needed to make one unit of that particular part. The data set also includes a short description and the unit of measure for each part. The SAS DATA step code to create and display the single-level BOM data set is as follows:

      /* single-level BOM data   */
   data SlBOM0;
      input Part      $8.
            Desc      $24.
            Unit      $8.
            Component $8.
            QtyPer    8.0
            ;
   datalines;
   LA01    Lamp LA                 Each    B100           1
                                           S100           1
                                           A100           1
   B100    Base assembly           Each    1100           1
                                           1200           1
                                           1300           1
                                           1400           4
   S100    Black shade             Each                   .
   A100    Socket assembly         Each    1500           1
                                           1600           1
                                           1700           1
   1100    Finished shaft          Each    2100          26
   1200    7-Diameter steel plate  Each                   .
   1300    Hub                     Each                   .
   1400    1/4-20 Screw            Each                   .
   1500    Steel holder            Each    1400           2
   1600    One-way socket          Each                   .
   1700    Wiring assembly         Each    2200          12
                                           2300           1
   2100    3/8 Steel tubing        Inches                 .
   2200    16-Gauge lamp cord      Feet                   .
   2300    Standard plug terminal  Each                   .
   ;

     /* Display the input data set */
   proc print data=SlBOM0 noobs;
      title 'ABC Lamp Company';
      title3 'Single-Level Bill of Material';
   run;

 
ABC Lamp Company
Single-Level Bill of Material

Part Desc Unit Component QtyPer
LA01 Lamp LA Each B100 1
      S100 1
      A100 1
B100 Base assembly Each 1100 1
      1200 1
      1300 1
      1400 4
S100 Black shade Each   .
A100 Socket assembly Each 1500 1
      1600 1
      1700 1
1100 Finished shaft Each 2100 26
1200 7-Diameter steel plate Each   .
1300 Hub Each   .
1400 1/4-20 Screw Each   .
1500 Steel holder Each 1400 2
1600 One-way socket Each   .
1700 Wiring assembly Each 2200 12
      2300 1
2100 3/8 Steel tubing Inches   .
2200 16-Gauge lamp cord Feet   .
2300 Standard plug terminal Each   .
Figure 1.1: Single-Level Bill of Material

The following code invokes PROC BOM to produce the indented bill of material and the summarized bill of material. It also uses PROC NETDRAW to draw a family tree diagram for illustrating the multilevel product structure. For further details about PROC NETDRAW, refer to "The NETDRAW Procedure" chapter in the SAS/OR User's Guide: Project Management, Version 8.

     /* Create the indented BOM and the summarized BOM */
   proc bom data=SlBOM0 out=IndBOM0 summaryout=SumBOM0; 
      structure / part=Part 
                  component=Component
                  quantity=QtyPer
                  id=(Desc Unit); 
   run;

     /* Draw a tree diagram for illustrating the product structure */
     /* Each record denotes a node in the tree */
   data IndBOM0a(drop=Part_ID);
      set IndBOM0;
      Paren_ID=Part_ID;
   run;

     /* Extract the Parent - Part information */
   data IndBOM0b;
      set IndBOM0(keep=Paren_ID Part_ID);
   run;

     /* Prepare the data set for running NETDRAW */
   data TreBOM0;
      set IndBOM0a IndBOM0b;
   run;

     /* Specify graphics options */
   goptions hpos=32 vpos=80 border;
   pattern1 v=s c=blue;

   title h=5 j=c 'Multilevel Bill of Material';
   footnote h=2 j=l 
      'Node shows ID Number, Part Number, and Quantity Required';

     /* Invoke PROC NETDRAW to display BOM tree */
   proc netdraw data=TreBOM0( where=(Paren_ID NE .) ); 
      actnet / act=Paren_ID succ=Part_ID id=(Paren_ID _Part_ QtyPer)
               ctext=white font=swiss htext=3 carcs=black
               ybetween=3 xbetween=8 centerid
               tree pcompress rotatetext rotate 
               arrowhead=0 rectilinear nodefid nolabel;
   run;

bomgsgg.gif (4797 bytes)

Figure 1.2: Multilevel Product Structure

Figure 1.2 displays the tree structure of the ABC Lamp Company. Corresponding to this tree diagram is the list of indented bill of material for the company as in Figure 1.3. The following code displays the indented BOM:

      /* Display the indented BOM data */
   proc print data=IndBOM0 noobs;
      var _Level_ _Part_ Part_ID Desc QtyPer Qty_Prod 
          Unit _Parent_ Paren_ID _Prod_;
      title 'ABC Lamp Company';
      title3 'Indented Bill of Material, Part LA01';
   run;

 
ABC Lamp Company
Indented Bill of Material, Part LA01

_Level_ _Part_ Part_ID Desc QtyPer Qty_Prod Unit _Parent_ Paren_ID _Prod_
0 LA01 0 Lamp LA . 1 Each   . LA01
1 A100 1 Socket assembly 1 1 Each LA01 0 LA01
2 1700 2 Wiring assembly 1 1 Each A100 1 LA01
3 2300 3 Standard plug terminal 1 1 Each 1700 2 LA01
3 2200 4 16-Gauge lamp cord 12 12 Feet 1700 2 LA01
2 1600 5 One-way socket 1 1 Each A100 1 LA01
2 1500 6 Steel holder 1 1 Each A100 1 LA01
3 1400 7 1/4-20 Screw 2 2 Each 1500 6 LA01
1 S100 8 Black shade 1 1 Each LA01 0 LA01
1 B100 9 Base assembly 1 1 Each LA01 0 LA01
2 1400 10 1/4-20 Screw 4 4 Each B100 9 LA01
2 1300 11 Hub 1 1 Each B100 9 LA01
2 1200 12 7-Diameter steel plate 1 1 Each B100 9 LA01
2 1100 13 Finished shaft 1 1 Each B100 9 LA01
3 2100 14 3/8 Steel tubing 26 26 Inches 1100 13 LA01
Figure 1.3: Indented Bill of Material

Each record in the indented BOM data set is associated with a node in the tree structure, and the node or record is uniquely identified by a sequence number that is assigned to it by the procedure. The Part_ID variable denotes this sequence number of the node or record. The Part_ID information is needed in case some items are required at more than one place in the BOM. For example, the item `1400' (1/4-20 Screw) is required at `B100' (Base assembly) and `1500' (Steel holder). In this situation the part number is not sufficient to identify each node in the tree structure. Thus, the two different nodes are uniquely identified by the values `7' and `10' for the variable Part_ID.

The _Level_ variable denotes the level number of each node. The final product, `LA01', is at level 0, and the level numbers increase as you look down the tree. The Part, QtyPer, and ID variables (Desc and Unit) in the single-level BOM data set, SlBOM0, are also included in the indented BOM data set. Note that the name of the Part variable is changed to _Part_ in the indented BOM data set. There are two variables in the indented BOM data set identifying parent information: the _Parent_ variable denotes the part number for the parent item (next assembly) of the part identified by the _Part_ variable, while the Paren_ID variable specifies the sequence number for the parent node of the current node (record) identified by the Part_ID variable. For example, the indented BOM data set, as shown in Figure 1.3, reveals that the part `1400' has two parent items: part `1500' and part `B100'. Meanwhile, the parent node of node `7' is node `6', and the parent node of node `10' is node `9'.

Finally, the _Prod_ variable denotes the part number of the final product in the production structure. The Qty_Prod variable contains the required quantity of the item identified by the _Part_ variable in order to make one unit of the final product identified by the _Prod_ variable. 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 values of the QtyPer variable for all parent items are 1.

Figure 1.2 and Figure 1.3 show that the Indented BOM data set lists all of the parts of the tree structure in depth-first order (Aho, Hopcroft, and Ullman 1983). Unlike the Single-level BOM data set, the Indented BOM data set provides the "part-parent" information rather than the "part-component" relationship. The part-component information can still be easily retrieved. For example, the following code creates a list of components that are directly used in the part `LA01':

     /* Display the components that are directly used */
     /* in item LA01                                  */
   proc print data=IndBOM0(where=(_Parent_='LA01')
                           rename=(_Part_=Component))
              noobs;
      var Component Desc QtyPer Unit _Prod_;
      title 'ABC Lamp Company';
      title3 'Single-Level Bill of Material Retrieval, Part LA01';
   run;

 
ABC Lamp Company
Single-Level Bill of Material Retrieval, Part LA01

Component Desc QtyPer Unit _Prod_
A100 Socket assembly 1 Each LA01
S100 Black shade 1 Each LA01
B100 Base assembly 1 Each LA01
Figure 1.4: Components That Are Directly Used in Part LA01

You can also create single-level where-used reports from the Indented BOM data set. For example, the single-level where-used data set Used0b, displayed in Figure 1.5, lists all parent items that directly use the part `1400'. The SAS code that creates the data set Used0b from the Indented BOM data set IndBOM0 is as follows:

     /* Create the where-used data set */
   data Used0a(keep=_Parent_ Paren_ID QtyPer Unit _Prod_);
      set IndBOM0(where=(_Part_='1400'));
   run;

     /* Get the part description from the IndBOM0 data set */
   proc sql;
      create table Used0b as
         select Used0a._Parent_, IndBOM0.Desc, 
                Used0a.QtyPer, Used0a.Unit, Used0a._Prod_
            from Used0a left join IndBOM0
               on Used0a.Paren_ID=IndBOM0.Part_ID;
   quit;

     /* Display the where-used data set */
   proc print data=Used0b noobs;
      var _Parent_ Desc QtyPer Unit _Prod_;
      title 'ABC Lamp Company';
      title3 'Single-Level Where-used Report, Part 1400';
   run;

 
ABC Lamp Company
Single-Level Where-used Report, Part 1400

_Parent_ Desc QtyPer Unit _Prod_
1500 Steel holder 2 Each LA01
B100 Base assembly 4 Each LA01
Figure 1.5: Parents in Which the Part 1400 Is Directly Used

The following SAS code sorts and displays the Summarized BOM data set that is produced by the BOM procedure:

      /* Sort and display the summarized BOM data */
   proc sort data=SumBOM0;
      by _Part_;
   run;

   proc print data=SumBOM0 noobs; 
      title 'ABC Lamp Company';
      title3 'Summarized Bill of Material, Part LA01';
   run;

 
ABC Lamp Company
Summarized Bill of Material, Part LA01

_Part_ Low_Code Gros_Req On_Hand Net_Req Desc Unit
1100 2 1 0 1 Finished shaft Each
1200 2 1 0 1 7-Diameter steel plate Each
1300 2 1 0 1 Hub Each
1400 3 6 0 6 1/4-20 Screw Each
1500 2 1 0 1 Steel holder Each
1600 2 1 0 1 One-way socket Each
1700 2 1 0 1 Wiring assembly Each
2100 3 26 0 26 3/8 Steel tubing Inches
2200 3 12 0 12 16-Gauge lamp cord Feet
2300 3 1 0 1 Standard plug terminal Each
A100 1 1 0 1 Socket assembly Each
B100 1 1 0 1 Base assembly Each
LA01 0 1 0 1 Lamp LA Each
S100 1 1 0 1 Black shade Each
Figure 1.6: Summarized Bill of Material

The Summarized BOM data set, as displayed in Figure 1.6, lists all the parts and their quantity required in the given ABC Lamp Company product structure. Since the Single-level BOM data set, SlBOM0, does not contain any gross requirement information, PROC BOM assumes that the final product, `LA01', is the only master schedule item. The master schedule items (MSI) are items selected to be planned by the master scheduler. These items are deemed critical in their impact on lower-level components or resources. Therefore, the master scheduler, not the computer, maintains the plan for these items. The BOM procedure also assumes that the gross requirement of `LA01' is 1 unit and that there are no items currently on hand. The net requirement of the part `LA01' is the gross requirement (1) minus the quantity on hand (0). The gross requirements of the other items are then calculated sequentially, level by level, as follows:

`B100' Base assembly (1 per lamp) 
Gross requirement1 ×1 = 1
Quantity on hand- 0
Net requirement1
`1100' Finished shaft (1 per base assembly) 
Gross requirement1 ×1 = 1
Quantity on hand- 0
Net requirement1
`2100' 3/8 Steel tubing (26 inches per shaft) 
Gross requirement1 ×26 = 26
Quantity on hand- 0
Net requirement26

If a part (like item `1400') is required at more than one assembly, the gross requirement is the total needed in all assemblies where it is required.

The Net_Req variable denotes the net requirement, and the Low_Code variable denotes the low-level code of the part. The low-level code is a number that indicates the lowest level in any bill of material at which the item appears. 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.

Chapter Contents
Chapter Contents
Previous
Previous
Next
Next
Top
Top

Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.