Cost control and accounting are important aspects of project management. Cost data for a project may be associated with activities or groups of activities, or with resources, such as personnel or equipment. For example, consider a project that consists of several subprojects, each of which is contracted to a different company. From the contracting company’s point of view, each subproject can be treated as one cost item; all the company needs to know is how much each subproject is going to cost. On the other hand, another project may contain several activities, each of which requires two types of labor, skilled and unskilled. The cost for each activity in the project may have to be computed on the basis of how much skilled or unskilled labor that activity uses. In this case, activity and project costs are determined from the resources used. Further, for any project, there may be several ways in which costs need to be summarized and accounted for. In addition to determining the cost of each individual activity, you may want to determine periodic budgets for different departments that are involved with the project or compare the actual costs that were incurred with the budgeted costs.
It is easy to set up cost accounting systems using the output data sets produced by PROC CPM, whether costs are associated with activities or with resources. In fact, you can even treat cost as a consumable resource if you can estimate the cost per day for each of the activities (see Chapter 4: The CPM Procedure, for details about resource allocation and types of resources). This example illustrates such a method for monitoring costs and shows how you can compute some of the standard cost performance measures used in project management.
The following three measures can be used to determine if a project is running on schedule and within budget (see Moder, Phillips, and Davis 1983, for a detailed discussion on project cost control):
Actual cost of work performed (ACWP) is the actual cost expended to perform the work accomplished in a given period of time.
Budgeted cost of work performed (BCWP) is the budgeted cost of the work completed in a given period of time.
Budgeted cost of work scheduled (BCWS) is the budgeted cost of the work scheduled to be accomplished in a given period of time (if a baseline schedule were followed).
Consider the survey example described earlier in this chapter. Suppose that it is possible to estimate the cost per day for
each activity in the project. The following data set survcost
contains the project data (activity, succ1–succ3, id, duration
) and a variable named cost
containing the cost per day in dollars. In order to compute the BCWS for the project, you need to establish a baseline schedule.
Suppose the early start schedule computed by PROC CPM is chosen as the baseline schedule. The Resource data set costavl
establishes cost
as a consumable resource, so that the CPM procedure can be used to accumulate costs (using the CUMUSAGE option).
The following program invokes PROC CPM with the RESOURCE statement and saves the Usage data set in survrout
. The variable ecost
in this Usage data set contains the cumulative expense incurred for the baseline schedule; this is the same as the budgeted
cost of work scheduled (or BCWS) saved in the data set basecost
.
data survcost; format id $20. activity $8. succ1-succ3 $8. ; input id & activity & duration succ1 & succ2 & succ3 & cost; datalines; Plan Survey plan sur 4 hire per design q . 300 Hire Personnel hire per 5 trn per . . 350 Design Questionnaire design q 3 trn per select h print q 100 Train Personnel trn per 3 cond sur . . 500 Select Households select h 3 cond sur . . 300 Print Questionnaire print q 4 cond sur . . 250 Conduct Survey cond sur 10 analyze . . 200 Analyze Results analyze 6 . . . 500 ; data holidata; format hol date7.; hol = '4jul03'd; run; data costavl; input per & date7. otype $ cost; format per date7.; datalines; . restype 2 1jul03 reslevel 12000 ;
proc cpm date='1jul03'd interval=weekday data=survcost resin=costavl holidata=holidata out=sched resout=survrout; activity activity; successor succ1-succ3; duration duration; holiday hol; id id; resource cost / period = per obstype = otype cumusage; run;
data basecost (keep = _time_ bcws); set survrout; bcws = ecost; run;
Suppose that the project started as planned on July 1, 2003, but some of the activities took longer than planned and some
of the cost estimates were found to be incorrect. The following data set, actual
, contains updated information: the variables as
and af
contain the actual start and finish times of the activities that have been completed or are in progress. The variable actcost
contains the revised cost per day for each activity. The following program combines this information with the existing project
data and saves the result in the data set update
, displayed in Output 3.8.1. The Resource data set costavl2
(also displayed in Output 3.8.1) defines cost
and actcost
as consumable resources.
data actual; format id $20. ; input id & as & date9. af & date9. actcost; format as af date7.; datalines; Plan Survey 1JUL03 8JUL03 275 Hire Personnel 9JUL03 15JUL03 350 Design Questionnaire 10JUL03 14JUL03 150 Train Personnel 16JUL03 17JUL03 800 Select Households 15JUL03 17JUL03 450 Print Questionnaire 15JUL03 18JUL03 250 Conduct Survey 21JUL03 . 200 ; data work.update; merge survcost actual; run; data costavl2; input per & date7. otype $ cost actcost; format per date7.; datalines; . restype 2 2 1jul03 reslevel 12000 12000 ;
title 'Activity Data Set UPDATE'; proc print data=work.update; run; title 'Resource Data Set COSTAVL2'; proc print data=costavl2; run;
Output 3.8.1: Project Cost Control: Progress Update
Activity Data Set UPDATE |
Obs | id | activity | succ1 | succ2 | succ3 | duration | cost | as | af | actcost |
---|---|---|---|---|---|---|---|---|---|---|
1 | Plan Survey | plan sur | hire per | design q | 4 | 300 | 01JUL03 | 08JUL03 | 275 | |
2 | Hire Personnel | hire per | trn per | 5 | 350 | 09JUL03 | 15JUL03 | 350 | ||
3 | Design Questionnaire | design q | trn per | select h | print q | 3 | 100 | 10JUL03 | 14JUL03 | 150 |
4 | Train Personnel | trn per | cond sur | 3 | 500 | 16JUL03 | 17JUL03 | 800 | ||
5 | Select Households | select h | cond sur | 3 | 300 | 15JUL03 | 17JUL03 | 450 | ||
6 | Print Questionnaire | print q | cond sur | 4 | 250 | 15JUL03 | 18JUL03 | 250 | ||
7 | Conduct Survey | cond sur | analyze | 10 | 200 | 21JUL03 | . | 200 | ||
8 | Analyze Results | analyze | 6 | 500 | . | . | . |
Resource Data Set COSTAVL2 |
Obs | per | otype | cost | actcost |
---|---|---|---|---|
1 | . | restype | 2 | 2 |
2 | 01JUL03 | reslevel | 12000 | 12000 |
Next, PROC CPM is used to revise the schedule by using the ACTUAL statement to specify the actual start and finish times and
the RESOURCE statement to specify both the budgeted and the actual costs. The resulting schedule is saved in the data set
updsched
(displayed in Output 3.8.2) and the budgeted and the actual cumulative costs of the project (until the current date) are saved in the data set updtrout
. These cumulative costs represent the budgeted cost of work performed (BCWP) and the actual cost of work performed (ACWP),
respectively, and are saved in the data set updtcost
. The two data sets basecost
and updtcost
are then merged to create a data set that contains the three measures: bcws
, bcwp
, and acwp
. The resulting data set is displayed in Output 3.8.3.
proc cpm date='1jul03'd interval=weekday data=work.update resin=costavl2 out=updsched resout=updtrout holidata=holidata; activity activity; successor succ1-succ3; duration duration; holiday hol; id id; resource cost actcost / per = per obstype = otype maxdate = '21jul03'd cumusage; actual / a_start=as a_finish=af; run;
title 'Updated Schedule: Data Set UPDSCHED'; proc print data=updsched; run;
data updtcost (keep = _time_ bcwp acwp); set updtrout; bcwp = ecost; acwp = eactcost; run; /* Create a combined data set to contain the BCWS, BCWP, ACWP */ /* per day and the cumulative values for these costs. */ data costs; merge basecost updtcost; run;
title 'BCWS, BCWP, and ACWP'; proc print data=costs; run;
Output 3.8.2: Project Cost Control: Updated Schedule
Updated Schedule: Data Set UPDSCHED |
Obs | activity | succ1 | succ2 | succ3 | duration | STATUS | A_DUR | id | cost | actcost | A_START | A_FINISH | S_START | S_FINISH | E_START | E_FINISH | L_START | L_FINISH |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | plan sur | hire per | design q | 4 | Completed | 5 | Plan Survey | 300 | 275 | 01JUL03 | 08JUL03 | 01JUL03 | 08JUL03 | 01JUL03 | 08JUL03 | 01JUL03 | 08JUL03 | |
2 | hire per | trn per | 5 | Completed | 5 | Hire Personnel | 350 | 350 | 09JUL03 | 15JUL03 | 09JUL03 | 15JUL03 | 09JUL03 | 15JUL03 | 09JUL03 | 15JUL03 | ||
3 | design q | trn per | select h | print q | 3 | Completed | 3 | Design Questionnaire | 100 | 150 | 10JUL03 | 14JUL03 | 10JUL03 | 14JUL03 | 10JUL03 | 14JUL03 | 10JUL03 | 14JUL03 |
4 | trn per | cond sur | 3 | Completed | 2 | Train Personnel | 500 | 800 | 16JUL03 | 17JUL03 | 16JUL03 | 17JUL03 | 16JUL03 | 17JUL03 | 16JUL03 | 17JUL03 | ||
5 | select h | cond sur | 3 | Completed | 3 | Select Households | 300 | 450 | 15JUL03 | 17JUL03 | 15JUL03 | 17JUL03 | 15JUL03 | 17JUL03 | 15JUL03 | 17JUL03 | ||
6 | print q | cond sur | 4 | Completed | 4 | Print Questionnaire | 250 | 250 | 15JUL03 | 18JUL03 | 15JUL03 | 18JUL03 | 15JUL03 | 18JUL03 | 15JUL03 | 18JUL03 | ||
7 | cond sur | analyze | 10 | In Progress | . | Conduct Survey | 200 | 200 | 21JUL03 | . | 21JUL03 | 01AUG03 | 21JUL03 | 01AUG03 | 21JUL03 | 01AUG03 | ||
8 | analyze | 6 | Pending | . | Analyze Results | 500 | . | . | . | 04AUG03 | 11AUG03 | 04AUG03 | 11AUG03 | 04AUG03 | 11AUG03 |
Output 3.8.3: Project Cost Control: BCWS, BCWP, ACWP
BCWS, BCWP, and ACWP |
Obs | _TIME_ | bcws | bcwp | acwp |
---|---|---|---|---|
1 | 01JUL03 | 0 | 0 | 0 |
2 | 02JUL03 | 300 | 300 | 275 |
3 | 03JUL03 | 600 | 600 | 550 |
4 | 07JUL03 | 900 | 900 | 825 |
5 | 08JUL03 | 1200 | 1200 | 1100 |
6 | 09JUL03 | 1650 | 1500 | 1375 |
7 | 10JUL03 | 2100 | 1850 | 1725 |
8 | 11JUL03 | 2550 | 2300 | 2225 |
9 | 14JUL03 | 3450 | 2750 | 2725 |
10 | 15JUL03 | 4350 | 3200 | 3225 |
11 | 16JUL03 | 5400 | 4100 | 4275 |
12 | 17JUL03 | 6150 | 5150 | 5775 |
13 | 18JUL03 | 6650 | 6200 | 7275 |
14 | 21JUL03 | 6850 | 6450 | 7525 |
15 | 22JUL03 | 7050 | . | . |
16 | 23JUL03 | 7250 | . | . |
17 | 24JUL03 | 7450 | . | . |
18 | 25JUL03 | 7650 | . | . |
19 | 28JUL03 | 7850 | . | . |
20 | 29JUL03 | 8050 | . | . |
21 | 30JUL03 | 8250 | . | . |
22 | 31JUL03 | 8450 | . | . |
23 | 01AUG03 | 8650 | . | . |
24 | 04AUG03 | 9150 | . | . |
25 | 05AUG03 | 9650 | . | . |
26 | 06AUG03 | 10150 | . | . |
27 | 07AUG03 | 10650 | . | . |
28 | 08AUG03 | 11150 | . | . |
29 | 11AUG03 | 11650 | . | . |
The data set costs
, containing the required cost information, is then used as input to PROC GPLOT to produce a plot of the three cumulative
cost measures. The plot is shown in Output 3.8.4.
Note: BCWS, BCWP, and ACWP are three of the cost measures used as part of Earned Value Analysis, which is an important component of the Cost/Schedule Control Systems Criteria (referred to as C/SCSC) that was established in 1967 by the Department of Defense (DOD) to standardize the reporting of cost and schedule performance on major contracts. Refer to Fleming (1988) for a detailed discussion of C/SCSC. Similar methods, such as the ones described in this example, can be used to calculate all the relevant measures for analyzing cost and schedule performance.
/* Plot the cumulative costs */ data costplot (keep=date dollars id); set costs; format date date7.; date = _time_; if bcws ^= . then do; dollars = BCWS; id = 1; output; end; if bcwp ^= . then do; dollars = BCWP; id = 2; output; end; if acwp ^= . then do; dollars = ACWP; id = 3; output; end; run;
legend1 frame value=(c=black j=l 'BCWS' 'BCWP' 'ACWP') label=(c=black); axis1 width=2 order=('1jul03'd to '1aug03'd by week) length=60 pct value=(c=black) label=(c=black); axis2 width=2 order=(0 to 12000 by 2000) length = 55 pct value=(c=black) label=(c=black); symbol1 i=join v=none c=green w=4 l=1; symbol2 i=join v=none c=blue w=4 l=2; symbol3 i=join v=none c=red w=4 l=3; title c=black h=2.5 'Comparison of Costs'; proc gplot data=costplot; plot dollars * date = id / legend=legend1 haxis=axis1 vaxis=axis2; run;