Program Control_break;
{ Purpose: illustrate the classical CONTROL BREAK problem, where subtotals
are accumulated for each of several different categories (Employee IDs,
sales accounts, etc.), after which a grand total of all subtotals is
given. The input file must be sorted according to category; when the
category changes, a "break" occurs and a subtotal is printed. The
technique can be used to any desired degree of nested. }
Uses
Crt;
Type
Code_num = 100..999;
Line = String[80];
Const
Inputfilename = 'NEWSALES.DAT';
Var
Infile: Text;
Sales_record: Line;
Salesperson_number, Previous_number: Code_num;
Sales_amount, Subtotal, Grandtotal: Real;
{ Procedure #1: Find the salesperson number in sales record St }
Procedure Find_Salesperson_number(St: Line; Var SN: Code_num);
{ Purpose: St is a string of 80 characters; the first characters in the
the string are the salesperson number. Determine this number.
Input: St = sales record as read from the input file
Output: the sales person number is copied from the string and returned
to the calling program in SN }
Const
Space = ' ';
Var
Num: Line;
Location, Error, Temp: Integer;
Begin
Location := POS(Space, St); { locate first space in St }
Num := COPY(St, 1, Location - 1); { Num is all chars in St up to 1st space }
Val(Num, Temp, Error); { Temp is numeric value of Num }
If Error > 0
Then Writeln('Conversion error at ', Error)
Else SN := Temp; { SN = salesperson number }
End;
{ Procedure #2: Find the sales amount at end of sales record St }
Procedure Find_sales_amount(St: Line; Var Sales: Real);
{ Purpose: St is a string of 80 characters; the final characters in the
the string are the amount of sales. Determine this number.
Input: St = sales record as read from the input file
Output: the sales amount is copied from the string and returned
to the calling program in Sales }
Const
Decimal_pt = '.';
Space = ' ';
Comma = ',';
Var
Location, Error: Integer;
R_St: Line;
Begin
Location := POS(Decimal_pt, St); { find decimal point in sales amount in St }
While St[Location] <> Space Do { back up to first space before decimal pt }
Location := PRED(Location);
R_st := COPY(St, Location, Length(St)); { copy sales amount string to R_st }
Location := POS(Comma, R_st); { find comma in R_st }
If Location > 0 { if comma found, remove it }
Then Delete(R_st, Location, 1);
Val(R_st, Sales, Error) { convert R_st to real value in Sales }
End;
Begin { MAIN }
Clrscr;
{ Open input file, initialize grand total of all sales, and print
report header to output file }
Assign(Infile, Inputfilename);
Reset(Infile);
Grandtotal := 0.0;
Writeln('Salesperson', 'Sales' :10, 'Totals' :20);
Writeln('==========================================');
{ Process the first line of the input file:
a) read a sales record from the input file
b) find the salesperson number from the record; put in Salesperson_number
c) record this number in Previous_number; when the salesperson number
changes, this change will be detected by comparison to Previous_number
d) find the sales amount for this salesperson; put in Sales_amount
e) initialize Subtotal }
If NOT EOF(Infile)
Then
Begin
Readln(Infile, Sales_record);
Find_Salesperson_number(Sales_record, Salesperson_number);
Previous_number := Salesperson_number;
Find_sales_amount(Sales_record, Sales_amount);
Writeln(Salesperson_number, Sales_amount :18:2);
Subtotal := Sales_amount;
End;
While NOT EOF(Infile) Do
Begin
{ Read next sales record, determine salesperson number, and
corresponding sales amount }
Readln(Infile, Sales_record);
Find_Salesperson_number(Sales_record, Salesperson_number);
Find_sales_amount(Sales_record, Sales_amount);
{ If salesperson number has not changed, then process sales for
this salesperson (update sales total) and print salesperson
number and amount of sales in output }
If Salesperson_number = Previous_number
Then
Begin
Subtotal := Subtotal + Sales_amount;
Write(Salesperson_number);
Writeln(Sales_amount :18:2)
End
Else
Begin
{ This is the "control break". The salesperson number has
changed, so the printing of information for the previous
salesperson is complete; "break" such output and print the
subtotal for that salesperson. Update Grand total. Record
the new salesperson number in Previous_number. Write a new
detail line for new salesperson and sales amount. }
Writeln;
Writeln('Subtotal: ', Subtotal :32:2);
Writeln;
Grandtotal := Grandtotal + Subtotal;
Subtotal := Sales_amount;
Previous_number := Salesperson_number;
Write(Salesperson_number);
Writeln(Sales_amount :18:2)
End
End;
Close(Infile);
{ When we leave the WHILE loop, the last subtotal has not yet been
printed, because there was no opportunity to change the salesperson
number. Print the last salesperson's sales subtotal, update the
grand total, and print the grand total of all sales }
Writeln;
Writeln('Subtotal: ', Subtotal :32:2);
Grandtotal := Grandtotal + Subtotal;
Writeln;
Writeln('TOTAL SALES: ', Grandtotal :29:2);
Readln
End.
-------------------------------------------------
INPUT FILE: NEWSALES.DAT
-------------------------------------------------
111 3/26/96 G28 1,292.49
111 10/10/96 G66 1,470.57
121 9/21/96 M71 558.89
121 1/5/96 I48 1,199.72
121 10/27/96 Q75 551.87
155 8/27/96 G39 1,749.14
-------------------------------------------------
SCREEN OUTPUT FROM PROGRAM RUN:
-------------------------------------------------
Salesperson Sales Totals
==========================================
111 1292.49
111 1470.57
Subtotal: 2763.06
121 558.89
121 1199.72
121 551.87
Subtotal: 2310.48
155 1749.14
Subtotal: 1749.14
TOTAL SALES: 6822.68