* as it is when the file is ordered on ascending StateName
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT SalesFile ASSIGN TO "Listing11-4TestData.Dat"
ORGANIZATION IS LINE SEQUENTIAL.
SELECT SalesReport ASSIGN TO "Listing11-4.RPT"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD SalesFile.
01 SalesRecord.
88 EndOfSalesFile VALUE HIGH-VALUES.
02 StateNum PIC 99.
02 BranchId PIC X(5).
02 SalesPersonId PIC X(6).
02 ValueOfSale PIC 9(4)V99.
FD SalesReport.
01 PrintLine PIC X(55).
WORKING-STORAGE SECTION.
01 StateNameTable.
02 StateNameValues.
03 FILLER PIC X(14) VALUE "Alabama".
03 FILLER PIC X(14) VALUE "Alaska".
03 FILLER PIC X(14) VALUE "Arizona".
03 FILLER PIC X(14) VALUE "Arkansas".
03 FILLER PIC X(14) VALUE "California".
03 FILLER PIC X(14) VALUE "Colorado".
03 FILLER PIC X(14) VALUE "Connecticut".
266
Chapter 11 ■ Creating tabular Data
03 FILLER PIC X(14) VALUE "Delaware".
03 FILLER PIC X(14) VALUE "Florida".
03 FILLER PIC X(14) VALUE "Georgia".
03 FILLER PIC X(14) VALUE "Hawaii".
03 FILLER PIC X(14) VALUE "Idaho".
03 FILLER PIC X(14) VALUE "Illinois".
03 FILLER PIC X(14) VALUE "Indiana".
03 FILLER PIC X(14) VALUE "Iowa".
03 FILLER PIC X(14) VALUE "Kansas".
03 FILLER PIC X(14) VALUE "Kentucky".
03 FILLER PIC X(14) VALUE "Louisiana".
03 FILLER PIC X(14) VALUE "Maine".
03 FILLER PIC X(14) VALUE "Maryland".
03 FILLER PIC X(14) VALUE "Massachusetts".
03 FILLER PIC X(14) VALUE "Michigan".
03 FILLER PIC X(14) VALUE "Minnesota".
03 FILLER PIC X(14) VALUE "Mississippi".
03 FILLER PIC X(14) VALUE "Missouri".
03 FILLER PIC X(14) VALUE "Montana".
03 FILLER PIC X(14) VALUE "Nebraska".
03 FILLER PIC X(14) VALUE "Nevada".
03 FILLER PIC X(14) VALUE "New Hampshire".
03 FILLER PIC X(14) VALUE "New Jersey".
03 FILLER PIC X(14) VALUE "New Mexico".
03 FILLER PIC X(14) VALUE "New York".
03 FILLER PIC X(14) VALUE "North Carolina".
03 FILLER PIC X(14) VALUE "North Dakota".
03 FILLER PIC X(14) VALUE "Ohio".
03 FILLER PIC X(14) VALUE "Oklahoma".
03 FILLER PIC X(14) VALUE "Oregon".
03 FILLER PIC X(14) VALUE "Pennsylvania".
03 FILLER PIC X(14) VALUE "Rhode Island".
03 FILLER PIC X(14) VALUE "South Carolina".
03 FILLER PIC X(14) VALUE "South Dakota".
03 FILLER PIC X(14) VALUE "Tennessee".
03 FILLER PIC X(14) VALUE "Texas".
03 FILLER PIC X(14) VALUE "Utah".
03 FILLER PIC X(14) VALUE "Vermont".
03 FILLER PIC X(14) VALUE "Virginia".
03 FILLER PIC X(14) VALUE "Washington".
03 FILLER PIC X(14) VALUE "West Virginia".
03 FILLER PIC X(14) VALUE "Wisconsin".
03 FILLER PIC X(14) VALUE "Wyoming".
02 FILLER REDEFINES StateNameValues.
03 StateName PIC X(14) OCCURS 50 TIMES.
267
Chapter 11 ■ Creating tabular Data
01 ReportHeading.
02 FILLER PIC X(35)
VALUE " Electronics2Go Sales Report".
01 SubjectHeading.
02 FILLER PIC X(43)
VALUE "State Name Branch SalesId SalesTotal".
01 DetailLine.
02 PrnStateName PIC X(14).
88 SuppressStateName VALUE SPACES.
02 PrnBranchId PIC BBX(5).
88 SuppressBranchId VALUE SPACES.
02 PrnSalespersonId PIC BBBBX(6).
02 PrnSalespersonTotal PIC BB$$,$$9.99.
01 BranchTotalLine.
02 FILLER PIC X(43)
VALUE " Branch Total: ".
02 PrnBranchTotal PIC $$$,$$9.99.
01 StateTotalLine.
02 FILLER PIC X(40)
VALUE " State Total : ".
02 PrnStateTotal PIC $$,$$$,$$9.99.
01 FinalTotalLine.
02 FILLER PIC X(39)
VALUE " Final Total :".
02 PrnFinalTotal PIC $$$,$$$,$$9.99.
01 SalespersonTotal PIC 9(4)V99.
01 BranchTotal PIC 9(6)V99.
01 StateTotal PIC 9(7)V99.
01 FinalTotal PIC 9(9)V99.
01 PrevStateNum PIC 99.
01 PrevBranchId PIC X(5).
01 PrevSalespersonId PIC X(6).
PROCEDURE DIVISION.
Begin.
OPEN INPUT SalesFile
OPEN OUTPUT SalesReport
WRITE PrintLine FROM ReportHeading AFTER ADVANCING 1 LINE
WRITE PrintLine FROM SubjectHeading AFTER ADVANCING 1 LINE
READ SalesFile
AT END SET EndOfSalesFile TO TRUE
END-READ
PERFORM UNTIL EndOfSalesFile
268
Chapter 11 ■ Creating tabular Data
MOVE StateNum TO PrevStateNum,
MOVE StateName(StateNum) TO PrnStateName
MOVE ZEROS TO StateTotal
PERFORM SumSalesForState
UNTIL StateNum NOT = PrevStateNum
OR EndOfSalesFile
MOVE StateTotal TO PrnStateTotal
WRITE PrintLine FROM StateTotalLine AFTER ADVANCING 1 LINE
END-PERFORM
MOVE FinalTotal TO PrnFinalTotal
WRITE PrintLine FROM FinalTotalLine AFTER ADVANCING 1 LINE
CLOSE SalesFile, SalesReport
STOP RUN.
SumSalesForState.
WRITE PrintLine FROM SPACES AFTER ADVANCING 1 LINE
MOVE BranchId TO PrevBranchId, PrnBranchId
MOVE ZEROS TO BranchTotal
PERFORM SumSalesForBranch
UNTIL BranchId NOT = PrevBranchId
OR StateNum NOT = PrevStateNum
OR EndOfSalesFile
MOVE BranchTotal TO PrnBranchTotal
WRITE PrintLine FROM BranchTotalLine AFTER ADVANCING 1 LINE.
SumSalesForBranch.
MOVE SalespersonId TO PrevSalespersonId, PrnSalespersonId
MOVE ZEROS TO SalespersonTotal
PERFORM SumSalespersonSales
UNTIL SalespersonId NOT = PrevSalespersonId
OR BranchId NOT = PrevBranchId
OR StateNum NOT = PrevStateNum
OR EndOfSalesFile
MOVE SalespersonTotal TO PrnSalespersonTotal
WRITE PrintLine FROM DetailLine AFTER ADVANCING 1 LINE
SET SuppressBranchId TO TRUE
SET SuppressStateName TO TRUE.
SumSalespersonSales.
ADD ValueOfSale TO SalespersonTotal, BranchTotal, StateTotal, FinalTotal
READ SalesFile
AT END SET EndOfSalesFile TO TRUE
END-READ.
269
Chapter 11 ■ Creating tabular Data
ANS 85 Table Changes
The ANS 85 COBOL standard introduced a number of changes to tables. Among these changes is a method that lets you create prefilled tables without using the REDEFINES clause, as long as the number of values is small. For large amounts of data, the REDEFINES clause is still required.
The new method works by assigning the values to a group name defined over a subordinate table. For instance, in Example 11-11, the data item Day actually declares the table, but I have given the table the overall group name DayTable. Assigning the values to this group name fills the area of the table with the
values.
Example 11-11. Creating a Prefilled Table Without the REDEFINES Clause
01 DayTable VALUE "MonTueWedThrFriSatSun".
02 Day OCCURS 7 TIMES PIC X(3).
The ANS 85 COBOL standard also introduced some changes to the way tables are initialized. In the previous
versions of COBOL, initializing a table was never a problem if the elements of the table were elementary items. All that was required was to move the initializing value to the table’s group name. For instance, the statement MOVE ZEROS TO
DriverTable initializes the following table to zeros:
01 DriverTable.
02 StateDrivers PIC 9(7) OCCURS 50 TIMES.
But initializing a table was much more difficult if each element was a group item that contained different types of data. For instance, in the following table, the StateDrivers part of the element had to be initialized to zeros, and the StateName part had to be initialized to spaces. The only way do this was to initialize the items, element by element, using iteration:
01 DriverTable.
02 State OCCURS 50 TIMES.
03 StateDrivers PIC 9(7).
03 StateName PIC X(14).
The ANS 85 standard introduced a new way to initialize table elements that solves this problem. A table cannot be initialized by assigning an initial value to each part of an element using the VALUE clause. The following description initializes the StateDrivers part of the element to zeros and the StateName part to spaces:
01 DriverTable.
02 State OCCURS 50 TIMES.
03 StateDrivers PIC 9(7) VALUE ZEROS.
03 StateName PIC X(14) VALUE SPACES.
This example shows the ANS 85 changes that allow table elements to be initialized when a program starts; but sometimes data items need to be reinitialized while a program is running. The ANS 85 standard added the INITIALIZE
verb for this purpose. The INITIALIZE verb sets data items, including table elements, either to their MOVE fill value (zero for numeric items, spaces for alphabetic or alphanumeric items) or to a specified compatible replacement value.
The metalanguage for the INITIALIZE verb is given in Figure 11-7.
270
Chapter 11 ■ Creating tabular Data
Figure 11-7. Metalanguage for the INITIALIZE verb
A large number of rules govern the operation of the INITIALIZE verb. For full details, please consult your COBOL
manual. To get a feel for how INITIALIZE operates, examine output produced by the code in Example 11-12.
Example 11-12. Example Uses of the INITIALIZE Verb
01 GroupItem.
02 Data1 PIC X(7).
02 Data2 PIC 9(5).
02 Data3 PIC 99/99/99.
02 Data4 PIC +99.99.
02 Data5 PIC $$,$$9.99.
: : : : : : : : : : : :
PROCEDURE DIVISION.
Begin.
MOVE ALL "-" TO GroupItem
INITIALIZE GroupItem
DISPLAY "Init1__" Data1 "__" Data2 "__" Data3 "__" Data4 "__" Data5.
INITIALIZE GroupItem REPLACING ALPHANUMERIC BY "Michael"
NUMERIC BY 54321.
DISPLAY "Init2__" Data1 "__" Data2 "__" Data3 "__" Data4 "__" Data5.
STOP RUN.
Summary
This chapter introduced the concept of tabular data. You learned how to create tables using the OCCURS clause and were introduced to the notion of group items as table elements. I discussed multidimensional tables and showed how to create, use, and graphically depict them. In the final section, you saw how to use the REDEFINES clause to create a table prefilled with table values, and I discussed the table declaration changes that were introduced with the ANS 85 standard.
The next chapter discusses the other uses of the REDEFINES clause and introduces the similar but ill-favored RENAMES clause. You learn about the importance of decimal arithmetic for the business and enterprise programming domains and discover the use and purpose of the USAGE clause.
prOGraMMING eXerCISe
earlier in this chapter, i presented a problem specification and suggested an approach to solving the problem that involved using a three-dimensional table. although the table was defined in example 11-7, no solution was given.
because you have a problem and no solution, this is an excellent opportunity for you to get some practice using three-dimensional tables.
271
Chapter 11 ■ Creating tabular Data
a subset of the u.S. census data has been made available to you by the u.S. Census bureau (not really—this is just the specification scenario) in an unordered sequential file called the CensusFile. the CensusFile contains the age category (adult, teen, child), gender, state number, and car-ownership information of every person in the country. each record in the file has the following description:
Field
Type
Length
Value
StateNum
9
2
1–50
Age
9
1
1 = Child
2 = Teen
3 = Adult
Gender
9
1
1 = Female
2 = Male
CarOwner
X
1
Y or N
Write a program to process the CensusFile and produce a population Details report that displays the number of males and females in each AgeCategory (Child, Teen, and Adult) in each state. the report format should be as shown in Figure 11-8.
Figure 11-8. Template for the Population Details Report
Specification Extension
Change the three-dimensional table so that it can be used to accumulate the number of car owners in each state.
Change the program so that the format of the report now conforms to the template in Figure 11-9.
Figure 11-9. Template for the Population Details Report that includes car ownership details
References
1. Fowler GC, Glorfeld LW. COBOL tables: A proposed standard of presentation. SIGCSE
Bull. 1983; 15(1): 200-203. http://doi.acm.org/10.1145/952978.801046
doi=10.1145/952978.801046
272
Chapter 12
Advanced Data Declaration
In the last chapter, you learned how to create and use a one-dimensional prefilled table. In this chapter, I continue the discussion of the REDEFINES clause and demonstrate how you can use it to create a two-dimensional prefilled table.
When I introduced the REDEFINES clause in the previous chapter, I did so informally. This chapter formally introduces the REDEFINES clause, including the metalanguage syntax and the semantic rules that apply. It also includes several examples of the other ways in which REDEFINES may be applied.
Because the RENAMES clause is similar to REDEFINES, I introduce RENAMES in this chapter. You learn about the metalanguage syntax for the clause, explore the semantic rules, and see some examples of how to use RENAMES.
The sections discussing the REDEFINES and RENAMES clauses are followed by an introduction to the USAGE clause.
I discuss the advantages and disadvantages of USAGE IS DISPLAY (the default). I cover the metalanguage syntax and the semantic rules and examine USAGE IS COMP, USAGE IS PACKED-DECIMAL, and USAGE IS INDEX in more detail.
Finally, you learn about the purpose and operation of the SYNCHRONIZED clause.
The final section discusses the importance of fixed-point decimal arithmetic to COBOL’s claim of fitness for creating business or enterprise applications. You learn about the problems with doing financial and commercial calculations using floating-point arithmetic. I discuss the Java BigDecimal class and highlight some of the problems with using it, and I contrast COBOL’s native support for decimal arithmetic with the bolted-on capability provided by BigDecimal.
The Redefines Clause
In the previous chapter, you used the REDEFINES clause to create a prefill
ed table of values. I noted at the time that the REDEFINES clause has a number of other uses; this chapter discusses how you can use REDEFINES to achieve powerful data-manipulation effects. However, before I discuss the other uses of REDEFINES, let’s revisit its use in creating prefilled tables. Listing 11-4 used the REDEFINES clause to create a table prefilled with the names of the American states. Although it was interesting to see how to create a prefilled table by laying down the values in memory and then using REDEFINES to redefine the area of memory as a table, the mapping between the actual values in memory and the table definition was straightforward because only a one-dimensional table was required. In Listing 12-1, later in this section, you see how to create a prefilled two-dimensional table of values.
Specification: Aromamora Base Oil Sales Report
The following specification defines a program that demonstrates how to create and use a prefilled two-dimensional table of values.
Aromamora PLC is a company that sells essential and base (carrier) oils to aromatherapists, health shops,
and other mass users of essential oils. Every month, details of the sales of base oils to these customers are gathered together into a sales file (Listing 12-1.Dat in the code download). A program is required that produces a summary report from this file. The report should show the value of the base oils purchased by each customer and should be printed sequenced on ascending CustomerId.
273
Chapter 12 ■ advanCed data deClaration
The Sales File
The sales file contains details of sales to all Aromamora customers. It is a sequential file ordered on ascending CustomerId. The records in the sales file have the following description:
Field
Type
Length
Value
CustomerId
9
5
0–99999
CustomerName
X
20
-
OilId
X
3
B01–B14
UnitSize
9
1
1/2/3
UnitsSold
9
3
1–999
Report Template
Michael Coughlan Page 34