Chapter Contents
Chapter Contents
Previous
Previous
Next
Next
The CPM Procedure

Example 2.1: Use of the SETFINISHMILESTONE Option

A simple activity network is used to illustrate the use of the SETFINISHMILESTONE option in a couple of different scenarios.

The following DATA step reads the project network in AON format into a SAS data set named tasks. The data set (printed in Output 2.1.1) contains an Activity variable (act), a Successor variable (succ), a Lag variable (lag), and a Duration variable (dur). Note that there are several milestones linked to other activities through different types of precedence constraints. The data set also contains some alignment constraints as specified by the variables target and trgttype. Note that the treatment of the milestones will vary depending on the presence or absence of the alignment constraints. The data set also contains two variables that indicate the expected early schedule dates for the milestones corresponding to two different invocations of PROC CPM: the variable notrgtmd corresponds to the non-aligned schedule and the variable miledate corresponds to an invocation with the ALIGNDATE statement.

   data tasks;
      input act $ 1-7 succ $ 9-15 lag $ dur target date9. 
            trgttype $ miledate date9. notrgtmd date9.; 
      format target date7. miledate date7. notrgtmd date7.;
   datalines;
   Task 0  Mile 1  ss_0 1 24Jan00  SGE .        .
   Mile 1  Task 2  .    0  .       .   24Jan00  24Jan00
   Task 2  .       .    1  .       .   .        .
   Task 3  Mile 4  .    1  .       .   .        .
   Mile 4  .       .    0  .       .   24Jan00  24Jan00
   Task 5  Mile 6  .    1  .       .   .        .
   Mile 6  Mile 7  FS_1 0  .       .   24Jan00  24Jan00
   Mile 7  .       .    0  .       .   25Jan00  25Jan00
   Task 8  Mile 9  SS_3 1  .       .   .        .
   Mile 9  Mile 10 .    0  .       .   27Jan00  27Jan00
   Mile 10 .       .    0  .       .   27Jan00  27Jan00
   Task 11 Mile 12 .    2  .       .   .        .
   Mile 12 Mile 13 FS_1 0 26Jan00  SGE 26Jan00  25Jan00
   Mile 13 .       .    0  .       .   27Jan00  26Jan00
   ;

Output 2.1.1: Input Data Set
 
Input Data Set

Obs act succ lag dur target trgttype miledate notrgtmd
1 Task 0 Mile 1 ss_0 1 24JAN00 SGE . .
2 Mile 1 Task 2   0 .   24JAN00 24JAN00
3 Task 2     1 .   . .
4 Task 3 Mile 4   1 .   . .
5 Mile 4     0 .   24JAN00 24JAN00
6 Task 5 Mile 6   1 .   . .
7 Mile 6 Mile 7 FS_1 0 .   24JAN00 24JAN00
8 Mile 7     0 .   25JAN00 25JAN00
9 Task 8 Mile 9 SS_3 1 .   . .
10 Mile 9 Mile 10   0 .   27JAN00 27JAN00
11 Mile 10     0 .   27JAN00 27JAN00
12 Task 11 Mile 12   2 .   . .
13 Mile 12 Mile 13 FS_1 0 26JAN00 SGE 26JAN00 25JAN00
14 Mile 13     0 .   27JAN00 26JAN00

Output 2.1.2: Default Schedule
 
Default Schedule

Obs act succ dur lag notrgtmd E_START E_FINISH L_START L_FINISH T_FLOAT F_FLOAT
1 Task 0 Mile 1 1 ss_0 . 24JAN00 24JAN00 26JAN00 26JAN00 2 0
2 Mile 1 Task 2 0   24JAN00 24JAN00 24JAN00 26JAN00 26JAN00 2 0
3 Task 2   1   . 24JAN00 24JAN00 26JAN00 26JAN00 2 2
4 Task 3 Mile 4 1   . 24JAN00 24JAN00 26JAN00 26JAN00 2 0
5 Mile 4   0   24JAN00 25JAN00 25JAN00 27JAN00 27JAN00 2 2
6 Task 5 Mile 6 1   . 24JAN00 24JAN00 25JAN00 25JAN00 1 0
7 Mile 6 Mile 7 0 FS_1 24JAN00 25JAN00 25JAN00 26JAN00 26JAN00 1 0
8 Mile 7   0   25JAN00 26JAN00 26JAN00 27JAN00 27JAN00 1 1
9 Task 8 Mile 9 1 SS_3 . 24JAN00 24JAN00 24JAN00 24JAN00 0 0
10 Mile 9 Mile 10 0   27JAN00 27JAN00 27JAN00 27JAN00 27JAN00 0 0
11 Mile 10   0   27JAN00 27JAN00 27JAN00 27JAN00 27JAN00 0 0
12 Task 11 Mile 12 2   . 24JAN00 25JAN00 24JAN00 25JAN00 0 0
13 Mile 12 Mile 13 0 FS_1 25JAN00 26JAN00 26JAN00 26JAN00 26JAN00 0 0
14 Mile 13   0   26JAN00 27JAN00 27JAN00 27JAN00 27JAN00 0 0

First, the CPM procedure is invoked with the default treatment of milestones. The resulting schedule is printed in Output 2.1.2. Note the dates for the milestones. Compare these dates with the values of the variable notrgtmd that contains the desired milestone schedule dates corresponding to the finish times of their predecessor.

   /* Schedule the project */
   proc cpm data=tasks out=out0 
            collapse interval=day
            date='24jan00'd;
      activity act;
      successor succ /lag=(lag);
      duration dur;
      id lag notrgtmd;
      run;

title 'Default Schedule';
proc print; run;

Next, the CPM procedure is invoked with the option SETFINISHMILESTONE and the resulting schedule is printed in Output 2.1.3. The variables EFINMILE and LFINMILE indicate if the milestone is a finish milestone or not. For example, the milestone `Mile 12' has E_FINISH = 25JAN00 and the value of EFINMILE is `1', indicating that the activity finishes at the end of the day on January 25, 2000. The milestone `Mile 13' (with a finish-to-start lag of 1 day) finishes at the end of the day on January 26, 2000. In fact, as the late finish schedule indicates, the value of L_FINISH for `Mile 13' (and the project finish time) is the end of the day on 26JAN00. Note that both the variables EFINMILE and LFINMILE have the same values for all the activities in this example.

   proc cpm data=tasks out=out1 
            collapse interval=day
            date='24jan00'd
            setfinishmilestone;
      activity act;
      successor succ /lag=(lag);
      duration dur;
      id lag notrgtmd;
      run;

   title 'Schedule with option SETFINISHMILESTONE';
   title2 'No Target Dates';
   proc print; 
     id act;
     var succ lag dur notrgtmd e_start e_finish 
         l_start l_finish efinmile lfinmile;
     run;

Output 2.1.3: Schedule with SETFINISHMILESTONE Option
 
Schedule with option SETFINISHMILESTONE
No Target Dates

act succ lag dur notrgtmd E_START E_FINISH L_START L_FINISH EFINMILE LFINMILE
Task 0 Mile 1 ss_0 1 . 24JAN00 24JAN00 26JAN00 26JAN00 . .
Mile 1 Task 2   0 24JAN00 24JAN00 24JAN00 26JAN00 26JAN00 . .
Task 2     1 . 24JAN00 24JAN00 26JAN00 26JAN00 . .
Task 3 Mile 4   1 . 24JAN00 24JAN00 26JAN00 26JAN00 . .
Mile 4     0 24JAN00 24JAN00 24JAN00 26JAN00 26JAN00 1 1
Task 5 Mile 6   1 . 24JAN00 24JAN00 25JAN00 25JAN00 . .
Mile 6 Mile 7 FS_1 0 24JAN00 24JAN00 24JAN00 25JAN00 25JAN00 1 1
Mile 7     0 25JAN00 25JAN00 25JAN00 26JAN00 26JAN00 1 1
Task 8 Mile 9 SS_3 1 . 24JAN00 24JAN00 24JAN00 24JAN00 . .
Mile 9 Mile 10   0 27JAN00 27JAN00 27JAN00 27JAN00 27JAN00 . .
Mile 10     0 27JAN00 27JAN00 27JAN00 27JAN00 27JAN00 . .
Task 11 Mile 12   2 . 24JAN00 25JAN00 24JAN00 25JAN00 . .
Mile 12 Mile 13 FS_1 0 25JAN00 25JAN00 25JAN00 25JAN00 25JAN00 1 1
Mile 13     0 26JAN00 26JAN00 26JAN00 26JAN00 26JAN00 1 1

The next invocation of CPM illustrates the effect of alignment constraints on the milestones. As explained in the "Finish Milestones" section, imposing an alignment constraint of type SGE on a milestone may change it from a finish milestone to a start milestone (default behavior) as far as the early schedule of the project is concerned. In the following program, the CPM procedure is invoked with the SETFINISHMILESTONE option and the ALIGNDATE and ALIGNTYPE statements. The resulting schedule is printed in Output 2.1.4. Note that the early schedule of the milestones now corresponds to the values in the variable miledate. Note also that the activities `Mile 12' and `Mile 13' are no longer finish milestones, as indicated by missing values for the variable EFINMILE.

   proc cpm data=tasks out=out2 
            collapse
            interval=day
            date='24jan00'd
            setfinishmilestone;
      activity act;
      successor succ /lag=(lag);
      duration dur;
      aligndate target;
      aligntype trgttype;
      id target trgttype lag miledate;
      run;

   title 'Schedule with option SETFINISHMILESTONE';
   title2 'Target Dates change Early Schedule for some Milestones';
   proc print; 
     id act;
     var succ lag target trgttype miledate e_start e_finish 
         l_start l_finish efinmile lfinmile;
     run;

Output 2.1.4: Effect of Alignment Constraints
 
Schedule with option SETFINISHMILESTONE
Target Dates change Early Schedule for some Milestones

act succ lag target trgttype miledate E_START E_FINISH L_START L_FINISH EFINMILE LFINMILE
Task 0 Mile 1 ss_0 24JAN00 SGE . 24JAN00 24JAN00 26JAN00 26JAN00 . .
Mile 1 Task 2   .   24JAN00 24JAN00 24JAN00 26JAN00 26JAN00 . .
Task 2     .   . 24JAN00 24JAN00 26JAN00 26JAN00 . .
Task 3 Mile 4   .   . 24JAN00 24JAN00 26JAN00 26JAN00 . .
Mile 4     .   24JAN00 24JAN00 24JAN00 26JAN00 26JAN00 1 1
Task 5 Mile 6   .   . 24JAN00 24JAN00 25JAN00 25JAN00 . .
Mile 6 Mile 7 FS_1 .   24JAN00 24JAN00 24JAN00 25JAN00 25JAN00 1 1
Mile 7     .   25JAN00 25JAN00 25JAN00 26JAN00 26JAN00 1 1
Task 8 Mile 9 SS_3 .   . 24JAN00 24JAN00 24JAN00 24JAN00 . .
Mile 9 Mile 10   .   27JAN00 27JAN00 27JAN00 27JAN00 27JAN00 . .
Mile 10     .   27JAN00 27JAN00 27JAN00 27JAN00 27JAN00 . .
Task 11 Mile 12   .   . 24JAN00 25JAN00 24JAN00 25JAN00 . .
Mile 12 Mile 13 FS_1 26JAN00 SGE 26JAN00 26JAN00 26JAN00 25JAN00 25JAN00 . 1
Mile 13     .   27JAN00 27JAN00 27JAN00 26JAN00 26JAN00 . 1

The interpretation of the start and finish times for a milestone depends on whether it is a start milestone or a finish milestone. By default, all milestones are start milestones and are assumed to be scheduled at the beginning of the date specified in the start or finish time variable. As such, PROC GANTT displays these milestones at the start of the corresponding days on the Gantt chart. However, if a milestone is a finish milestone then it may not be displayed correctly on the Gantt chart, depending on the scale of the display.

In this example, PROC GANTT is used to display the schedule produced in Output 2.1.4. Recall that the schedule is saved in the data set out2. First, PROC GANTT is invoked without any modifications to the schedule data set. The resulting Gantt chart is displayed in Output 2.1.5. Note that the finish milestones (with values of EFINMILE = `1') are not plotted correctly. For example, `Mile 6' is plotted at the beginning instead of the end of the schedule bar for the predecessor activity, `Act 5'. To correct this problem, you can adjust the schedule variables for the finish milestones and plot the new values, as illustrated by the second invocation of PROC GANTT. The corrected Gantt chart is displayed in Output 2.1.6.

   title h=1.5 
       'Schedule with option SETFINISHMILESTONE and ALIGNDATE';
   title2 'Gantt Chart of Early Schedule without adjustment';
   proc gantt data=out2(drop=l_:);
      chart / compress act=act succ=succ lag=lag 
              font=swiss scale=7
              cprec=cyan cmile=magenta
              caxis=black cframe=ligr;
              dur=dur nojobnum nolegend;
      id act succ lag e_start efinmile;
      run;

   /* Save adjusted E_START and E_FINISH times for finish 
      milestones */
   data temp;
      set out2;
      format estart efinish date7.;
      estart = e_start;
      efinish = e_finish;
      if efinmile then do;
         estart=estart+1;
         efinish=efinish+1;
         end;
      run;

   /* Plot the adjusted start and finish times for the 
      early schedule */
   title h=1.5 
      'Schedule with option SETFINISHMILESTONE and ALIGNDATE';
   title2 'Gantt Chart of Early Schedule after adjustment';
   proc gantt data=temp(drop=l_:);
      chart / compress act=act succ=succ lag=lag 
              font=swiss scale=7
              es=estart ef=efinish
              cprec=cyan cmile=magenta
              caxis=black cframe=ligr;
              dur=dur nojobnum  nolegend;
      id act succ lag e_start efinmile;
      run;

Output 2.1.5: Gantt Chart of Unadjusted Schedule
cpm1o5.gif (5979 bytes)

Output 2.1.6: Gantt Chart of Adjusted Schedule
cpm1o6.gif (5955 bytes)

Chapter Contents
Chapter Contents
Previous
Previous
Next
Next
Top
Top

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