Book Read Free

Michael Coughlan

Page 31

by Beginning COBOL for Programmers-Apress (2014) (pdf)


  updates. to accommodate this change in the specification two new record types will have to be added to the transaction file. these new transaction records are the AddToStock record indicated by a type code of 4 and the SubtractFromStock record indicated by a type code of 5.

  the record descriptions for the MF and the new version of the tF are given here.

  the stock MF is a sequential file ordered on ascending GadgetId. each record has the following description.

  StockMaster Record

  Field

  Type

  Length

  Value

  GadgetId

  9

  6

  000001–999999

  GadgetName

  X

  30

  -

  QtyInStock

  9

  4

  0000–9999

  239

  Chapter 10 ■ proCessing sequential Files

  Field

  Type

  Length

  Value

  Price

  9

  6

  0000.00–9999.99

  the tF is a sequential file ordered on ascending GadgetId. in each set of records with the same GadgetId the records are ordered in sequence in which the transactions occurred in the real world. records in the tF have the following descriptions:

  Insertion record

  Field

  Type

  Length

  Value

  TypeCode

  9

  1

  1

  GadgetId

  9

  6

  000001–999999

  GadgetName

  X

  30

  -

  QtyInStock

  9

  4

  0000–9999

  Price

  9

  6

  0000.00–9999.99

  Deletion record

  Field

  Type

  Length

  Value

  TypeCode

  9

  1

  2

  GadgetId

  9

  6

  000001–999999

  PriceChange record

  Field

  Type Length

  Value

  TypeCode

  9

  1

  3

  GadgetId

  9

  6

  000001–999999

  Price

  9

  6

  0000.00–9999.99

  AddToStock record

  Field

  Type

  Length

  Value

  TypeCode

  9

  1

  4

  GadgetId

  9

  6

  000001–999999

  QtyToAdd

  9

  4

  0000–9999

  SubtractFromStock record

  Field

  Type Length

  Value

  TypeCode

  9

  1

  5

  GadgetId

  9

  6

  000001–999999

  QtyToSubtract 9

  4

  0000–9999

  240

  Chapter 10 ■ proCessing sequential Files

  TestData

  To test your program you can use the test data shown below in Figure 10-17.

  Figure 10-17. Test data including add and subtract from stock transactions

  Notes

  There is an additional error conditions to be noted. If the GadgetId-TF < GadgetId-MF and the type code is 4 or 5 then an error has occurred (no matching master file record) but it is also an error if the transaction is a SubtractFromStock record but the QtyInStock in the MF is less than the QtyToSubtract in the SubtractFromStock record

  prOGraMMING eXerCISe - aNSWer

  Listing 10-5. Update with added AddToStock and SubtractFromStock transactions

  IDENTIFICATION DIVISION.

  PROGRAM-ID. Listing10-5.

  AUTHOR. Michael Coughlan

  * File Update program based on the algorithm described by Barry Dwyer in

  * "One more time - How to update a Master File"

  * Applies the transactions ordered on ascending GadgetId-TF to the

  * MasterStockFile ordered on ascending GadgetId-MF.

  * Within each key value records are ordered on the sequence in which

  241

  Chapter 10 ■ proCessing sequential Files

  * events occurred in the outside world.

  * All valid, real world, transaction sequences are accommodated

  * This version includes additions and subtractions from QtyInStock

  ENVIRONMENT DIVISION.

  INPUT-OUTPUT SECTION.

  FILE-CONTROL.

  SELECT MasterStockFile ASSIGN TO "Listing10-5Master.dat"

  ORGANIZATION IS LINE SEQUENTIAL.

  SELECT NewStockFile ASSIGN TO "Listing10-5NewMast.dat"

  ORGANIZATION IS LINE SEQUENTIAL.

  SELECT TransactionFile ASSIGN TO "Listing10-5Trans.dat"

  ORGANIZATION IS LINE SEQUENTIAL.

  DATA DIVISION.

  FILE SECTION.

  FD MasterStockFile.

  01 MasterStockRec.

  88 EndOfMasterFile VALUE HIGH-VALUES.

  02 GadgetID-MF PIC 9(6).

  02 GadgetName-MF PIC X(30).

  02 QtyInStock-MF PIC 9(4).

  02 Price-MF PIC 9(4)V99.

  FD NewStockFile.

  01 NewStockRec.

  02 GadgetID-NSF PIC 9(6).

  02 GadgetName-NSF PIC X(30).

  02 QtyInStock-NSF PIC 9(4).

  02 Price-NSF PIC 9(4)V99.

  FD TransactionFile.

  01 InsertionRec.

  88 EndOfTransFile VALUE HIGH-VALUES.

  02 TypeCode-TF PIC 9.

  88 Insertion VALUE 1.

  88 Deletion VALUE 2.

  88 UpdatePrice VALUE 3.

  88 StockAddition VALUE 4.

  88 StockSubtraction VALUE 5.

  02 RecordBody-IR.

  03 GadgetID-TF PIC 9(6).

  03 GadgetName-IR PIC X(30).

  03 QtyInStock-IR PIC 9(4).

  03 Price-IR PIC 9(4)V99.

  01 DeletionRec.

  02 FILLER PIC 9(7).

  242

  Chapter 10 ■ proCessing sequential Files

  01 PriceChangeRec.

  02 FILLER PIC 9(7).

  02 Price-PCR PIC 9(4)V99.

  01 AddToStock.

  02 FILLER PIC 9(7).

  02 QtyToAdd PIC 9(4).

  01 SubtractFromStock.

  02 FILLER PIC 9(7).

  02 QtyToSubtract PIC 9(4).

  WORKING-STORAGE SECTION.

  01 ErrorMessage.

  02 PrnGadgetId PIC 9(6).

  02 FILLER PIC XXX VALUE " - ".

  02 FILLER PIC X(46).

  88 InsertError VALUE "Insert Error - Record already exists".

  88 DeleteError VALUE "Delete Error - No such record in Master".

  88 PriceUpdateError VALUE "Price Update Error - No such record in Master".

  88 QtyAddError VALUE "Stock Add Error - No such record in Master".

  88 QtySubtractError VALUE "Stock Subtract Error - No such record in Master".

  88 InsufficientStock VALUE "Stock Subtract Error - Not enough stock".

  01 FILLER PIC X VALUE "n".

  88 RecordInMaster VALUE "y".

  88 RecordNotInMaster VALUE "n".

  01 CurrentKey PIC 9(6).

  PROCEDURE DIVISION.

  Begin.

  OPEN INPUT MasterStockFile

  OPEN INPUT TransactionFile

  OPEN OUTPUT NewStockFile

  PERFORM ReadMasterFile

  PERFORM ReadTransFile

  PERFORM ChooseNextKey

  PERFORM UNTIL EndOfMasterFile AND EndOfTran
sFile

  PERFORM SetInitialStatus

  PERFORM ProcessOneTransaction

  UNTIL GadgetID-TF NOT = CurrentKey

  * CheckFinalStatus

  IF RecordInMaster

  WRITE NewStockRec

  END-IF

  PERFORM ChooseNextKey

  END-PERFORM

  CLOSE MasterStockFile, TransactionFile, NewStockFile

  STOP RUN.

  243

  Chapter 10 ■ proCessing sequential Files

  ChooseNextKey.

  IF GadgetID-TF < GadgetID-MF

  MOVE GadgetID-TF TO CurrentKey

  ELSE

  MOVE GadgetID-MF TO CurrentKey

  END-IF.

  SetInitialStatus.

  IF GadgetID-MF = CurrentKey

  MOVE MasterStockRec TO NewStockRec

  SET RecordInMaster TO TRUE

  PERFORM ReadMasterFile

  ELSE SET RecordNotInMaster TO TRUE

  END-IF.

  ProcessOneTransaction.

  * ApplyTransToMaster

  EVALUATE TRUE

  WHEN Insertion PERFORM ApplyInsertion

  WHEN UpdatePrice PERFORM ApplyPriceChange

  WHEN Deletion PERFORM ApplyDeletion

  WHEN StockAddition PERFORM ApplyAddToStock

  WHEN StockSubtraction PERFORM ApplySubtractFromStock

  END-EVALUATE.

  PERFORM ReadTransFile.

  ApplyInsertion.

  IF RecordInMaster

  SET InsertError TO TRUE

  DISPLAY ErrorMessage

  ELSE

  SET RecordInMaster TO TRUE

  MOVE RecordBody-IR TO NewStockRec

  END-IF.

  ApplyDeletion.

  IF RecordNotInMaster

  SET DeleteError TO TRUE

  DISPLAY ErrorMessage

  ELSE SET RecordNotInMaster TO TRUE

  END-IF.

  ApplyPriceChange.

  IF RecordNotInMaster

  SET PriceUpdateError TO TRUE

  DISPLAY ErrorMessage

  ELSE

  MOVE Price-PCR TO Price-NSF

  END-IF.

  244

  Chapter 10 ■ proCessing sequential Files

  ApplyAddToStock.

  IF RecordNotInMaster

  SET QtyAddError TO TRUE

  DISPLAY ErrorMessage

  ELSE

  ADD QtyToAdd TO QtyInStock-NSF

  END-IF.

  ApplySubtractFromStock.

  IF RecordNotInMaster

  SET QtySubtractError TO TRUE

  DISPLAY ErrorMessage

  ELSE

  IF QtyInStock-NSF < QtyToSubtract

  SET InsufficientStock TO TRUE

  DISPLAY ErrorMessage

  ELSE

  SUBTRACT QtyToSubtract FROM QtyInStock-NSF

  END-IF

  END-IF.

  ReadTransFile.

  READ TransactionFile

  AT END SET EndOfTransFile TO TRUE

  END-READ

  MOVE GadgetID-TF TO PrnGadgetId.

  ReadMasterFile.

  READ MasterStockFile

  AT END SET EndOfMasterFile TO TRUE

  END-READ.

  245

  Chapter 11

  Creating Tabular Data

  This chapter and the next return to the DATA DIVISION to explore more data-declaration concepts. In this chapter, I discuss how to create and manipulate tabular data. I compare and contrast COBOL tables with the arrays used in many other programming languages. Chapter 12 covers more advanced data declaration using the USAGE, REDEFINES, and RENAMES clauses.

  The chapter starts with a discussion of the similarities and differences between arrays and tables. You then see how COBOL tables are declared using the OCCURS clause and manipulated using subscripts. I introduce a

  scenario to explain why tabular data is required and end the scenario with an example program that uses a simple one-dimensional table as part of the solution.

  The middle section of the chapter introduces the concept of group items as table elements and demonstrates this in an example program. Multidimensional tables are then introduced. You learn the best way to depict a multidimensional COBOL table graphically; and I again address the contrast between arrays and tables, which is more pronounced with multidimensional tables. I present an example program using a two-dimensional table as part of its solution and introduce a scenario requiring a three-dimensional table.

  In the chapter’s final section, I show how to create prefilled tables using the REDEFINES clause. You see this demonstrated in an example program that uses a table prefilled with the names of the American states. I also discuss some of the table declaration changes introduced with the ANS 85 standard.

  Tables vs. Arrays

  Most programming languages have a facility to create tabular information. Tabular information consists of multiple occurrences of a homogeneous data item.

  Most programming languages use the term array to describe these multiple-occurrence data items, but COBOL

  uses the term table. This is not just a difference of nomenclature. In most languages (including Basic, Pascal, Java, FORTRAN, and Ada), arrays look and work similarly; but COBOL tables, although they have some similarities to arrays, have a number of minor and major differences.

  Table/Array Definition

  Tables and arrays are so similar that you can use the same definition for them. A table/array may be defined as a contiguous sequence of memory locations that all have the same name and that are uniquely identified by that name and by their position in the sequence. The position index is called a subscript, and the individual components of the table/array are referred to as elements.

  247

  Chapter 11 ■ Creating tabular Data

  Table/Array Differences

  If the same definition can be used for tables and arrays, what is the difference between them? The first difference affects the C language derivatives (C++, Java, and C#). In these languages, arrays start at element 0 and go to the maximum size of the array minus one. This arrangement is a rich source of programming errors for beginner

  programmers who have difficulty coming to grips with this displaced referencing: for instance, element[9] is the tenth element in the array. In COBOL, tables start at element 1 (not 0) and go to the maximum size of the table. In a COBOL

  table, element(9) is the ninth element of the table.

  A major difference between COBOL tables and arrays is that COBOL tables are declared using record

  descriptions. The nature of a record description is that there is a hierarchical relationship between the items in the record. Consequently, one item in a multidimensional table must always be subordinate to another. Arrays have no such hierarchical relationship. An array is simply a matrix of cells that are referenced using row and column subscripts. The hierarchical structuring of COBOL tables allows data-manipulation opportunities that are not available to languages that use arrays.

  Declaring Tables

  Tables are declared using an extension to the PICTURE clause, called the OCCURS clause. The metalanguage for the basic OCCURS clause is as follows:

  OCCURS TableSize#1 TIMES

  To declare a table, you define the type and size of the table element, and then you use the OCCURS clause to specify how many times the element occurs. In the following NFL-Stadium example, the type and size of the element are defined by its subordinate data items. Each element is alphanumeric and 35 characters (30 + 5) in size:

  01 SoccerStadiumName PIC X(25) OCCURS 20 TIMES.

  01 NFL-Stadium OCCURS 31 TIMES.

  02 NFL-StadiumName PIC X(30).

  02 NFL-StadiumCapacity PIC 9(5).

  OCCURS Clause Rules

  Here are the rules for the OCCURS clause:

  • Any data item whose description includes an OCCURS clause must be subscripted when

  referred to. For example:

  DISPLAY SoccerStadiumName(15)

  MOVE NFL-Stadium(12) TO
NFL-Stadium(7)

  • Any data item that is subordinate to a group item whose description contains an OCCURS clause

  must be subscripted when referred to. For example:

  DISPLAY NFL-StadiumName(7)

  DISPLAY NFL-StadiumCapacity(7)

  248

  Chapter 11 ■ Creating tabular Data

  Subscript Rules

  Now let’s look at the subscript rules:

  • A subscript is a bracketed numeric index (or something that evaluates to one) that points to a

  particular element (or part of an element) of the table. The subscript immediately follows the

  element name.

  • The numeric index must be a positive integer, a data name that represents one, or a simple

  expression that evaluates to one.

  • The numeric index is a value between one and the number of elements in the table, inclusive.

  • When more than one subscript is used, they must be separated from one another by commas.

  • One subscript must be specified for each dimension of the table. There must be one subscript

  for a one-dimensional table, two subscripts for a two-dimensional table, and three for a

  three-dimensional table.

  • The first subscript applies to the first OCCURS clause, the second applies to the second OCCURS

  clause, and so on.

  • Subscripts must be enclosed in rounded brackets: ().

  Here are some examples:

  MOVE ZEROS TO StateSalesTotal(35)

  ADD BranchSales TO StateSalesTotal(StateNum)

  ADD BranchSales TO StateSalesTotal(StateNum + 1)

  ADD BranchSales TO StateSalesTotal(StateNum - 2)

  ADD MonthlyBranchSales TO StateSalesTotal(StateNum, MonthNum)

  DISPLAY "Stadium Name is " StadiumName(24)

  DISPLAY "Stadium Capacity is " StadiumCapacity(24)

  Why Use Tabular Data?

  Let’s start this introduction to tabular data by setting up a hypothetical problem. In the course of exploring the problem and a number of variations, I will show how tables are defined and used in COBOL.

  First Specification

  YoreCandyShoppe is a franchise that sells old-time candy at branches all over the United States. A program is required that will sum the candy sales for all the YoreCandyShoppe branches in the country. The sales data is obtained from a sales file containing the candy sales for each branch. The sales file is a sequential file sequenced on ascending BranchId. Each record of the file may be described using the following record description:

 

‹ Prev