0% found this document useful (0 votes)
64 views

Cobol Programming For Business Success

This document provides an introduction to COBOL programming for business success. It covers topics such as the structure of COBOL programs, which include divisions like the identification, environment, data, and procedure divisions. It also discusses data representation in COBOL, including defining data types, valid names, data hierarchy, the PICTURE clause, literals, and data formats. The goal is to help readers understand the basics of writing COBOL programs for business applications.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
64 views

Cobol Programming For Business Success

This document provides an introduction to COBOL programming for business success. It covers topics such as the structure of COBOL programs, which include divisions like the identification, environment, data, and procedure divisions. It also discusses data representation in COBOL, including defining data types, valid names, data hierarchy, the PICTURE clause, literals, and data formats. The goal is to help readers understand the basics of writing COBOL programs for business applications.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 174

COBOL Programming For

Business Success

Información Confidencial | Información Propietaria de GladiusTechnology |


COBOL Programming For Business Success

VERSION FECHA NUM. PAGINAS

1 14/06/2016 175

Versión Fecha Com entario del cam bio

1.00 14/06/2016 Creación documento COBOL programming for business


success

Información Confidencial | Información Propietaria de Gladius Technology | Página 2 de 176


Contenido
Prerequisites .......................................................................................................................................... 9
Audience ................................................................................................................................................. 9
Objectives ............................................................................................................................................... 9
COBOL PROGRAMMING FOR BUSINESS SUCCESS .................................................................... 11

1. Module 1: Introduction to COBOL Programming ............................................................... 11


1.1. Objectives ........................................................................................................................... 11
1.2. What is COBOL? ............................................................................................................... 11
COBOL Maintains Its Edge ................................................................................................ 12
1.3. Writing COBOL Programs ................................................................................................ 13
1.4. The Structure of a COBOL Program .............................................................................. 13
COBOL Program Divisions ................................................................................................. 13
Divisions Can Contain Sections ...................................................................................... 14
Sections Can Contain Paragraphs ................................................................................ 15
Sections and Paragraphs Contain Statements ..................................................... 15
1.5. Summary ............................................................................................................................. 16
2. Module 2: COBOL Programming Structure ........................................................................ 16
2.1. Objectives ........................................................................................................................... 16
2.2. Divisions, Sections, and Statements .............................................................................. 16
2.3. Program Column Layout Rules ....................................................................................... 16
Sequence Number Area ...................................................................................................... 17
Indicator Area .......................................................................................................................... 17
Area A ............................................................................................................................................ 17
Area B ............................................................................................................................................ 18
Identifying Areas .................................................................................................................... 18
2.4. The IDENTIFICATION DIVISION ................................................................................... 19
Optional Comment Entries ................................................................................................ 19
2.5. The ENVIRONMENT DIVISION...................................................................................... 19
2.6. The DATA DIVISION ........................................................................................................ 20
2.7. The PROCEDURE DIVISION.......................................................................................... 21
2.8. Using Periods ..................................................................................................................... 21
2.9. Summary ............................................................................................................................. 22
2.10. Exercise: Creating a Skeleton Program ......................................................................... 22

Información Confidencial | Información Propietaria de Gladius Technology | Página 3 de 176


Introduction .............................................................................................................................. 22
Details ........................................................................................................................................... 22
3. Module 3: Data Representation ............................................................................................ 23
3.1. Objectives ........................................................................................................................... 23
3.2. Defining Data...................................................................................................................... 23
Data Names ................................................................................................................................ 24
Reserved Words ...................................................................................................................... 24
Valid Names ............................................................................................................................... 25
Invalid Names .......................................................................................................................... 25
3.3. Data Hierarchy ................................................................................................................... 25
3.4. The PICTURE Clause ....................................................................................................... 26
3.5. Data Types ......................................................................................................................... 27
Alphabetic Data Fields ......................................................................................................... 27
Alphanumeric Data Fields ................................................................................................. 27
Numeric Data Fields .............................................................................................................. 27
Decimal Values ........................................................................................................................ 28
Negative Numbers ................................................................................................................. 28
Literals .......................................................................................................................................... 28
Invalid Literals ......................................................................................................................... 29
3.6. Applying Data Principles .................................................................................................. 29
3.7. Record Definition Review ................................................................................................. 32
3.8. FILLER, USAGE, VALUE Clause ................................................................................... 32
The USAGE Clause .................................................................................................................. 33
Display Format ......................................................................................................................... 34
Binary Format ........................................................................................................................... 34
Packed Decimal Format ...................................................................................................... 35
The VALUE Clause ....................................................................................................................... 35
Numeric Literals ...................................................................................................................... 35
Figurative Constants ............................................................................................................ 36
3.9. Manipulating Data.............................................................................................................. 38
3.10. The COPY Statement ....................................................................................................... 38
COPYing and REPLACING .................................................................................................. 39
3.11. The REDEFINES Clause ................................................................................................. 40
3.12. Identical Data Names........................................................................................................ 40
3.13. Summary ............................................................................................................................. 41

Información Confidencial | Información Propietaria de Gladius Technology | Página 4 de 176


3.14. Exercise: Defining an Employee Record ....................................................................... 41
Introduction .............................................................................................................................. 41
Details ........................................................................................................................................... 41
4. Module 4: Basic Verbs ........................................................................................................... 43
4.1. Objectives ........................................................................................................................... 43
4.2. Introduction ......................................................................................................................... 43
4.3. Terminating Statements ................................................................................................... 44
4.4. PROCEDURE DIVISION Verbs ...................................................................................... 45
4.5. The DISPLAY Verb ........................................................................................................... 45
4.6. The ACCEPT Verb ............................................................................................................ 46
4.7. The GOBACK Verb ........................................................................................................... 46
4.8. The MOVE Verb ................................................................................................................ 46
Numeric literal MOVE ........................................................................................................... 46
Character literal MOVE ........................................................................................................ 47
Figurative constant MOVE ................................................................................................. 47
Data item MOVE....................................................................................................................... 47
Using MOVE ................................................................................................................................ 47
Sending and Target Field Lengths................................................................................ 48
Padding and Truncating in Various MOVEs............................................................. 48
4.9. The PERFORM Verb ........................................................................................................ 50
The PERFORM Verb and Processing Loops.............................................................. 52
The Verbs PERFORM … UNTIL and GO TO ............................................................... 52
Using PERFORM with Multiple Paragraphs ............................................................. 55
4.10. The GO TO Verb ............................................................................................................... 55
4.11. Mixing PERFORMs and GO TOs ................................................................................... 56
4.12. Summary ............................................................................................................................. 57
4.13. Exercise: Using Verbs ...................................................................................................... 57
Introduction .............................................................................................................................. 57
Details ........................................................................................................................................... 58
5. Module 5: Best Practices ....................................................................................................... 60
5.1. Objectives ........................................................................................................................... 60
5.2. Designing a COBOL Program ......................................................................................... 60
Program Structure Design ................................................................................................ 61
Input and Output Files ........................................................................................................ 64
Program Actions ..................................................................................................................... 65

Información Confidencial | Información Propietaria de Gladius Technology | Página 5 de 176


5.3. Design Analysis ................................................................................................................. 66
5.4. Summary ............................................................................................................................. 69
5.5. Exercise 1: Creating Structure Diagrams ...................................................................... 69
5.6. Exercise 2: Accessing Data ............................................................................................. 70
Introduction .............................................................................................................................. 70
Details ........................................................................................................................................... 70
6. Module 6: Handling Sequential Files ................................................................................... 71
6.1. Objectives ........................................................................................................................... 71
6.2. File Handling ...................................................................................................................... 71
6.3. Files and Records.............................................................................................................. 72
6.4. Connecting Files ................................................................................................................ 72
6.5. Identifying Files .................................................................................................................. 72
Specifying Files are Sequential ...................................................................................... 73
Naming Files .............................................................................................................................. 73
Input and Output Files ........................................................................................................ 73
6.6. Specifying File Layout ....................................................................................................... 74
File Description (FD) Entries ........................................................................................... 75
Record Structures .................................................................................................................. 75
6.7. Accessing Sequential Files .............................................................................................. 75
The OPEN Verb ......................................................................................................................... 76
The CLOSE Verb ....................................................................................................................... 76
The READ Verb ......................................................................................................................... 77
The WRITE Verb ...................................................................................................................... 77
6.8. Putting It All Together ....................................................................................................... 78
6.9. The Full READ Statement ................................................................................................ 80
6.10. READ INTO and WRITE FROM ..................................................................................... 81
6.11. More Examples .................................................................................................................. 81
6.12. Multiple Record Types ...................................................................................................... 83
Input Record ............................................................................................................................. 85
Output Record Types ............................................................................................................ 89
6.13. Summary ............................................................................................................................. 94
6.14. Exercise: Reformatting Data ............................................................................................ 94
Introduction .............................................................................................................................. 94
Details ........................................................................................................................................... 94
7. Module 7: Decision Logic ....................................................................................................... 95

Información Confidencial | Información Propietaria de Gladius Technology | Página 6 de 176


7.1. Objectives ........................................................................................................................... 96
7.2. Decisions in Programs ...................................................................................................... 96
7.3. The IF Statement ............................................................................................................... 96
7.4. Condition Statements........................................................................................................ 97
Types of Data Affect Evaluating Conditions ........................................................... 97
Relational Conditions ........................................................................................................... 97
Class Conditions ...................................................................................................................... 98
Sign Conditions ........................................................................................................................ 99
Condition-name Conditions (Level 88s) ................................................................... 99
Compound Conditions ........................................................................................................ 105
Nested Conditions ................................................................................................................ 105
7.5. The EVALUATE Statement............................................................................................ 106
The Simple EVALUATE Statement............................................................................... 106
The EVALUATE [condition] Statement ..................................................................... 107
The CONTINUE Clause ....................................................................................................... 108
7.6. Using Different Conditions ............................................................................................. 109
7.7. Summary ........................................................................................................................... 114
7.8. Exercise 1: Using the EVALUATE statement ............................................................. 114
Introduction ............................................................................................................................ 114
Details ......................................................................................................................................... 114
7.9. Exercise 2: Evaluating Salaries ..................................................................................... 116
Introduction ............................................................................................................................ 116
Details ......................................................................................................................................... 116
8. Module 8: Data Manipulation............................................................................................... 117
8.1. Objectives ......................................................................................................................... 117
8.2. Manipulating Data............................................................................................................ 117
8.3. The INITIALIZE Verb ...................................................................................................... 118
8.4. Arithmetic Statements ..................................................................................................... 119
The ADD Verb .......................................................................................................................... 120
The SUBTRACT Verb ............................................................................................................ 123
The MULTIPLY Verb ............................................................................................................ 125
The DIVIDE Verb................................................................................................................... 128
ADD, SUBTRACT, MULTIPLY, and DIVIDE Summary ....................................... 131
The COMPUTE Verb .............................................................................................................. 131
The ON SIZE ERROR Clause ........................................................................................... 132

Información Confidencial | Información Propietaria de Gladius Technology | Página 7 de 176


8.5. Verbs for String Handling ............................................................................................... 134
The INSPECT Verb ................................................................................................................ 135
The BEFORE and AFTER Clauses .................................................................................. 136
The STRING Format ............................................................................................................ 139
The UNSTRING Format ...................................................................................................... 143
Reference modification ..................................................................................................... 144
8.6. Using Data Manipulation Verbs ..................................................................................... 146
8.7. Summary ........................................................................................................................... 151
8.8. Exercise: Using Calculations and Accumulations ...................................................... 151
Introduction ............................................................................................................................ 151
Details ......................................................................................................................................... 151
9. Module 9: Handling Repeating Data .................................................................................. 152
9.1. Objectives ......................................................................................................................... 153
9.2. What is Repeating Data? ............................................................................................... 153
9.3. What is a Table? .............................................................................................................. 154
Using Subscripts ................................................................................................................... 155
9.4. Using REDEFINES Clauses in Tables ......................................................................... 158
9.5. Indexed Tables ................................................................................................................ 161
Using the SEARCH VERB ................................................................................................... 162
Using the SET verb with SEARCH ................................................................................ 165
9.6. Multi-dimensional Tables................................................................................................ 168
9.7. Variable Length Tables or Fields .................................................................................. 168
9.8. Using Repeated Data...................................................................................................... 170
9.9. Summary ........................................................................................................................... 174
9.10. Exercise: Using Tables ................................................................................................... 174
Introduction ............................................................................................................................ 174
Details ......................................................................................................................................... 174

Información Confidencial | Información Propietaria de Gladius Technology | Página 8 de 176


INTRODUCTION
This training course teaches you how to design and code COBOL programs. It explains
basic COBOL constructs and continues through to lessons on strategic modular
programming. The course also provides practical tips and best practices used by
experienced COBOL professionals that will help you avoid programming pitfalls.

Prerequisites
To get the maximum value from this course, you should meet the following
prerequisites:
• Basic Windows familiarity
• Some familiarity with the concept of programming
• IMPORTANT! Have the class files.

Audience
The audience for this course includes programming project managers, programmers,
and analysts.

Objectives
Upon successful completion of this course, you will be able to:
• Describe the advantages of programming with COBOL.
• Include the divisions in the correct order within a COBOL program.
• Use verbs in the PROCEDURE DIVISION.
• Include meaningful comments when writing code.
• Design a typical COBOL file-handling program.
• Design and code a typical COBOL program which handles sequential files.
• Write a COBOL program using different types of condition testing.
• Use the various arithmetic COBOL verbs.
• Use the verbs for manipulating character data.
• Describe the role of reference modification.
• Use subscripts and indexes to manipulate tables.
• Write fully functioning print programs.
• Describe the uses of indexed files.

Información Confidencial | Información Propietaria de Gladius Technology | Página 9 de 176


• Write COBOL programs using all modes of access
• Describe modular programming.
• Pass parameters between modules.

Información Confidencial | Información Propietaria de Gladius Technology | Página 10 de


176
COBOL PROGRAMMING
FOR BUSINESS SUCCESS
1. Module 1: Introduction to COBOL
Programming
1.1. Objectives
At the end of this module you will be able to:
• Describe the history and purpose of COBOL as a programming language.
• Explain why COBOL skills and applications will be in demand for many years to
come.
• Describe the basic structure of a COBOL program.

1.2. What is COBOL?


COBOL (Common Business Oriented Language) is one of many high-level computer
programming languages. It was designed to solve common business problems, which
often require collection, processing, and reporting on large quantities of numeric data.
For example, COBOL programs generate payroll information, store and report on
personnel information, and produce profit and loss statements. Other languages are
geared toward solving complex scientific problems that require complex algorithms.
COBOL is best suited for financial and business data processing and reporting.

The purpose of a programming language is to communicate instructions to the


computer. Each type of central processing unit or CPU, understands a particular set of
instructions. Because these instructions appear cryptic and confusing to humans, the
early pioneers of the computer industry developed programming languages. These
languages, which add a layer of comprehension for the programmer and analyst, are
translated into the native instructions of a computer's processor, otherwise known as
machine language. The process of translating the original program, or source code, into
machine language is called compilation. The compiler program translates (or compiles)
the source code, that is, code with instructions that humans can understand, into
machine language.

COBOL is an easy-to-understand language. It uses English-like structures, such as


paragraphs, statements, and verbs. Paragraphs contain statements and statements can
include verbs. It also is a highly structured language, where different types of
statements must be included in specific parts of the program. This structure helps in

Información Confidencial | Información Propietaria de Gladius Technology | Página 11 de


176
the analysis of COBOL programs.

Compared with other programming languages, COBOL results in programs that are
verbose. This dramatically differs with languages such as C, where programs can be
more obscure. COBOL, on the other hand, encourages coding that is easy to read and,
therefore, simple to maintain. Because modern COBOL compilers produce tight,
efficient code, wordiness in a program does not reduce performance. COBOL is one of
the most readable and self-documenting programming languages in use today.

COBOL includes the following features:


• Representation of commercial concepts of files and records, such as employee
name and salary information in personnel records.
• Excellent data definition —data fields customized for each program.
• A wide range of data (numeric and string) manipulation facilities.
• Comprehensive file-handling capabilities, such as methods to open and close
files, store file data, and update file records.
• High-level data processing commands (for example, sort, merge, and table
manipulation commands).
• Conformity to an agreed standard, so that different companies can offer COBOL
programming tools with the same features.
• Support for scientific calculations, such as trigonometric functions, although
COBOL was not designed to solve highly complex scientific problems.

COBOL Maintains Its Edge

COBOL was developed by Rear Admiral Grace Hopper in 1959 as a language that would
be relevant for commercial implementation. It has a long and steady history with
continued developments that make it a viable choice for many applications.

In the past, mainframes processed large quantities of data. Since then, many
companies consider client/server technology for their processing needs. COBOL
supports this technology with its basic business logic remaining sound.

Although COBOL has been enhanced to meet today's computing needs, it remains true
to strict standards as developed by the American National Standards Institute (ANSI).

Both mainframes and desktop computers support COBOL programs. COBOL also
provides database file access, providing another upgrade to its original language
standard.

COBOL can be viewed as the internal combustion engine of the computing community:
it is familiar, perceived as unglamorous, and largely taken for granted. Just like the
internal combustion engine, it is, and will continue to be, a vital part of many of our

Información Confidencial | Información Propietaria de Gladius Technology | Página 12 de


176
society's applications.

1.3. Writing COBOL Programs


Typically, programmers write statements for their COBOL programs using some sort of
editor. This creates a source file.

NOTE: An appendix to this course provides brief introductions to two types of editors,
which you can use to write your programs.

A compiler processes the statements you created in the source file into information
that the computer can execute. The compiler also identifies syntax errors, which are
the equivalent of spelling mistakes in a document. However, logic errors (the
equivalent of using totally the wrong words in a document) pass unnoticed. The
programmer must find and correct these. (Ideally, programs should omit logic errors.)

1.4. The Structure of a COBOL Program


The COBOL program on the next page illustrates some of the major components within
a COBOL program. A COBOL structure uses divisions, sections, paragraphs, and
statements.
• Divisions can contain sections.
• Sections can contain paragraphs.
• Paragraphs can contain one or more statements.

COBOL Program Divisions

A COBOL program includes four divisions. Although some compilers will permit the
omission of some of the divisions, they must appear in the following sequence.
• IDENTIFICATION DIVISION – the first division. Insert statements here that
define the name of the program. Add comments that describe the program's
function.
• ENVIRONMENT DIVISION – the second division. Here, define the particular
system environment under which the program will run.
• DATA DIVISION – the third division. This is where all data is defined. All
programs manipulate data in some way.
• PROCEDURE DIVISION – the final division. Write in this division all the
statements that determine what the program does. Any data items referred to
here must have been already defined in the Data Division.

The following is a stub of a COBOL program. Look for the four divisions; don't worry
about the specifics of the code.

Información Confidencial | Información Propietaria de Gladius Technology | Página 13 de


176
IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE1.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM-370.
OBJECT-COMPUTER. IBM-370.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INFILE ASSIGN "DATA-IN.DAT". (Windows)
SELECT OUTFILE ASSIGN "FILE-OUT.DAT". (Windows)
DATA DIVISION.
FILE SECTION.
FD INFILE.
01 INFILE-REC PIC X(80).
FD OUTFILE.
01 OUTFILE-REC PIC X(132).
WORKING-STORAGE SECTION.
01 WORK-FIELD PIC X(20).
LINKAGE SECTION.
01 LS-FIELD PIC X(30).
PROCEDURE DIVISION USING LS-FIELD
MAINLINE SECTION.
DISPLAY "HELLO WORLD".
GOBACK.

Divisions Can Contain Sections

The four divisions can have these sections.

COBOL Program

Identification Division

Environment Division
Configuration Section
Input-Output Section

Data Division
File Section
Working-Storage Section
Linkage Section
Communication Section
Report Section
Screen Section

Procedure Division
[can have sections, but must have paragraphs]

Look at the sample on the following page and locate the sections within the divisions.
The word "section" appears in its label.

Información Confidencial | Información Propietaria de Gladius Technology | Página 14 de


176
Sections Can Contain Paragraphs

Some sections include paragraphs, which contain multiple statements. Within the
INPUT-OUTPUT SECTION in the following code, a paragraph begins with a paragraph
heading, similar to what you see in this book.

Open x:\class\module1\netx\example1.cbl

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE1.
AUTHOR. TRAINING.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM-370.
OBJECT-COMPUTER. IBM-370.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INFILE ASSIGN "DATA-IN.DAT".
SELECT OUTFILE ASSIGN "FILE-OUT.DAT".
DATA DIVISION.
FILE SECTION.
FD INFILE.
01 INFILE-REC PIC X(80).
FD OUTFILE.
01 OUTFILE-REC PIC X(132).
WORKING-STORAGE SECTION.
01 WORK-FIELD PIC X(20).
LINKAGE SECTION.
01 LS-FIELD PIC X(30).
PROCEDURE DIVISION.
MAINLINE SECTION.
DISPLAY "HELLO WORLD".
GOBACK.

The FILE-CONTROL paragraph describes how the program uses files specified in the
program. In this case, the files are called INFILE and OUTFILE.

Sections and Paragraphs Contain Statements

Lastly, programs include statements and many of them. We could put the following
statements on two lines to identify each statement more easily.
FILE-CONTROL. [Paragraph heading]
SELECT INFILE [Statement]
ASSIGN "DATA-IN.DAT". [Statement]
Mainframe
FILE-CONTROL. [Paragraph heading]
SELECT INFILE [Statement]
ASSIGN UT-INFILE [Statement]

Información Confidencial | Información Propietaria de Gladius Technology | Página 15 de


176
Later, this course reviews a statement in more detail. For now, it is sufficient to know
the elements in a program.

1.5. Summary
In this module we have examined the following topics:

• The history and purpose of COBOL as a programming language.
• The structure of a COBOL program.

2. Module 2: COBOL Programming


Structure
2.1. Objectives
At the end of this module you will be able to:
• Create a basic COBOL program that includes the four divisions and their
sections.
• Explain layout-positioning rules imposed by COBOL.

2.2. Divisions, Sections, and Statements


From the previous module, recall that a COBOL program includes four divisions and
those divisions can contain sections.

This module explores the divisions in more detail and analyzes statements written in
each section. Because divisions and statements must be placed in a specific location,
we must look at COBOL programming layout.

2.3. Program Column Layout Rules


COBOL programs expect statements to be confined to particular columns on an
invisible page of 72-column lines. The following figure shows only 52 of those 72
columns and shows two lines of code.


....+....1....+....2....+....3....+....4....+....5..
PROCEDURE DIVISION.
000-MAIN SECTION.

Notice that the "P" in Procedure Division appears starting at the 8th column. Each 72-

Información Confidencial | Información Propietaria de Gladius Technology | Página 16 de


176
position line represents one line in a COBOL program.

Some columns are reserved for specific items in categories called areas, as listed in the
following graphic.

These layout rules are referred to as the COBOL reference format. Let's inspect each
area.

Sequence Number Area

Columns 1–6 are not typically used. They used to be reserved for line numbering,
referred to as sequence numbering. Line numbers can help identify each line in a
program. If you use sequence numbers, they must be six digits. In the past only the
compiler used these columns. So anything here is ignored. This means that if a COBOL
statement begins, say in column 1, the first six characters of the statement will be
ignored. This will probably reduce the rest of the statement to nonsense.

Indicator Area

Column 7 is a special column, where only certain characters can be inserted. By far the
most common of these is an asterisk ('*'). Placing an asterisk here tells the compiler to
see the whole line as a comment. Because COBOL programs may have a very long life,
insert comments into your code whenever possible (anywhere in the program after the
IDENTIFICATION DIVISION). Comments in the code help ensure that at least some
documentation will be available for years to come.

The comment below starts with an asterisk on position 7.


....+....1....+....2....+....3....+....4....+....5..
* *** THIS IS A COMMENT ***

Area A

Columns 8-11 are known as Area A. All Division names, Section names, and paragraph
headings must start here. Also, all 01 data items, which are discussed later, must start
here. Statements under the headings appear indented, making programs easier to
read.

Información Confidencial | Información Propietaria de Gladius Technology | Página 17 de


176
NOTE: Area A is sometimes referred to as Margin A.

COBOL statements in Area A can begin in position 8, 9, 10 or 11. Again to make


programs easier to read, however, programmers typically begin statements in Area A at
column 8.

Additionally, all Division and Section headings must appear on one line without other
entries and must end with a period.

Paragraph headings must begin in Area A, but can appear on a line with or without
other entries. Although some paragraph headings do not require periods, adding
periods after paragraph headings will never create errors. So, adding the period might
be easier to remember.

Area B

Columns 12-72 are known as Area B. The main body of the program appears here. Also,
all entries that began in Area A, or comments, can continue here.

Similar to Area B, statements can begin anywhere starting position 12 through 72, but
for ease of reading, programmers typically start Area B statements at position 12 and
indent related statements.

NOTE: Area B is sometimes referred to as Margin B.

Statements in Area B end with a period if the statement ends a paragraph or a section.

Identifying Areas

The following code places all the divisions in their correct column layout. The bolded
statements begin in Area A at position 8. All other statements appear in Area B starting
at position 12.

....+....1....+....2....+....3....+....4....+....5..
IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE2.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM-370.
OBJECT-COMPUTER. IBM-370.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INFILE ASSIGN TO "EMPL.DAT".
SELECT OUTFILE ASSIGN TO "EMPLOUT.DAT".

Información Confidencial | Información Propietaria de Gladius Technology | Página 18 de


176

2.4. The IDENTIFICATION DIVISION


Now that we have looked at COBOL program layout and areas, we can continue our
inspection of each division. We'll begin again with the IDENTIFICATION DIVISION.

The IDENTIFICATION division, which is the first and simplest division, does not include
any sections. The IDENTIFICATION SECTION names the program. It can have only one
entry: the PROGRAM-ID.

....+....1....+....2....+....3....+....4....+....5..
IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE3.

PROGRAM-ID starts in column 8 (Area A). The program name often starts in column 40,
although this is not necessary.

Optional Comment Entries

Within the IDENTIFICATION DIVISION you can insert comment-entries with associated
values that provide details about the program, such as the author and date written.
The compiler ignores the values.

If using comment entries, include them in the following order and include periods.

....+....1....+....2....+....3....+....4....+....5..
IDENTIFICATION DIVISION
PROGRAM-ID. EXAMPLE3.
AUTHOR. SALLY ROGERS.
INSTALLATION. MARS.
DATE-WRITTEN. 18th SEPTEMBER.
DATE-COMPILED. 21st OCTOBER.
SECURITY. NONE.

These entries can be very useful for maintenance purposes. Documentation supporting
COBOL programs may become lost over the decades in which they are used. Include
important information directly in the program whenever possible.

2.5. The ENVIRONMENT DIVISION


The second division is used to identify any parts of the program that apply to specific
computer hardware or devices. This section also specifies any data files used in the
program.

Información Confidencial | Información Propietaria de Gladius Technology | Página 19 de


176
This division can contain two sections.

• CONFIGURATION SECTION contains particular entries that define the actual


environment. This section can be omitted if no such entries are necessary.
• INPUT-OUTPUT SECTION is present whenever the program reads from, or writes
to, files. This section is covered in more detail in a later module.

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE4.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INFILE ASSIGN "SYSIN.TXT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS SYSIN-FILE-STATUS.
SELECT OUTFILE ASSIGN "SYSOUT.TXT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS I S SYSOUT-FILE-STATUS.
DATA DIVISION.
FILE SECTION.
FD INFILE.
01 INFILE-REC PIC X(80).
FD OUTFILE.
01 OUTFILE-REC PIC X(132).
WORKING-STORAGE SECTION.
01 WORK-FIELD PIC X(20).
LINKAGE SECTION.
01 LS-FIELD PIC X(20).
[more code]

2.6. The DATA DIVISION


The Data Division describes the data needed by the program. The data can originate
from input sources such as files on disks or data from working areas. The third division
in a COBOL program can contain up to three sections.

• The FILE SECTION always appears when files are accessed in the program.
• The WORKING-STORAGE SECTION contains all data items that the program
needs, for example, counters of how many records have been written or data
resulting from intermediate calculations.
• A LINKAGE SECTION is needed when the program is being called from another
program. In this case data values (called "parameters") are probably being
passed back and forth. These are defined in this section.

This snippet from the previous code shows only the DATA DIVISION.

Información Confidencial | Información Propietaria de Gladius Technology | Página 20 de


176
....+....1....+....2....+....3....+....4....+....5..
DATA DIVISION.
FILE SECTION.
FD INFILE.
01 INFILE-REC PIC X(80).
FD OUTFILE.
01 OUTFILE-REC PIC X(132).
WORKING-STORAGE SECTION.
01 WORK-FIELD PIC X(20).
01 SYSIN-FILE-STATUS PIC X(2).
01 SYSOUT-FILE-STATUS PIC X(2).
LINKAGE SECTION.
01 LS-FIELD PIC X(20).

2.7. The PROCEDURE DIVISION


The last division, the PROCEDURE DIVISION, contains the program's processing
statements and must contain at least one paragraph. This sample shows a MAIN
SECTION and a PROCESSING SECTION. Paragraph headings appear within the sections.

....+....1....+....2....+....3....+....4....+....5..
PROCEDURE DIVISION USING LS-FIELD.
000-MAIN SECTION. [Section
heading]
010-MAIN. [Paragraph heading]
OPEN INPUT INFILE, OUTPUT OUTFILE
PERFORM 110-READ-AND-WRITE 10 TIMES
CLOSE INFILE, OUTFILE
GOBACK
100-PROCESSING SECTION.
110-READ-AND-WRITE.
READ INFILE
AT END GOBACK
END-READ
IF INFILE-REC IS NOT EQUAL TO SPACES THEN
WRITE OUTFILE-REC FROM INFILE-REC
END-IF.
120-END.
EXIT.

NOTE: In most of remaining code samples, exact column layout positions are not
shown due to space limitations.

2.8. Using Periods


The use of periods is important. Each division and section definition must end with a
period (referred to as a "full stop"). Also, terminate each statement within the first
three divisions (IDENTIFICATION, ENVIRONMENT, and DATA) with a period. If you omit
a necessary period, the compiler may notice an error only at the beginning of the next

Información Confidencial | Información Propietaria de Gladius Technology | Página 21 de


176
line, causing a misleading error message to appear. If you ever see an error message
that makes little sense, check missing periods first.

The rules for using periods in the PROCEDURE DIVISION are slightly different, as
discussed in a later module.

2.9. Summary
In this module we have examined the following topics:

• The history and purpose of COBOL as a programming language.


• The structure of a COBOL program.
• The naming and positioning rules imposed by COBOL.

2.10. Exercise: Creating a Skeleton Program


Introduction

In this exercise, create a skeleton COBOL program that includes the 4 divisions and the
sections in each division.

Details

Follow these steps to build and complete a skeleton COBOL program.

1. Start your editor. (open module 2 from x:\class\module2\netx)

2. Enter in the following information insuring that all typed information begins in column 8:

IDENTIFICATION DIVISION.
PROGRAM-ID. PROGRAM2.
AUTHOR. TRAINING.
INSTALLATION. MARS.
DATE-WRITTEN. 18/10/2005.
DATE-COMPILED.
SECURITY. MICROFOCUS
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM-370.
OBJECT-COMPUTER. IBM-370.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
LINKAGE SECTION.

Información Confidencial | Información Propietaria de Gladius Technology | Página 22 de


176
PROCEDURE DIVISION.
MAINLINE SECTION.
DISPLAY "MY NAME IS xxxxxxxx"
GOBACK.

3. Save the program in the X: \CLASS\MODULE2\NETX directory and provide the program name
PROGRAM2.CBL.

3. Module 3: Data Representation


3.1. Objectives
At the end of this module you will be able to:

• Explain the different ways in which data can be defined.


• Define data items in a basic COBOL program.
• Create a stub program showing the Group and Elementary Level data hierarchy.
• Use the COPY statement and the COPY… REPLACING statement.
• Use the REDEFINE clause to redefine data.

3.2. Defining Data


Before you can write COBOL programs, you need to learn about how data is defined
and processed.

Data is defined in the same way in all three sections within the DATA DIVISION.
Instructions using that data are provided in the PROCEDURE DIVISION. Learning about
data definitions applies to both the DATA and PROCEDURE DIVISIONS.

COBOL Program
Identification Division
Environment Division
Configuration Section
Input-Output Section
Data Division
File Section
Working-Storage Section
Linkage Section
Procedure Division
[can have sections, but must have paragraphs]

Data items are fields, for example, a last name or a telephone number. In COBOL, rules
govern how you can define data items. This module looks at how data items are
named, lists names that are reserved and cannot be used to identify your own fields,
and explains how data item characteristics can be defined using the PICTURE clause.

Información Confidencial | Información Propietaria de Gladius Technology | Página 23 de


176
Data Names

The use of long, meaningful names for data items is encouraged in COBOL, which
supports the fact that COBOL is an easy-to-read language.

The following table shows how you can provide COBOL names to data that used
currently.

For… Use the data name…


Employee Last Name Employee-Last-Name
Employee First Name Employee-First-Name
Employee ID Employee-ID
Employee Salary Employee-Salary

Name data items with intuitive names. However, restrictions apply to names you can
define.

• Names must be 1-30 characters.


• Names must include at least one alphabetic character.
• Names cannot include spaces. Replace spaces with hyphens.
• The name cannot start or end with a hyphen.
• Names can consist of the following characters: A-Z, a-z, 0-9, hyphen.
• The name should be unique within the program. (You can use the same name
more than once, if it really necessary; however, try to avoid this.)

Reserved Words

COBOL uses some words for special processing instructions. These words are known as
reserved words. The data item name must not be a reserved word, such as DATA.
COBOL uses the word DATA for itself, so "DATA" cannot be used as a name. However,
you can use a reserved word as part of a larger name. "DATA-GROUP" would be
acceptable.

The following lists some reserved words that cannot be used when naming data fields.

• All Division and Section names and the words "DIVISION" and "SECTION"
• AND, CLOSE, DISPLAY, FILE, INPUT, MOVE, MULTIPLY, NOT, OPEN, OR, PICTURE,
RECORD, SPACE

Note: Online help of your editor provides a complete list of reserved words.

Información Confidencial | Información Propietaria de Gladius Technology | Página 24 de


176
Valid Names

Here are examples of valid user-defined words.

• EMPLOYEE-GENDER – This is a meaningful name for an item.


• WS-VALID-RECORD-COUNT – Here the WS- prefix indicates that the item is in
the WORKING-STORAGE SECTION of the DATA DIVISION. A prefix such as this is
almost universally used.
• BA-INITIAL-ACTIONS – This represents a paragraph in the PROCEDURE DIVISION,
which should contain statements to be executed at the start of the program.

Invalid Names

Here are examples of invalid data names.

• PERSONS_SURNAME – Underlined characters are not allowed.


• INPUT – Reserved words are not allowed as a name. "INPUT" is a reserved
word.

3.3. Data Hierarchy


Defining a field in the DATA DIVISION requires a specific data hierarchy: either at a
Group Level or a subordinate Elementary Level. When describing data, show not only
the size of different data fields, but also how they relate to each other. This is done
through level numbers.

Level numbers (for example, "01" or "03) preceding the data name represent the
hierarchy of the data. The following example shows the EMPLOYEE-NAME in the higher
Group Level with the three EMPLOYEE Elementary Level data fields indented below it.

01 EMPLOYEE-NAME. [Group Level]


03 EMPLOYEE-TITLE PIC X(3).
03 EMPLOYEE-INITIALS PIC X(4).
03 EMPLOYEE-SURNAME PIC X(30).

We could have numbered the Elementary Level fields with "02" rather than "03." Using
a numbering scheme that skips numbers is highly recommended. Also, although
indenting is not required, it makes the program easier to read.

Actually EMPLOYEE-NAME is the name of a record that includes three data fields. A
record is group of associated fields.

The 01 level must be positioned in Area A (positions 8–11). The record's data fields
must be coded in Area B (positions 12–72) and be followed by a period.

Información Confidencial | Información Propietaria de Gladius Technology | Página 25 de


176
You can use many levels, each indented within another as shown next.

....+....1....+....2....+....3....+....4....+....5..
01 EMPLOYEE-RECORD.
03 EMPLOYEE-NAME.
05 EMPLOYEE-TITLE PIC X(3).
05 EMPLOYEE-INITIALS PIC X(4).
05 EMPLOYEE-SURNAME PIC X(30).
03 EMPLOYEE-GENDER PIC X.
03 EMPLOYEE-ADDRESS.

There are many ways to define records; the definition depends on the results needed.
In the following example, someone has presumably decided that there is no need to
access the parts of the name individually. So, they have been defined as just one field.

....+....1....+....2....+....3....+....4....+....5..
01 EMPLOYEE-RECORD.
03 EMPLOYEE-PERSONAL-DETAILS.
05 EMPLOYEE-FULL-NAME PIC X(37).
05 EMPLOYEE-GENDER PIC X.
03 EMPLOYEE-ADDRESS.

A new Group field (EMPLOYEE-PERSONAL-DETAILS) is defined, which allows the


programmer to pick up the whole name and gender in one go.

3.4. The PICTURE Clause


COBOL provides a method of specifying the characteristics of data items. Data items
referenced as Elementary Level items use the PICTURE clause to specify their
characteristics. PICTURE is abbreviated as PIC.

PICTURE clauses are very closely related to the concepts of data hierarchy as PICTURE
clauses are used only with Elementary Level items (preceded below with "03").

Again, due to space constraints, the following code and much of the code for the
remainder of the manual is not placed in its true column.

01 EMPLOYEE-NAME. [Group Level]


03 EMPLOYEE-TITLE PIC X(3) [Elementary Level]
03 EMPLOYEE-INITIALS PIC X(4) [Elementary Level]
03 EMPLOYEE-SURNAME PIC X(30) [Elementary Level]

The PICTURE clause provides information about the type of data stored and the size of
the storage area for the item.

PIC X(3) The X represents alphanumeric data.

PIC A(3) The A represents alphabetic data.

Información Confidencial | Información Propietaria de Gladius Technology | Página 26 de


176
The "3" represents the number of characters in the storage area.

Do not embed any spaces in PIC clause definitions. These are invalid: PIC X( 77) or PIC X
(77).

3.5. Data Types


Let's look at how these types of data are represented in PICTURE clauses.

• Alphabetic fields (rarely used)


• Alphanumeric fields
• Numeric fields
• Literals (both numeric and alphanumeric)

The following PIC clauses illustrate the data types.

03 DATA-FIELD1 PIC A(3). [Alphabetic]


03 DATA-FIELD2 PIC X(3). [Alphanumeric]
03 DATA-FIELD3 PIC 9(3). [Numeric]
03 DATA-FIELD4 PIC X(6) Value "Hello " [Literal]

Alphabetic Data Fields

Use the PIC A syntax to identify a field as alphabetic. You could use format 1 or format
2.

Format 1

03 DATA-FIELD1 PIC A(3).

Format 2

03 DATA-FIELD1 PIC AAA.

In Format 2 each of the three As identifies the storage for one character. The 3 in the
first format is merely another way to write this. PIC A is rarely used.

Alphanumeric Data Fields

Fields containing letters, numbers, and spaces are identified by PIC (X).

03 DATA-FIELD2 PIC X(3).

Numeric Data Fields

Información Confidencial | Información Propietaria de Gladius Technology | Página 27 de


176
Define a field containing all numbers along with optional + or – sign as numeric data by
using the PIC 9999 clause. Each 9 represents one digit.

03 DATA-FIELD3 PIC 9999.

Alternatively, use the PIC 9(4) format, where the 4 represents the number of digits.

03 DATA-FIELD3 PIC 9(4).

Numeric fields can be up to 18 digits long.

Always make the definitions for numeric fields large enough to accommodate any
possible number. If a field needs to hold 1 million, many programmers will at first
define this in a PIC 9(6) field. Such a fields will hold 999,999 with ease. However, adding
one sets the field to zero, as the leading '1' is lost to the left – probably not what is
needed.

Decimal Values

In the PICTURE clause, a V represents the decimal point.

03 EMPLOYEE-SALARY PIC 9(5)V99.

Each 9 after the V represents a digit after the decimal point. So, an EMPLOYEE-SALARY
would appear as $50000.00, two digits after the decimal point. Alternatively, you could
write this as shown next.

03 EMPLOYEE-SALARY PIC 9(5)V9(2).

Negative Numbers

The notation of 9(5)V99 allows only for zero or positive values. However, if we needed
to allow for negative numbers, for example, for a customer's account balance, we
would say something like the following.

03 CUSTOMER-BALANCE PIC S9(5)V99.

S stands for 'signed'. The sign is stored on the data item itself and does not take an
extra byte.

Literals

Información Confidencial | Información Propietaria de Gladius Technology | Página 28 de


176
Literals are data items that have specific values, either numeric values (for example, 53
or 2) or alphanumeric values (for example, "Hello"). Literals represent the actual data
rather than the name of the data.

03 DATA-FIELD4 PIC X(6) Value "Hello ".


03 AMOUNT-Field PIC 9(4) Value 5678.

The following rules apply to using numeric literals in COBOL programs.

• Numeric literals must be 1–18 characters.


• A + or – sign can be included, but only at the left.
• A decimal can be included, but not at the end of the literal.
• Literals cannot include special characters, such as a comma or $.

The following rules apply to using alphanumeric literals in COBOL programs.

• Alphanumeric literals can contain up to 268,434,912 characters.


• Surround the literal with either single or double quotation marks (for example,
"USA").

Invalid Literals

Here are examples of invalid literals.

Numeric literals… Alphanumeric literals…


563. USA
$563 Enter your choice"
563,300 "Sunnyvale Street

3.6. Applying Data Principles


Now, we'll look at an example and identify the PIC clauses, data storage, and data
hierarchy. Let's say an employee record needs to hold the following information about
a person.

• Title (3 characters or bytes)


• Initials (4 bytes)
• Surname (30 bytes)
• Gender (1 byte)

Información Confidencial | Información Propietaria de Gladius Technology | Página 29 de


176
• Address and ZIP or postal code (4 lots of 30 bytes, plus say another 8 bytes)
• Salary (up to 5 bytes for numbers before the decimal point and 2 after)

Once you define this in a COBOL program, you can access the information in the
following ways.

• Access any field individually.


• Access the whole name as one unit.
• Access the whole address as one unit.
• Access the whole record as one unit.

Because COBOL programs commonly read input records and write output records, this
sort of record hierarchy makes sense.

Using this example, we could write the following code in Working-Storage Section in
the DATA DIVISION.

..1....+....2....+....3....+....4....+....5....+
DATA DIVISION
FILE SECTION.
[more code]
WORKING-STORAGE SECTION.
01 EMPLOYEE-RECORD.
03 EMPLOYEE-NAME.
05 EMPLOYEE-TITLE PIC X(3)
05 EMPLOYEE-INITIALS PIC X(4)
05 EMPLOYEE-SURNAME PIC X(30)
03 EMPLOYEE-GENDER PIC X.
03 EMPLOYEE-ADDRESS.
05 EMPLOYEE-ADDRESS-1 PIC X(30)
05 EMPLOYEE-ADDRESS-2 PIC X(30)
05 EMPLOYEE-ADDRESS-3 PIC X(30)
05 EMPLOYEE-ADDRESS-4 PIC X(30)
05 EMPLOYEE-ZIP-POSTAL-CODE PIC X(8)
03 EMPLOYEE-SALARY PIC 9(5)V99.

Let's look at these entries one by one, and see what they mean.

Line 1

Firstly, EMPLOYEE-RECORD is the name given to the definition of the record as a whole.
Because it's at the top level, it has a level number of 01. It will appear in Area A of the
Data Division, meaning that the first character will be in column 8. This line is a Group
Level field, made up of lower-level items. Since it is not at the Elementary level, it does
not include a PIC clause.

Line 2

Información Confidencial | Información Propietaria de Gladius Technology | Página 30 de


176
The next line shows EMPLOYEE-NAME. Again this is a Group field; it has subordinate
entries. EMPLOYEE-NAME appears as level 03. The numbers represent the hierarchy in
the record. Here EMPLOYEE-NAME is at the same level as EMPLOYEE-ADDRESS and
EMPLOYEE-SALARY, all one level down from the record itself.

Rather than 03, we could have said 02 or 05, as long as the hierarchy logic is
maintained. Using odd-numbered levels allows us to insert extra levels later during
maintenance. In practice, however, this is rarely done. The programmer is more likely
to code the whole record again.

Lines 3 – 5

In the next line, we reach an elementary item, EMPLOYEE-TITLE, which is three


characters long.

05 EMPLOYEE-TITLE PIC X(3).

The X in PIC X indicates that any alphanumeric character can be used. To specify that
only alphabetic characters be used, we could have said
PIC A(3). However, PIC A is rarely used.

The next three lines show more Elementary Level items. Notice that PIC X is used for
EMPLOYEE-GENDER. PIC X(1) could be used instead.

Lines 7 –12

Next, we go up a level to 03 EMPLOYEE-ADDRESS. This Group field consists of four


address lines and a ZIP or postal code. Each has its own name and PIC clause showing
its size. (Another way of showing repeating items such as these address lines is to
declare them as OCCURS fields. This is discussed in another module.)

Line 13

Finally comes EMPLOYEE-SALARY.

03 EMPLOYEE-SALARY PIC 9(5)V99.

Note first that this is a 03 level, even though it is also an Elementary level. This is
because it doesn't belong within the NAME or ADDRESS groups, so it is logically shown
as being one level below the record itself.

Its PICture is 9(5)V99, that is, a field capable of holding up to 99999, then a virtual
decimal point (hence the V), and two decimal places (the 99). The decimal point is
virtual in that it does not take up any space. If you looked at the field as it is stored, you
would see only seven digits even though the program "knows" to take the decimal
point into account.

Información Confidencial | Información Propietaria de Gladius Technology | Página 31 de


176
The notation of 9(5)V99 could have been written as 99999V99, 9(5)V9(2), or
99999V9(2). However the one used is the most common, probably because it is the
easiest to read.

3.7. Record Definition Review


Let's now look at whether this definition meets the criteria we mentioned earlier. Here
is the employee record again.

01 EMPLOYEE-RECORD.
03 EMPLOYEE-NAME.
05 EMPLOYEE-TITLE PIC X(3).
05 EMPLOYEE-INITIALS PIC X(4).
05 EMPLOYEE-SURNAME PIC X(30).
03 EMPLOYEE-GENDER PIC X.
03 EMPLOYEE-ADDRESS.
05 EMPLOYEE-ADDRESS-1 PIC X(30).
05 EMPLOYEE-ADDRESS-2 PIC X(30).
05 EMPLOYEE-ADDRESS-3 PIC X(30).
05 EMPLOYEE-ADDRESS-4 PIC X(30).
05 EMPLOYEE-ZIP-POSTAL-CODE PIC X(8).
03 EMPLOYEE-SALARY PIC 9(5)V99.

• Can we access any field individually? Yes, because all Elementary fields (those
with a PIC clause defining its size) have individual names.
• Can we access the whole name as one unit? Yes, because it is a Group field,
called EMPLOYEE-NAME.
• Can we access the whole address as one unit? Yes, because it is named
EMPLOYEE-ADDRESS.
• Can we access the whole record as one unit? Yes, because it is the 01 level,
EMPLOYEE-RECORD itself.

3.8. FILLER, USAGE, VALUE Clause


Maybe you are interested only in parts of a Group Level data item. Looking at our
employee record again, let's say that we have to write a program that examines only
the one-byte field containing the GENDER value, and we are not interested in any of
the preceding or following fields.

However, as this is at byte 38 — the previous data fields were defined as PIC X(3), PIC
X(4), and PIC X(30) — the structure below is incorrect. This will be pointing at byte 1 of
the group field, not byte 38.

01 EMPLOYEE-RECORD.
03 EMPLOYEE-GENDER PIC X(01).

Información Confidencial | Información Propietaria de Gladius Technology | Página 32 de


176
Since for this case we are not interested in those first 37 bytes, we can use a FILLER as
shown next.

01 EMPLOYEE-RECORD.
03 FILLER PIC X(37).
03 EMPLOYEE-GENDER PIC X(01).
03 FILLER PIC X(135).

Use a FILLER clause to show that data is present, but you have no interest in accessing
it. FILLER clauses can be found in almost every program.

Instead of saying FILLER, you can omit the name of the data item, as shown next. This is
treated in exactly the same way by the compiler.

01 EMPLOYEE-RECORD.
03 PIC X(37).
03 EMPLOYEE-GENDER PIC X(01).
03 PIC X(135).

The USAGE Clause

Previously, we have defined data characteristics using the PICTURE clause. Next we
look at ways to indicate different storage methods when defining data items. This is
done with the USAGE clause. The USAGE clause tells the computer how to represent
numbers internally. Here are some USAGE clauses:

03 FIELD1 PIC 9(4).


03 FIELD2 PIC 9(4) COMP.
03 FIELD3 PIC 9(4) COMP-3.
03 FIELD4 PIC 9(4) COMP-5.

NOTE: A clause — PIC 9(4) — is part of a statement. This is similar to English where a
clause is part of a sentence.

By default when usage is not specified, numeric data is held in the format we have seen
previously, as shown in the following example.

01 RECORD-COUNTER PIC 9(4).

This is known as USAGE Display. The number is stored as one digit per byte, in just the
same way as an alphanumeric (PIC X) or alphabetic (PIC A) field. Such fields work
perfectly well, in that you can carry out any arithmetical operations on them that you
wish.

Yet, other methods of storing numeric data are more efficient (the calculations take
place more rapidly) and the data takes up less room. Programmers tend to use such
data types for internal data items (ones say in WORKING-STORAGE) or on records
where space is a priority.

Información Confidencial | Información Propietaria de Gladius Technology | Página 33 de


176
Let us look at four ways in which a data item that needs to hold up to 9,999 can be
stored.

• Usage Display Format – PIC 9(4)


• Usage Binary Format – PIC 9(4) COMP
• Usage Packed Decimal Format – PIC 9(4) COMP-3
• Usage Computational or COMP – PIC 9 COMP

Display Format

The first of these methods (Usage Display) allocates one byte per digit, which is what
we are familiar with. If the number contained "1234", it would be stored like this.

00110001 00110010 00110011 00110100 in binary


31 32 33 34 in hex

Binary Format

The Binary Format method allocates the actual number of bits needed to hold the
maximum number (9,999) and then rounds that up to the next byte. So, 9999 (binary
10011010101011) can be held in 14 bits and would occupy 2 bytes (16 bits). The
number "1234" would be stored as shown in the following.

10011010010 in binary
4D2 in hex

Storing data in binary numeric fields is the most efficient. However, there is a tradeoff
for gaining efficiency in this way. It is more difficult to know how much space a COMP
numeric field requires, for example, if the field is in a record. The following table lists
the space required for various COMP fields on the PC not mainframe.

COMP Numeric Field… Space Required…


PIC 9 or PIC 99 COMP 1 byte
PIC 999 or PIC 9(4) COMP 2 bytes
PIC 9(5) or PIC 9(6) COMP 3 bytes
PIC 9(7), PIC 9(8) or PIC 9(9) COMP 4 bytes
PIC 9(10) or PIC 9(11) COMP 5 bytes
PIC 9(12) , PIC 9(13) or PIC 9(14) COMP 6 bytes
PIC 9(15) or PIC 9(16) COMP 7 bytes
PIC 9(17) or PIC 9(18) COMP 8 bytes

Información Confidencial | Información Propietaria de Gladius Technology | Página 34 de


176
Signed fields are exactly the same size (the number is held in two's complement
format). A decimal number is stored according to its total number of digits, for example
a PIC 9(6)v9(4) will fit in 5 bytes.

Packed Decimal Format

The third method (Packed-Decimal Format) is in some ways a hybrid between the first
two. The number is stored or packed more compactly than in display format, and it can
be accessed with most of the extra efficiency of a binary field, yet it is still possible to
see its value if you look at the field's hex representation. The space allocated is one half
byte for each digit and one half byte for the sign (whether the field is signed or not). If
necessary, the number of bytes is then rounded up to the next whole number.

An example will make things clearer. A data item to hold 9(4) COMP-3 will consist of
two and a half bytes – four half bytes for the digits and half a byte for the sign. The two
and a half is then rounded up to three bytes. The number '1234' would be stored as
follows.

00000001 00100011 01101111 in binary


01 23 4F in hexadecimal

In the example above note the 'F' for the sign. If a number is unsigned, as here, then
this last half byte will always be hex F (binary 1111). If the number is signed, then the
last half byte will be one of the following:

• If the number is positive, hex C (binary 1100) with the "C" representing
"Credit.")
• If the number is negative, hex D (binary 1101) with the "D" representing
"Debit."

To calculate the length of a COMP-3 field, divide the number of digits (PIC 9s) by 2, and
then round up to the next whole byte if necessary.

The VALUE Clause

It is often useful to be able to preset the value of one or more data items, so that these
values are in place before any code in the PROCEDURE DIVISION is executed. This is
done with the VALUE clause along with literals or constants.

Numeric Literals

Let's look at a couple of examples.

Información Confidencial | Información Propietaria de Gladius Technology | Página 35 de


176
01 WS-ITEMS.
03 WS-NAME PIC X(20) VALUE "SMITH".
03 WS-SALARY PIC 9(6)V99 VALUE 27500.

The values shown in lines two and three are known as numeric literals. In the case of
PIC X or PIC A fields, the values must be enclosed in quotes. In the above example, WS-
NAME will now contain "SMITH" followed by fifteen spaces. WS-SALARY will contain
027500.00. In other words, if the value of the literal does not fill up the field, then
character fields are padded with spaces on the right and numeric fields padded with
zeros on the left.

Entering too large a value into a field (for example, giving WS-NAME a value of
"General Dwight D Eisenhower") causes the COBOL compiler to identify an error.

Also, use a numeric literal that matches the PICture of the item. Since WS-SALARY is
defined as PIC 9(6)V99, (the first 9 indicating a numeric data type), it would be wrong
to assign SALARY a VALUE of "NONE" (which is an alphabetic value).

Figurative Constants

In addition to numeric literals, you can use VALUE clauses with figurative constants.
Figurative constants preset data items to useful values. The following figurative
constants are available.

• SPACE or SPACES (which mean the same thing)


• ZERO or ZEROS (which mean the same thing)
• LOW-VALUES
• HIGH-VALUES
• ALL "literal"

The SPACES Figurative Constant

SPACES, the easiest figurative constant to understand, is designed for use on


alphanumeric or alphabetic fields. Ensure that such fields are cleared out before any
data manipulation takes place. The following clause includes the SPACES figurative
constant.

03 WS-NAME PIC X(20) VALUE SPACES.

The next example illustrates a more problematic use of SPACES.

01 WS-RECORD.
03 WS-NAME PIC X(20).
03 WS-ADDRESS PIC X(100).
03 WS-SALARY PIC 9(5)V99.

Información Confidencial | Información Propietaria de Gladius Technology | Página 36 de


176
MOVE SPACES TO WS-RECORD or INITIALIZE WS-RECORD

Group fields are always regarded as being alphanumeric (even if all the Elementary
Level fields are numeric). In this case, WS-SALARY will end up set to spaces, which
might not be appropriate.

The ZERO Figurative Constant

ZERO (or ZEROES) can be similarly thought-provoking. ZERO will put that value in the
field or fields referred to by the VALUE clause and format it using the PICture
information.

The following clause will move "character zero" (hex 30) into each of the bytes of WS-
NUMBER.

03 WS-NUMBER PIC 9(4) VALUE ZERO.

Another example will result in binary zero (hex 00) throughout the two bytes of the
field, as shown next

03 WS-BIN-NUMBER PIC 9(4) COMP VALUE ZERO.

This results in a nasty little trap that is very easy to fall into.

In the following sample, the programmer is trying to set all four items in the group to
zero. Instead, ZERO gets moved to the group. Because the group is alphanumeric, hex
30 is moved to each of the eight bytes, setting all the items to 2336! (hex 3030). Note:
Each field defined in the example as PIC 9(4) COMP is stored as 2 bytes.

01 WS-NUMBERS.
03 WS-NUM-1 PIC 9(4) COMP.
03 WS-NUM-2 PIC 9(4) COMP.
03 WS-NUM-3 PIC 9(4) COMP.
03 WS-NUM-4 PIC 9(4) COMP.

MOVE ZERO TO WS-NUMBERS

The LOW-VALUES Figurative Constant

To avoid the previous dilemma, use the LOW-Values figurative constant, which sets a
field to its lowest possible value. Preset the group to "binary zero." The following
example shows the correct way of achieving the goal.

01 WS-GROUP.
03 WS-NUM-1 PIC 9(4).
03 WS-NUM-2 PIC 9(4).
03 WS-NUM-3 PIC 9(4).
03 WS-NUM-4 PIC 9(4).

Información Confidencial | Información Propietaria de Gladius Technology | Página 37 de


176
MOVE LOW-VALUES TO WS-GROUP or INITIALZIE WS-GROUP

Use LOW-VALUES to set a field or field to its lowest possible value. HIGH-VALUES is the
opposite. HIGH VALUES moves hex FF to every byte of the field or fields in question.

The ALL "literal" presets a field with a character value, as shown in the following
example.

03 WS-STARS PIC X(30) VALUE ALL "*".


03 WS-LINE PIC X(80) VALUE ALL "_".

Important note: Use the VALUE clause as shown above only in the Working-Storage
Section.

3.9. Manipulating Data


Now that we've defined data and its characteristics and reviewed data hierarchy, we
can look at ways to manipulate data using these methods:

• COPY data
• COPY and REPLACE data
• REDEFINE data

Let's look at each method.

3.10. The COPY Statement


What happens when a definition of data needs to be used in more than one — even
many — programs? Record layouts, for example, may be very complex and several
hundreds of lines long. Is it wise to repeat them?

Sometimes working storage items should be common across different programs. How
do you handle these items?

Rather than repeat the definition in each case, use the COPY statement.

Let's look at an example where all programs in a payroll suite need the following same
definitions for working storage counters.

01 WS-COUNTERS.
03 WS-NUMBER-OF-EMPLOYEES PIC 9(4).
03 WS-TOTAL-SALARY PIC 9(8)V99.
03 WS-TOTAL-TAX PIC 9(7)V99.
03 WS-TOTAL-DEDUCTIONS PIC 9(6)V99.

Información Confidencial | Información Propietaria de Gladius Technology | Página 38 de


176
When code needs to be shared in this way, the best solution is to write the relevant
lines into a copyfile, that is, a text file that can be automatically copied into the
program.

In the following example, the file was saved as counters.cpy. The COPY statement is
typically inserted in Area A, though it is also valid in Area B.

COPY "COUNTERS.CPY". (Windows and Unix)


COPY COUNTERS. (Mainframe)

PROCEDURE DIVISION.
This results in the following code.

COPY "COUNTERS.CPY".
01 WS-COUNTERS .
03 WS-NUMBER-OF-EMPLOYEES PIC 9(4).
03 WS-TOTAL-SALARY PIC 9(8)V99.
03 WS-TOTAL-TAX PIC 9(7)V99.
03 WS-TOTAL-DEDUCTIONS PIC 9(6)V99.
PROCEDURE DIVISION.

Sometimes full stops (periods) are absolutely necessary. The full stop at the end of a
COPY statement must never be omitted. In the above example, such an omission would
cause the compiler to be unable to find the Procedure Division.

COPYing and REPLACING

You can create a "generic" copy file, where the actual names of the data items can be
modified to suit the particular program (rather than having to use the names in the
copy file). This is done using tags. The copy file can then be imported into a program,
and the (TAG) element can be replaced with another value.

First, we set up a copy file as follows. We named it the "ws.cpy" file.

01 (TAG)-NUMBERS .
03 (TAG)-NUM-1 PIC 9(4).
03 (TAG)-NUM-2 PIC 9(6).
03 (TAG)-NUM-3 PIC 9(5).

In the example below, the file is imported twice.

COPY "WS.CPY"
REPLACING ==(TAG)== BY ==WS01==.
COPY "WS.CPY"
REPLACING ==(TAG)== BY ==WS02==.

This makes the following data items available.

01 WS01-NUMBERS.
03 WS01-NUM-1 PIC 9(4).

Información Confidencial | Información Propietaria de Gladius Technology | Página 39 de


176
03 WS01-NUM-2 PIC 9(6).
03 WS01-NUM-3 PIC 9(5).
01 WS02-NUMBERS.
03 WS02-NUM-1 PIC 9(4).
03 WS02-NUM-2 PIC 9(6).
03 WS02-NUM-3 PIC 9(5).

Copyfiles are commonly used to hold data hierarchies, such as records. They can also
be used to hold executing code, that is, statements that are found in the Procedure
Division (discussed in the Procedure Division module later).

3.11. The REDEFINES Clause


The REDEFINES clause gives you a way to manipulate data very flexibly. It allows you to
specify a different PICTURE clause for a data item defined previously.

Let's say that we have a group of items in Working-Storage, perhaps copied in from a
record that was read. One of those fields is normally a numeric birthdate. However, if
the birthdate is not known, the field needs to be alphanumeric, so that it can contain
some other value, as shown in the following code.

01 WS-RECORD.
03 WS-NAME PIC X(30).
03 WS-DOB PIC 9(8).
03 WS-DOB-XX REDEFINES WS-DOB
PIC X(8).

The redefining item must immediately follow the one being redefined. Redefine items
at any level (except 01 in the File Section, as we shall see later). A redefined item can
have a VALUE clause, but the redefining clause cannot.

3.12. Identical Data Names


It has been suggested that data names should be unique, and indeed this is very often
easy to achieve. Sometimes identical names can be used, as shown in the following
example.

01 WS-INPUT-AREA-1.
03 EMPLOYEE-NAME PIC X(20).
03 EMPLOYEE-ADDRESS PIC X(60).
03 EMPLOYEE-SALARY PIC 9(6)V99.
(and so on)
01 WS-INPUT-AREA-2.
03 EMPLOYEE-NAME PIC X(20).
03 EMPLOYEE-DOB PIC 9(8).

The COBOL compiler tolerates any number of identically-named fields, until it has to
distinguish between them. For example, the following statement from the Procedure
Division will be flagged as an error.

Información Confidencial | Información Propietaria de Gladius Technology | Página 40 de


176
MOVE "VLAD THE IMPALER" TO EMPLOYEE-NAME.

To anticipate a later portion of this course, the MOVE statement moves a value ("VLAD
THE IMPALER") to a data item (EMPLOYEE-NAME). Here the compiler cannot complete
the MOVE, as the data name is not unique. The solution is to qualify the data name,
making it unique, as shown by the addition of "WS-INPUT-AREA-2."

MOVE "VLAD THE IMPALER"


TO EMPLOYEE-NAME OF WS-INPUT-AREA-2.

3.13. Summary
In this module we have examined the following topics:

• Data definitions and reserved words


• Data hierarchy in Group and Elementary Levels and the use of digits preceding
the statement to indicate the level
• Methods of defining data characteristics using the PICTURE clause
• Data types including numeric, alphanumeric, and literals
• Other ways to represent data with the USAGE clause
• Methods to assign values to data with the VALUE clause
• Ways to manipulate data, using the COPY statement, the COPY REPLACING
statement, and the REDEFINES clause
• The different ways in which data can be defined

3.14. Exercise: Defining an Employee Record


Introduction

In this exercise, a description will be added to the skeleton program of an input


employee record that contains an employee number, name, salary, and leaving date for
this employee.

Details

Follow these steps to define the employee record.

Información Confidencial | Información Propietaria de Gladius Technology | Página 41 de


176
1. Start your editor.

2. Open PROGRAM3 located in X:\CLASS\MODULE3\NETX In the WORKING-STORAGE SECTION enter

01 EMPLOYEE-REC-N as the top-level data name for the record to be defined.

3. At the elementary level, code in the following:

Define this
Using this value…
field…
EMPLOYEE-TYPE 1 alphanumeric digits
EMPLOYEE-NAME 20 alphanumeric digits
7 numeric digits 2 of which are
EMPLOYEE-SALARY
decimals
EMPLOYEE-NO 6 numeric digits

4. On the next 03 level, create a group name of EMPLOYEE-LEAVING-DATE to include the following

fields:

Define this field… Using this value…


EMPLOYEE-LEAVE-YEAR 4 numeric digits
EMPLOYEE-LEAVE-MONTH 2 numeric digits
2 numeric digits
EMPLOYEE-LEAVE-DAY

5. Add the following code to Procedure Division.

MAINLINE SECTION.
MOVE SPACES TO EMPLOYEE-REC-N.
DISPLAY EMPLOYEE-REC-N
MOVE ZEROS TO EMPLOYEE-REC-N.
DISPLAY EMPLOYEE-REC-N.
MOVE LOW-VALUES TO EMPLOYEE-REC-N.
DISPLAY EMPLOYEE-REC-N.
MOVE HIGH-VALUES TO EMPLOYEE-REC-N.
DISPLAY EMPLOYEE-REC-N.
MOVE ALL "A" TO EMPLOYEE-REC-N.
DISPLAY EMPLOYEE-REC-N.
GOBACK.

6. Save the program in the X:\CLASS\MODULE3\NETX directory and provide the program name

PROGRAM3.CBL

Información Confidencial | Información Propietaria de Gladius Technology | Página 42 de


176
7. Create a copybook for the employee-rec-n and copy book with copy replacing statement.

8. Compile and Test the program.

4. Module 4: Basic Verbs


4.1. Objectives
At the end of this module you will be able to:

• Explain the DISPLAY, ACCEPT, STOP, MOVE, and PERFORM verbs used in the
PROCEDURE DIVISION.
• Describe how the verbs PERFORM … IF, PERFORM … UNTIL, and GO TO can be
used to direct program logic.
• Write a basic COBOL program using a combination of verbs.

4.2. Introduction
Recall that the PROCEDURE DIVISION is the final division. It is the place where all the
code is written. The PROCEDURE DIVISION heading should start in Area A (columns 8-
11). Code written in this division should be contained in paragraphs, each of which
again starts in Area A. Typically paragraphs should appear in a SECTION.

This module discusses verbs that are used within the PROCEDURE DIVISION.

The following code provides a complete (though very simple) program and shows the

PROCEDURE DIVISION.

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE41.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM-370.
OBJECT-COMPUTER. IBM-370.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
DATA DIVISION.
WORKING-STORAGE SECTION .
01 WS-MESSAGE PIC X(20).
01 WS-NAME PIC X(20).
PROCEDURE DIVISION .
MAINLINE SECTION.
THE-ONLY-PARAGRAPH .
MOVE "HELLO WORLD" TO WS-MESSAGE .

Información Confidencial | Información Propietaria de Gladius Technology | Página 43 de


176
DISPLAY WS-MESSAGE .
DISPLAY "Please enter your name:" .
ACCEPT WS-NAME .
DISPLAY "Nice to meet you, " WS-NAME .
MOVE "That's all, folks" TO WS-MESSAGE .
DISPLAY WS-MESSAGE .
GOBACK .

The PROCEDURE DIVISION contains statements that are executed one by one (with
exceptions that we shall see later).

This program, when run, produces the following results.

HELLO WORLD
Please enter your name:
Hiram Holliday
Nice to meet you, Hiram Holliday
That's all, folks

4.3. Terminating Statements


In all the sample code we have seen, each COBOL statement ended with a period (full
stop). This is often unnecessary for statements in the PROCEDURE DIVISION, and it may
be difficult to decide whether a statement needs to be explicitly terminated. However
the only consideration is that the COBOL compiler must be able to tell where one
statement ends and the next begins. This yields the following rules.

• The last statement in a paragraph or section must have a period or full stop, as
shown in the following example.

SECTION-6 SECTION.
PARA-6. [Paragraph header]
DISPLAY "I JUST MOVED 10 TO THE TOTAL".
PARA-7. [End of paragraph]
EXIT

• Any statement that is immediately followed by another verb is implicitly


terminated, so it does not need a period or full stop (unless it is the last
statement in a paragraph or section). Line 3 in the following example shows a
verb following a statement on the previous line.
PARA-8.
MOVE 100000 TO WS-SALARY-1 WS-SALARY-2
DISPLAY "I JUST GAVE US A RAISE" [Line 3]
GOBACK.

• All statements can end with a period or full stop, so it is never incorrect to
terminate in this way.

Información Confidencial | Información Propietaria de Gladius Technology | Página 44 de


176
Following the above rules produces code that does not generate any syntax errors
because of the way that you terminate statements; however, there is one other
consideration. You often need to show the end of the scope of a verb, and the period
or full stop may be used for this. The code below shows the period at the end of the
STOP statement.

IF WS-ERROR-COUNT> 15 THEN
DISPLAY "TOO MANY ERRORS"
GOBACK.
READ [and so on]

The logic shown here stops the run if more than fifteen errors exist. Adding a period at
the end of the DISPLAY statement would cause the program to always stop, which is
not a correct solution. The positioning of the periods is very important.

For this reason, many verbs have an END- construction, indicating the end of the verb's
scope, as shown in the following example. Although optional, it is a good idea to
include an END-IF statement.

IF WS-ERROR-COUNT > 15 THEN


DISPLAY "TOO MANY ERRORS"
GOBACK
END-IF.
READ [and so on]

4.4. PROCEDURE DIVISION Verbs


Within the PROCEDURE DIVISION, you can use many verbs, including the following.

• DISPLAY
• ACCEPT
• GOBACK
• MOVE
• PERFORM … IF
• PERFORM … UNTIL
• GO TO

4.5. The DISPLAY Verb


DISPLAY can be used to output the value of any combination of data items and literal. It
will also show the useful (as opposed to the binary or hex) values of COMP or COMP-3
fields. In the example at the beginning of this module ("DISPLAY WS-MESSAGE"),
DISPLAY sends the value of the field WS-MESSAGE to the screen.

Información Confidencial | Información Propietaria de Gladius Technology | Página 45 de


176
4.6. The ACCEPT Verb
ACCEPT is an exact opposite of DISPLAY, allowing the person running the program to
input a value into a data item. After the value has been accepted, it can be
manipulated like any other data value. In the example at the beginning of this module
("ACCEPT WS-NAME"), ACCEPT copies the value on the screen into the field named
WS-NAME.

4.7. The GOBACK Verb


Goback stops the program and returns control to the operating system. It is surprisingly
easy to forget this statement or to write the program in such a way that the statement
is never executed. This causes the program to hang, when there are no more
statements to execute or, even worse, executing statements when they should not be
executed. Always ensure that you have a working GOBACK.

PARA-8.
MOVE 100000 TO WS-SALARY-1 WS-SALARY-2
DISPLAY "I JUST GAVE US A RAISE" [Line 3]
GOBACK.

4.8. The MOVE Verb


MOVE copies a value from a data item (or a literal or figurative constant) to one or
more data items. MOVE transfers data from a sending field to a target field. For
example, if a program read a record and stored it, you could use MOVE to move the
data from the input storage area to the output storage area. Here is a simple form of
MOVE.

MOVE DATA_SEND_FIELD TO DATA_TARGET_FIELD.

Then sending field could contain one of the following

• Numeric literal (0 or 2004)


• Character literal ("Hello")
• Figurative constant (like SPACES or ZERO)
• Data item (for example, WS_NAME or WS_COUNTER)

Numeric literal MOVE

In the examples below the numeric literal zero is moved to field WS-TOTAL and 2004 is
moved to the field WS-YEAR.

MOVE 0 TO WS-TOTAL

Información Confidencial | Información Propietaria de Gladius Technology | Página 46 de


176
MOVE 2004 TO WS-YEAR

Character literal MOVE

In this example the character literal HELLO is moved to the field WELCOME-MESSAGE.

MOVE "HELLO" TO WELCOME-MESSAGE

Figurative constant MOVE

These two examples use the figurative constants SPACES and ZERO.

MOVE SPACES TO WS-CHARACTER-FIELDS


MOVE ZERO TO WS-TOTAL-2 WS-TOTAL-3

In the examples above spaces are moved to the field


WS-CHARACTER_FIELDS, and zero is moved to two fields: WS-TOTAL-2 and WS-TOTAL-
3.

Data item MOVE

Here are two examples showing how data items can be moved.

MOVE WS-NAME TO OUTPUT-NAME-1 OUTPUT-NAME-2

In this example the value of field WS-NAME is moved to two fields: OUTPUT-NAME-1
and OUTPUT-NAME-2.

MOVE WS-COUNTER to STORE-COUNTER

In this example the value of the field WS-COUNTER is moved to the field STORE-
COUNTER.

Using MOVE

MOVE works in a totally predictable way. MOVEing to a character field (whether from a
character or numeric one) causes the target field to fill up from the left. If the target
field is longer, the remaining byte(s) on the right will be space-filled. If the target field is
too short, the original value will be truncated from the right. The following illustrates
the how sending field will start filling up the target field starting from the left.

Sending Field Target Field


ABC A _ _

Información Confidencial | Información Propietaria de Gladius Technology | Página 47 de


176
MOVEing to a numeric field yields opposite results. The target field will be filled up
from the right. If the target field is longer, the remaining character positions (on the
left) will be zero-filled. If the target field is too short, the original value will be
truncated from the left. The following illustrates how the receiving field fills up from
the right and will eventually display "234" only.

Sending Field Target Field


1234 _ _ 4

This behavior applies also if the source field is alphanumeric or alphabetic. However,
runtime errors often occur when a MOVE fails because a program is trying to move
non-numeric data to a numeric field. This happens when input fields do not contain an
expected numeric value. If there is the slightest chance of such errors, for example if
input fields might not contain numbers, then validate them. This is discussed further in
a later module.

Sending and Target Field Lengths

The previous two examples used sending and target fields of the same length. Consider
the following example when the target field length is more restricted than the sending
field length.

NAME-IN PIC X(8) VALUE "ELIZABETH". / MOVE NAME-IN


NAME-OUT PIC X(4) VALUE "AMY". / TO NAME-OUT

One would think that "ELIZABETH" becomes assigned to NAME_OUT; however, the PIC
X(4) limits the target field to "ELIZ" only.

Padding and Truncating in Various MOVEs

Let us examine the following code.

Add code for move ws-char-1 to ws-char-2 thru 5 and w-number-2 thru 4.

IDENTIFICATION DIVISION.
PROGRAM-ID. Example42.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-NUMBER-1 PIC 9(6) VALUE 243.
01 WS-NUMBER-2 PIC 99.
01 WS-NUMBER-3 PIC 9(9).
01 WS-NUMBER-4 PIC 9(4).
01 WS-CHAR-1 PIC X(4) VALUE "ABCD".
01 WS-CHAR-2 PIC X(8).

Información Confidencial | Información Propietaria de Gladius Technology | Página 48 de


176
01 WS-CHAR-3 PIC XX.
01 WS-CHAR-4 PIC X(12).
01 WS-CHAR-5 PIC X(3).
PROCEDURE DIVISION.
A-PARA SECTION.
MOVE WS-NUMBER-1 TO WS-NUMBER-2
WS-NUMBER-3 WS-NUMBER-4.
DISPLAY "WS-NUMBER-1=" WS-NUMBER-1
DISPLAY "WS-NUMBER-2=" WS-NUMBER-2
DISPLAY "WS-NUMBER-3=" WS-NUMBER-3
DISPLAY "WS-NUMBER-4=" WS-NUMBER-4
MOVE WS-NUMBER-1 TO WS-CHAR-4 WS-CHAR-5.
DISPLAY "WS-NUMBER-1=" WS-NUMBER-1
DISPLAY "WS-CHAR-4=" WS-CHAR-4
DISPLAY "WS-CHAR-5=" WS-CHAR-5.
A-PARA-EXIT.
GOBACK.

After the code is executed, the follow results are produced:

This
Contains this value…
field…
WS-
000243
NUMBER-1
WS- 43 (the six digits 000243 were truncated on
NUMBER-2 the left)
WS-
000000243
NUMBER-3
WS-
0243
NUMBER-4
WS-CHAR-4 "0243 " ("0243" followed by eight spaces)
"000" (the six characters "000243" were
WS-CHAR-5
truncated on the right)

Let's continue with additional code, as shown next.

MOVE WS-CHAR-1 TO WS-CHAR-2 WS-CHAR-3


WS-CHAR-4.
MOVE WS-CHAR-1 TO WS-NUMBER-2 WS-NUMBER-3.

After the code is executed, the follow results are produced.

This
Contains this value…
field…
WS-CHAR-1 ABCD
WS-CHAR-2 "ABCD " ("ABCD" followed by four spaces

Información Confidencial | Información Propietaria de Gladius Technology | Página 49 de


176
AB (the four characters "ABCD" were truncated
WS-CHAR-3
on the right)
WS-CHAR-4 "ABCD " ("ABCD" followed by eight spaces)

Assuming that the moves of non-numeric data to numeric fields are allowed in the last
two lines, the fields now contain the following values.

This
Contains this value…
field…
WS - CD (the four non-numeric characters ABCD are
NUMBER-2 truncated on the left)
WS-NUMBER-
00000ABCD (five leading zeros)
3

4.9. The PERFORM Verb


Up until now the course has shown programs that execute in the order that the
statements appear. However, you can control the order of execution sequence using
the PERFORM verb. You can control execution using several formats of the PERFORM
verb, including using it with an IF condition or using PERFORM UNTIL a condition
occurs.

The following shows how to use PERFORM, a reserved word.

PERFORM paragraph-header

PERFORM identifies the instruction to be done on paragraph-header, which is the


name of a subprogram to be executed. The subprogram must also be written in your
program. Here is an example.

In the ninth line of the following program, the verb PERFORM executes INIT-PARA, a
subprogram that begins on line 12.

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE43.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM-370.
OBJECT-COMPUTER. IBM-370.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
DATA DIVISION.
WORKING-STORAGE SECTION .
01 WS-TIMES PIC 9(4).
01 WS-NUM1 PIC 9(4).

Información Confidencial | Información Propietaria de Gladius Technology | Página 50 de


176
01 WS-NUM2 PIC 9(4).
01 WS-NUM3 PIC 9(6) .

PROCEDURE DIVISION .
PROG SECTION.
PERFORM INIT-PARA .
PERFORM LOOP-PARA WS-TIMES TIMES.
PERFORM END-PARA .

INIT-PARA SECTION.
DISPLAY "A SIMPLE MULTIPLIER" .
DISPLAY "HOW MANY TIMES (1 TO 6)?" .
ACCEPT WS-TIMES .
IF WS-TIMES > 6 OR WS-TIMES < 1 THEN
MOVE 1 TO WS-TIMES
END-IF.
INIT-PARA-EXIT.
EXIT.
LOOP-PARA SECTION.
DISPLAY "FIRST NUMBER?" .
ACCEPT WS-NUM1 .
DISPLAY "SECOND NUMBER?" .
ACCEPT WS-NUM2 .
MULTIPLY WS-NUM1 BY WS-NUM2 GIVING WS-NUM3
DISPLAY "PRODUCT OF " WS-NUM1 " AND " WS-NUM2
" IS " WS-NUM3 .
LOOP-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "MULTIPLICATION DONE " WS-TIMES " TIME(S)" .
DISPLAY "THANK YOU FOR THAT" .
END-PARA-EXIT.
GOBACK.

This program might yield the following sample output.

A SIMPLE MULTIPLIER
HOW MANY TIMES (1 TO 6)?
3
FIRST NUMBER?
873
SECOND NUMBER?
990
PRODUCT OF 873 AND 990 IS 864270
FIRST NUMBER?
526
SECOND NUMBER?
17
PRODUCT OF 526 AND 017 IS 008942
FIRST NUMBER?
499
SECOND NUMBER?
21
PRODUCT OF 499 AND 021 IS 010479
MULTIPLICATION DONE 3 TIME(S)
THANK YOU FOR THAT

Información Confidencial | Información Propietaria de Gladius Technology | Página 51 de


176
NOTE: This program and later ones omit the IDENTIFICATION DIVISION and
ENVIRONMENT DIVISION when they are not needed.

The PERFORM Verb and Processing Loops

The program logic can be seen in PROG. The verb PERFORM executes the subprogram,
INIT-PARA. Control passes to INIT-PARA and the program works through the INIT-PARA
statements. The ACCEPT verb in INIT-PARA gets a value that the program needs. Here,
ACCEPT gets the number of times the main program loop will occur.

PROG also contains an IF statement, as repeated here.

IF WS-TIMES > 6 OR WS-TIMES < 1


MOVE 1 TO WS-TIMES.

This logic states that if a user enters 0 or a number greater than 6, ignore it and
substitute 1. (A later module provides a more detailed discussion of the format of IF.)

At the end of INIT-PARA we return to PROG, where the second statement appears:
PERFORM LOOP-PARA WS-TIMES TIMES. This paragraph executes a particular number
of times (at the end of which control returns to PROG).

If we now look at the code in LOOP-PARA, we see two more ACCEPT statements, which
give the program the numbers needed for the MULTIPLY statement. There is more to
MULTIPLY than can be covered here, but we should be able to see that the statement
calculates the product of two data items, places it in a third data item, and then
DISPLAYs it.

Note: Both the MULTIPLY and DIVIDE statements will be covered later. The Divide
statement format is very similar to the MULTPLY; DIVIDE one data filed by a second
data field placing the result in a third data field.

DIVIDE WS-NUM1 BY WS-NUM2 GIVING WS-NUM3.

The whole paragraph will be PERFORMed as many times as WS-TIMES decrees.

Eventually, LOOP-PARA completes for the last time, and control passes to the last
statement of PROG, which is PERFORM END-PARA. This statement initiates END-PARA.
The END-PARA paragraph contains two informational DISPLAYs and a GOBACK. Note
that there is no need to end the program in PROG, making the GOBACK the last
statement in END-PARA as perfectly acceptable.

The Verbs PERFORM … UNTIL and GO TO

Información Confidencial | Información Propietaria de Gladius Technology | Página 52 de


176
COBOL offers two verbs, PERFORM and GO TO, to direct the logic of a program. For
various reasons PERFORM is far more likely to be seen in modern COBOL. GO TO in
COBOL, as in other languages, has acquired a bad reputation, because it has become
associated with poor programming practice. In truth, it is possible to write well- or
badly-designed programs with either verb, but PERFORM makes it easier to do the
former.

You can use the PERFORM verb in several formats, including PERFORM…UNTIL. Use
PERFORM … UNTIL according to the following syntax.

PERFORM PARAGRAH_HEADER UNTIL CONDITION

We have looked at the simple use of PERFORM, which executes once. The PERFORM ...
UNTIL executes one or many times until the condition is true.

Here is an example of a program using PERFORM ... UNTIL. The output follows the
program.

NOTE: Use comments liberally to make the code more understandable. The compiler
ignores any line with an asterisk ('*') in column 7. Use this for comments.

IDENTIFICATION DIVISION.
PROGRAM-ID. Example44.
AUTHOR. TRAINING.
INSTALLATION. MARS.
DATE-WRITTEN. 18/10/2005.
DATE-COMPILED.
SECURITY. MICROFOCUS
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.

SOURCE-COMPUTER. IBM-370.
OBJECT-COMPUTER. IBM-370.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-COUNTER PIC 9.
PROCEDURE DIVISION.
*
MAINLINE SECTION.
PERFORM INIT-PARA.
PERFORM LOOP-PARA UNTIL WS-COUNTER > 4.
PERFORM END-PARA.

INIT-PARA SECTION.
****************************************
* Initial actions
****************************************
DISPLAY "IN INIT PARA".
MOVE ZERO TO WS-COUNTER.

Información Confidencial | Información Propietaria de Gladius Technology | Página 53 de


176
INIT-PARA-EXIT.
EXIT.
LOOP-PARA SECTION.
**************************************
* Main program loop
**************************************
ADD 1 TO WS-COUNTER.
DISPLAY "DOING LOOP PARA...." WS-COUNTER.
LOOP-PARA-EXIT.
EXIT.

*
END-PARA SECTION.
DISPLAY "IN END PARA - STOPPING".
END-PARA-EXIT.
GOBACK.

The output is:

IN INIT PARA
DOING LOOP PARA....1
DOING LOOP PARA....2
DOING LOOP PARA....3
DOING LOOP PARA....4
DOING LOOP PARA....5
IN END PARA - STOPPING

This program illustrates the following interesting points.

• PERFORM UNTIL is very commonly used, but the condition must become true at
some point or the program could loop forever. In this case, if the ADD 1 TO WS-
COUNTER were not present, this would happen. Another common mistake is for
the test not to be met because it has been incorrectly specified. For example,
the following code would generate a perpetual loop if the salary paid never
exactly equalled 20,000 — a better test would probably be greater than some
figure.
• PERFORM LOOP-PARA UNTIL SALARY-PAID = 20000
• By default, the UNTIL clause is tested before the loop. The loop happened five
times, because "greater than 4" becomes true only after the fifth iteration.
When the program comes round for the sixth time, "greater than 4" is now
true.
• There is a different format of the verb, PERFORM WITH TEST AFTER UNTIL . This
means that the will always be PERFORMed at least once. The default version of
PERFORM with the test before is very useful, as the loop will stop if the
condition is never true. For example, if you are reading records from a file, you
might write pseudo-code such as "perform process-record until there are no
more records on the file." The WITH TEST AFTER version of the verb would
assume that at least one record existed. So, if there were no records on the file,
a logic error would occur.

Información Confidencial | Información Propietaria de Gladius Technology | Página 54 de


176
Using PERFORM with Multiple Paragraphs

PERFORM works predictably in that control passes to a paragraph and then returns to
the statement after the PERFORM. bPERFORM can be used with multiple paragraphs,
as illustrated in the following program.

PROG.
PERFORM PARA-3 THRU PARA-5.
****** some other code
GOBACK.
PARA-3.
* code
PARA-4.
* code
PARA-5.
* code

PARA-3, PARA-4 and PARA-5 would be carried out in that order.

The programmer could later add another paragraph (or multiple paragraphs), as shown
in the following code.

PARA-3.
* code
PARA-3A.
* new code
PARA-4.

Because the program lists PARA-3A between the start- and end-points of the
PERFORM, it will be executed. This is not necessarily a problem; indeed it can appear a
very convenient way of inserting extra code without altering the main logic of the
program. However, someone looking at the original PERFORM statement might not be
aware of the change. This illustrates the need for inserting comments in the code at
that point.

Always include a GOBACK in your code. In the previous example, if it were omitted,
after the PERFORM of the three paragraphs, the program would look what to do next.
The program would fall into PARA-3 and so on. This is not the fault of COBOL; rather, it
is the predicted behavior.

4.10. The GO TO Verb


In some instances we could use the verb GO TO to control the logic. The following code
shows how the previous program could be rewritten using GO TO.

IDENTIFICATION DIVISION.
PROGRAM-ID. Example45.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.

Información Confidencial | Información Propietaria de Gladius Technology | Página 55 de


176
INPUT-OUTPUT SECTION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-COUNTER PIC 9.
PROCEDURE DIVISION.
PROG SECTION.
PERFORM INIT-PARA.
PERFORM LOOP-PARA.
PERFORM END-PARA.
INIT-PARA SECTION.
DISPLAY "IN INIT PARA".
MOVE ZERO TO WS-COUNTER.
INIT-PARA-EXIT.
EXIT.
LOOP-PARA SECTION.
LOOP-PARA-01.
ADD 1 TO WS-COUNTER.
DISPLAY "DOING LOOP PARA...." WS-COUNTER.
IF WS-COUNTER < 5 THEN
GO TO LOOP-PARA-01
END-IF.
LOOP-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "IN END PARA - STOPPING".
END-PARA-EXIT.
GOBACK.

GO TOs are just as predictable as PERFORMs, yet as a generalization, they produce


more mistakes in program logic than PERFORMs. This may be because GO TO relies on
COBOL's ability to "fall through" paragraphs, as shown in the previous code. (Program
control falls through PROG to INIT-PARA, then to LOOP-PARA, and then to
END-PARA when WS-COUNTER is not less than 5.)

PERFORM, on the other hand, always jumps back to the place from which it came.
Apart from anything else, this makes the program logic easier to visualize and so less
prone to error.

4.11. Mixing PERFORMs and GO TOs


Avoid mixing PERFORMs and GO Tos at all costs. The following code shows these two
verbs mixed. Let's look at the errors that can result.

IDENTIFICATION DIVISION.
PROGRAM-ID. Example46.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
DATA DIVISION.
WORKING-STORAGE SECTION.
PROCEDURE DIVISION.
PROG.
PERFORM PARA-1 THRU PARA-3.

Información Confidencial | Información Propietaria de Gladius Technology | Página 56 de


176
GOBACK.
PARA-1.
DISPLAY "IN PARA 1".
GO TO PARA-4.
PARA-2.
DISPLAY "IN PARA 2".
PARA-3.
DISPLAY "IN PARA 3".
PARA-4.
DISPLAY "IN PARA 4".
PARA-5.
DISPLAY "IN PARA 5".
GO TO PARA-3.

Even in this small piece of code, it has become difficult to follow the logic. Although the
PERFORM results in control jumping to PARA-1, the GO TO then takes us to PARA-4, and
then we drop through to PARA-5. In fact, everything works out all right, as the GO TO
PARA-3 takes us back to the last paragraph to be PERFORMed. Control can therefore
return to the GOBACK. If that GO TO pointed to, say a PARA-8 or there was no GO TO,
the results would be unpredictable, to say the least.

Incidentally, this program produces the following output.

IN PARA 1
IN PARA 4
IN PARA 5
IN PARA 3

4.12. Summary
In this module we have examined the following PROCEDURE DIVISION verbs:

• DISPLAY
• ACCEPT
• GOBACK
• MOVE
• PERFORM … IF, PERFORM … UNTIL
• GO TO

4.13. Exercise: Using Verbs


Introduction

Write a program that does the following:

Información Confidencial | Información Propietaria de Gladius Technology | Página 57 de


176
• Prompts the user for input of a pair of numbers.
• Modifies the second number to be .01 if 0 is entered.
• Divides the pair of numbers producing a number with only 2 decimals and
displays results.
• Allows the user to specify the number of problems to be calculated. Valid
response must be a between 1 and 16. If outside this range, the number is
replaced with 5.
• Displays a few messages when complete.

You must use these verbs and statements in your code.

• PERFORM
• DISPLAY
• IF - MOVE
• ACCEPT
• DIVIDE
• GOBACK

The output should look like this:

A SIMPLE DIVIDING PROGRAM


HOW MANY PROBLEMS WOULD YOU LIKE TO DO?
3
FIRST NUMBER?
7350.33
SECOND NUMBER?
1.97
RESULT IS 3731
FIRST NUMBER?
2383.01
SECOND NUMBER?
99
RESULT IS 0024
FIRST NUMBER?
10
SECOND NUMBER?
0
SECOND NUMBER ZERO - REPLACED WITH .01
RESULT IS 1000
DIVISION DONE 03 TIMES

Details

1. Start your editor.

Información Confidencial | Información Propietaria de Gladius Technology | Página 58 de


176
2. Open PROGRAM4 located in X: \CLASS\MODULE4\NETX.

3. In the WORKING-STORAGE SECTION create the follow 01 level fields:

Define this field… Using this value…


WS-TIMES 2 numeric digits
WS-FIRST-NUMBER 4 numeric digits with 2 decimals
WS-SECOND-NUMBER 4 numeric digits with 2 decimals
WS-RESULT 4 numeric digits

4. In the PROCEDURE DIVISION create 4 paragraphs. In the first paragraph list the PERFORM

statement used to execute each successive paragraph.

5. In the 2nd paragraph list 2 DISPLAY statements for the title and question for the program; and the

accept statement for the WS-TIMES field which defines the number of problems to be computed.

6. Include in the 2nd paragraph an IF statement that specifies that if the number of times is less that

0 or greater that 16, the number 5 will be used.

7. In the 3rd paragraph code the following:

Use this
To…
Verb…
DISPLAY Prompt user for first number.
ACCEPT Read in value for WS-FIRST-NUMBER.
DISPLAY Prompt user for second number.
ACCEPT Read in value for WS-SEOND-NUMBER.
IF Test WS-SECOND-NUMBER for 0.
Assign .01 to WS-SECOND-NUMBER if IF
MOVE
condition is true.
Notify user second number was replaced with
DISPLAY
.01.
DIVIDE Divide WS-FIRST-NUMBER
BY Provide WS-SECOND-NUMBER
GIVING Calculate WS-RESULT
ROUNDED Round to whole number.
DISPLAY Output results.

Información Confidencial | Información Propietaria de Gladius Technology | Página 59 de


176
8. In the last paragraph code the following:

Use this
To…
Verb…
Notify user calculations have been preformed
DISPLAY
"WS-TIMES" times.
DISPLAY Display concluding message.
GOBACK End program.

9. Save the program in the X:\CLASS\MODULE4\NETX directory as PROGRAM4.cbl.

10. Compile and test the program

5. Module 5: Best Practices


Over the life of a typical COBOL application, many different people might make fixes
and improvements at different times. Often this maintenance work may take many
times more than the initial effort needed to create the application in the first place.
Implementing best practices when creating new programs speeds up the process of
getting a stable, high-quality application yet also yields huge benefits during the
maintenance phase.

5.1. Objectives
Upon successful completion of this module, you will be able to:

• Write meaningful comments when writing code.


• Design a typical COBOL file-handling program.

5.2. Designing a COBOL Program


Does a COBOL program need to be designed? Could the code be written immediately
with no thought being given to program structure? It is always possible to write a
program in this way, but it is rarely sensible. Most programs need to make decisions at
some point. Many programs must contain procedural logic, meaning, certain things
must take place before other actions can be undertaken. For example, programs may
have to execute a loop a particular number of times or until some condition is true, as
we saw in the discussion of the PERFORM...IF or PERFORM...UNTIL verb. If a program
has to do any of these things, then bad design or not designing at all will introduce
logic errors. Logic errors cause the code to behave differently than the programmer
expects. The COBOL compiler cannot find such logic errors, and they may remain

Información Confidencial | Información Propietaria de Gladius Technology | Página 60 de


176
undetected until the program goes live, surfacing in the future. A well-designed
program omits logic errors. Spend time on the design to avoid problems later.

COBOL programs tend to be very long-lived, perhaps for twenty or thirty years. Over
that time they may undergo revision, from the addition of minor features to almost a
total rewrite. A well-designed program from the start makes modifications considerably
easier. If the modifications are in turn well designed, then the task is simplified for the
next maintenance programmer, and so on.

Program Structure Design

There are many different ways of writing a COBOL program. We will examine one
method that works by expressing the structure of anything, whether or not computer-
related, in terms of the following structures. We can use this method to design a
program visually.

The following illustration represents one structure. A single box indicates the entire
structure to be defined.

The next illustration shows multiple constructs that make up the structure. One or
more constructs might appear below the whole structure. Two or more boxes in a
horizontal line (a group of items or events) are known as a sequence.

Información Confidencial | Información Propietaria de Gladius Technology | Página 61 de


176
Two or more boxes, each with a circle in their top right-hand corner, represent a
choice, where only one option is true. This is known as a selection. The following
illustration depicts a selection between CLEAN or DIRTY.

One box containing an asterisk in the top right-hand corner represents an iteration.
This indicates multiple occurrence of whatever is below. The number of occurrences or
the condition when there are no more occurrences might show above the box. Note
that the number of occurrences can be zero. The following illustration shows an
iteration of the train carriage item.

Información Confidencial | Información Propietaria de Gladius Technology | Página 62 de


176
All boxes should have meaningful names.

In practice, a structure diagram of almost anything will contain a combination of


different occurrences of the above three constructs.

The following illustration shows the train in detail.

Different types of boxes cannot be at the same level in the same part of the structure.

We can now see how to apply these structures to data files, and from those structures,
how to design a logically correct program. We have not yet covered the COBOL entries
needed to cope with file and record handling. But, we can complete the design here
and then write programs in a later module, secure in the knowledge that we have
mastered the underlying logic.

Información Confidencial | Información Propietaria de Gladius Technology | Página 63 de


176
Input and Output Files

Let us say that we want to design a program that reads in a file of records and then
deals with them in different ways depending on the type of record we find. Let's use
the following rules for our example.

• The input file can include any number of records (including 0).
• There are two types of input records, type A and type B. We will assume that
there is a PIC X field on the record.
• If we find a type A record, create an output record based on that record, and
write it out. (The details of the fields are not relevant at the design stage.)
• If we find a type B record, just add to a type B counter, which will display at the
end of the program.

We can show the input file in the following way.

The '*' indicates that the program includes an iteration of record (zero or more). We
can worry about how the program deals with zero records later. The circle in the top
right-hand of the bottom boxes represents a selection (only one of the boxes at this
level can be true at one time).

The output file is similar, but simpler, as shown in the following illustration.

Información Confidencial | Información Propietaria de Gladius Technology | Página 64 de


176
This program structure faithfully reflects and combines both file structures. You will see
that it contains examples of sequence, selection, and iteration; this is the case with
very many programs.

Program Actions

The structure also contains actions that the program will need. Practically any program
reading or writing to a sequential file (records following one another) will have a very
similar design, depicted in the following illustration.

The following lists the actions shown as numbers above.

Información Confidencial | Información Propietaria de Gladius Technology | Página 65 de


176
5.3. Design Analysis
Let us now discuss how this program structure works. (We are not discussing how to
achieve this in COBOL as yet, that is discussed in another module.) The top-level box
(PROG) has below it three boxes, which have neither asterisks nor circles in their
corners. This represents a sequence, read left to right.

The program includes the following elements.

• PROG – Perform INIT. Perform BOD. Perform END.


• INIT – Includes three actions:
o Open the files [1]. (We will take it for granted at the moment that we
have to do this. It's the way of connecting the program to the files it
needs.)
o Clear counters [8]. (We could do this with VALUE clauses, but it's a useful
reminder.)
o Read the input file [4] looking for a record. To anticipate, in COBOL you
can check whether a READ failed because of the end-of-file indication.
Then, set a flag automatically (either a PIC 9 set to 1 when end-of-file or
PIC X set to 'Y' — or anything else you want). It's worth remembering
that this flag will need to be cleared as one of the counters. Again, we
can do this explicitly, or we can use a VALUE clause.
• BOD – Perform PROCESS-REC until the flag is true. If the file was empty, then
the flag is already true and the PERFORM won't happen at all.
• END – Display the type B counter [9], which must be getting updated elsewhere,
close the files [2] (again, let's assume that this is a good thing to do), and stop

Información Confidencial | Información Propietaria de Gladius Technology | Página 66 de


176
the run [3].
• PROCESS-REC – If the record we have at the moment is a Type A, Perform Type-
A; else Perform Type-B.
• TYPE-A – Set up the output record (presumably by copying values from the
input record) [5], and write an output record [6]. Try and read another record
[4]. This read will either succeed (in which case we go round the loop again) or
fail because of the end-of-file (in which case we have finished the loop).
• TYPE-B – Add 1 to the type B counter [7], and try and read another record [4],
as above. Again the same logic applies. If we find a record, we go round again; if
not, we leave the PERFORM.

Writing this in a mixture of COBOL and pseudo-COBOL yields something like the
following code.

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE52.
AUTHOR. TRAINING.
INSTALLATION. MARS.
DATE-WRITTEN. 18/10/2005.
DATE-COMPILED.
SECURITY. MICROFOCUS
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM-370.
OBJECT-COMPUTER. IBM-370.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT TRAIN-IN ASSIGN "EXAMPLE52.DAT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS TRAININ-FILE-STATUS.
DATA DIVISION.
FILE SECTION.
FD TRAIN-IN.
01 TRAIN-REC.
03 TRAIN-TYEP PIC X .
03 TRAIN-NAME PIC X(20) .
03 TRAIN-NO PIC 9(6).
03 TRAIN-AGE PIC 9(6) .
WORKING-STORAGE SECTION.
01 TRAININ-FILE-STATUS PIC X(02).
01 WS-END-OF-FILE PIC 9 VALUE 0.
01 WS-TYPE-B-COUNTER PIC 9(6) VALUE 0.

PROCEDURE DIVISION.
PROG.
PERFORM INIT-PARA.
PERFORM BOD-PARA.
PERFORM END-PARA.

INIT-PARA SECTION.
DISPLAY "START OF PROGRAM".
[open files]

Información Confidencial | Información Propietaria de Gladius Technology | Página 67 de


176
[Check FILE Status]
[read file, if no record, move 1
to flag]
INIT-EXIT.
EXIT.

BOD-PARA SECTION.
PERFORM UNTIL WS-END-OF-FILE = 1
PERFORM PROCESS-REC
END-PERFORM.
BOB-EXIT.
EXIT.

END-PARA SECTION.
DISPLAY WS-TYPE-B-COUNTER
" 'B' RECORDS READ".
[close files]
END-EXIT.
GOBACK.

PROCESS-REC SECTION.
IF [it's a type A record] THEN
PERFORM TYPE-A-ACTIONS
ELSE [we're assuming here only A or B]
PERFORM TYPE-B-ACTIONS
END-IF.
PROCESS-REC-EXIT.
EXIT.

TYPE-A-ACTIONS SECTION.
[set up output record]
[write output record ]
[read file, if no record, move 1
to flag]
TYPE-A-ACTIONS-EXIT.
EXIT.

TYPE-B-ACTIONS SECTION.
ADD 1 TO WS-TYPE-B-COUNTER.
[read file, if no record, move 1
to flag]
TYPE-B-ACTIONS-EXIT.
EXIT.

In the above example, there are a couple of things to note.

• Firstly, the IF statement this time has an ELSE. The actions here will be carried
out if the condition is false (in other words, any record which isn't a type A will
automatically be treated as a type B). This may well be acceptable. Alternatively
you may need to check for A, B, and 'anything else'. Conditions are discussed in
far greater detail in another module.
• Secondly, on this occasion the IF statement has been terminated with an END-
IF. Normally this means that no period (full stop) is needed at the end of the IF.
But, because this is the last statement in the paragraph, the period is necessary.

Información Confidencial | Información Propietaria de Gladius Technology | Página 68 de


176
5.4. Summary
In this module we have examined the following topics.

• The importance of using comments when writing code


• The design of a typical COBOL file-handling program

5.5. Exercise 1: Creating Structure Diagrams


In this exercise, create a structure diagram for each example below.

1. A dinner party with a number of guests, each of whom is either male of female.

2. A dinner party, where only couples are invited.

3. The meal at the dinner party. The starter is quail's egg salad, langoustines or vegetable terrine.

Next, include a main course of steak (well-done, medium rare, or rare) with vegetables (and either

French fries or salad) or spinach and aubergine bake. Guests may drink one or more glasses of wine with

this portion of the meal. Peaches in Armagnac or lime and durian ice cream make the final course. (Both

the first and third courses are optional).

Finally, everyone can have one or more cups of coffee (black or with cream) or a liqueur.

4. The train (shown previously), now more complex, with first- and standard-class carriages, a buffet

car, and an extra engine at the back.

5. A holiday that consists of a flight at the beginning and a return flight at the end. Between those

two events are days where the holidaymaker goes to the beach, takes a coach trip, or goes shopping.

Allow for the luggage missing on the flight out.

6. An encyclopedia that consists of many volumes, each containing many articles. Each volume has a

table of contents and an index. A supplementary volume also has a table of contents and index of all the

volumes together with an atlas.

7. A person's life, defined in different ways. Firstly, draw a structure showing the person going to

school (more than one, possibly) and college, getting a job, and having a working life, followed by

Información Confidencial | Información Propietaria de Gladius Technology | Página 69 de


176
retirement. After you have done this, produce a totally different structure, showing the person getting

married, having children, and grandchildren.

8. Draw a structure of what you do in a typical week, showing events such as meals, working,

watching television (or whatever you do instead), hobbies and so on. You will probably have to show

workdays separately from weekends.

9. A COBOL program with a start, middle, and end. The start and end don't have to show any detail at

the moment, but in the middle we have to show that a number of records (possibly zero) will be

processed. Each record is of type A, B or C.

5.6. Exercise 2: Accessing Data


Introduction

The purpose of this program is to reformat the employee records. This program will
also count the number of records read and reformatted. In addition, this program will
count and display any invalid records on the employee master file.

Details

1. Start your editor.

2. Open PROGRAM5 located in X \CLASS\MODULE5\NETX.

3. Design and partly code a COBOL program to do the following.

• Read in a file of records, and then deal with them in different ways depending on the type of
record found. The input file may have any number of records (including 0).
• The records should all be of type A. Let us assume that this is a PIC X field on the record that we
can test. However, there may be records with other values on the file.
• If it finds a type A record, make an output record based on that record and write it out (the
details of the fields are not relevant at the moment). Also increment a type A record counter.
• If it finds any other type of record, display the entire contents of that record, and add to an
'other-type-of-record counter'.
• Display a start-up message at the beginning of the program. Display both counters at the end.
• Note: The input file description of the Employee-Leaving-Date must be commented out.

Información Confidencial | Información Propietaria de Gladius Technology | Página 70 de


176
4. Save the program in the X:\CLASS\MODULE5\NETX directory and provide the program name

PROGRAM5.CBL Compile the program correct any errors and test.

5. Output from the Run

PROGRAM STARTING
NUMBER OF VALID RECORDS PROCESSED: 0002
NUMBER OF INVALID RECORDS: 0000
ALL DONE!

The output file is

AVlad the Impaler 6587000228279


Ajames Tank 1456977025611

6. Module 6: Handling Sequential Files


The ability to easily and flexibly handle data files is central to commercial computing
needs and, not coincidentally, to COBOL. The language regards files as either sequential
or random access. Here, we look at the constructs and techniques for handling
sequential files effectively.

6.1. Objectives
Upon successful completion of this module, you will:

• Use the Environment Division and Data Division entries in a COBOL program
that uses input or output sequential files.
• Use the correct format of READ, WRITE, OPEN and CLOSE statements in the
Procedure division for sequential files, including testing for an end-of-file
condition.
• Describe how COBOL deals with multiple record types on the same file.
• Be able to design and code a typical COBOL program that handles sequential
files.

6.2. File Handling


In the earlier modules, we have written only COBOL programs that do not use files. We
shall now examine the extra entries necessary to use sequential files, which are in fact
the default file types used in a COBOL program. When a program uses sequential files,
the program must include the following entries and statements.

• Environment Division entries – to identify a file to your program

Información Confidencial | Información Propietaria de Gladius Technology | Página 71 de


176
• Data Division entries – to specify the file's layout for your program so that your
program can read or write to it accurately
• Procedure Division statements – to act on the file

After the discussion, we shall take the program from the previous module and turn it
into a working COBOL program. We shall then examine the way that COBOL deals with
multiple record types, within an input or output file.

6.3. Files and Records


Before we begin discussing how to open and close files, let's define a file and a record.

• A file is a group of records.


• A record is a group of fields or data items. A record must be written as a Group
Level item, which contains Elementary Level data items.

A sequential file is a file containing records that must be retrieved in the exact order as
within the file. This module discusses how to open and close sequential files.

6.4. Connecting Files


Before opening a file in your program, you must first establish its identify in your
program and specify its layout so your program can access it appropriately. This is done
in two steps and two places within a program.

• Identify a file within the ENVIRONMENT DIVISION using a SELECT statement.


• Specify a file's layout within the DATA DIVISION.

6.5. Identifying Files


The ENVIRONMENT DIVISION has not detained us for long up until now. Now, we must
identify the file to our program using a SELECT statement. The SELECT statement must
be included in the INPUT-OUTPUT SECTION of the ENVIRONMENT DIVISION. The
INPUT-OUTPUT SECTION contains an entry for each file.

The following code shows an entry for one file, INPUTFILE.DAT.

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INFILE ASSIGN "INPUTFILE.DAT". (windows)
SELECT INFILE ASSIGN INPUTFILE. (Mainframe)

Información Confidencial | Información Propietaria de Gladius Technology | Página 72 de


176
This is the minimum entry for a file. The file is called INPUTFILE.DAT in the outside
world; however, your COBOL program knows it as INFILE within the program. This
SELECT statement assigns the INPUTFILE.DAT file with an internal file on your system,
INFILE, which you name.

While the Division and Section entries begin in Area A, the file entries should start in
Area B.

Specifying Files are Sequential

Although COBOL assumes that the file is a sequential one, we could say this explicitly.
To make things crystal clear, specify that the file is sequential, as in the following code.

SELECT INFILE ASSIGN "INPUTFILE.DAT"


ORGANIZATION IS RECORD SEQUENTIAL.

If you use an ORGANIZATION clause, you must write at least the first and last words
(ORGANIZATION and SEQUENTIAL). The words IS and RECORD are both optional.
ORGANIZATION must be spelled with a Z.

Naming Files

You may be wondering what naming rules apply for the SELECT…ASSIGN clause. The
filename used inside the program (INFILE) must conform to normal COBOL
requirements. The external name (INPUTFILE.DAT) follows the normal Windows
practice of name/dot/three-character extension. The DAT extension shows that this is a
data file. Also, although the name is shown in upper case, at run-time the Windows
environment ignores the case when looking for the file.

Input and Output Files

The following code shows a slightly larger entry. This time it includes an input and an
output file, both sequential.

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INFILE ASSIGN "INPUTFILE.DAT".
SELECT OUTFILE ASSIGN "OUTFILE.DAT".

Each file needs its own SELECT statement. Each of them should be terminated with a
period.

The input file must exist while an output file might not exist. If it does, by default the
program overwrites it and loses existing records.

Información Confidencial | Información Propietaria de Gladius Technology | Página 73 de


176
Although we have now told the program that we are going to access one or more files,
the program needs detail of the data on the records within the file(s). This information
appears in the DATA DIVISION.

6.6. Specifying File Layout


The second step of connecting files to your program is identifying the file's layout, its
attributes, and records. Do this in the DATA DIVISION.

The following program adds a FILE SECTION within the DATA DIVISION and a FILE
DESCRIPTIION (FD) to the program above. The DATA DIVISION almost always contains a
WORKING-STORAGE SECTION. If you use a FILE SECTION, it must precede WORKING-
STORAGE.

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INFILE ASSIGN "INPUTFILE.DAT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS INFILE-FILE-STATUS.

SELECT OUTFILE ASSIGN "OUTFILE.DAT"


ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS INFILE-FILE-STATUS.

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INFILE ASSIGN "INPUTFILE.DAT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS INFILE-FILE-STATUS.

SELECT OUTFILE ASSIGN "OUTFILE.DAT"


ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS INFILE-FILE-STATUS.

DATA DIVISION.
FILE SECTION.
* The input file
FD INFILE. [File Description]
01 INREC. [Record Description]
03 IN-REC-TYPE PIC X.
03 IN-NAME PIC X(20).
03 IN-DOB PIC 9(8).
* The output file
FD OUTFILE.
01 OUTREC.
03 OUT-NAME PIC X(20).
03 OUT-DOB PIC 9(8).

Información Confidencial | Información Propietaria de Gladius Technology | Página 74 de


176
WORKING-STORAGE SECTION.
[more code]

File Description (FD) Entries

For every file name named in the SELECT statement within the INPUT-OUTPUT
SECTION of the ENVIRONMENT DIVISION, you must include an FD (File Description)
entry. The FD statement marks the beginning of the data description for that file. The
name following the FD must match that after the appropriate SELECT statement in the
INPUT-OUTPUT SECTION. Because two SELECT statements were included for two file
names in the previous code, the program must include two FD entries. Code FD entries
in Area A.

Record Structures

After coding the file description entries for both files, you need to define records within
each file. The record description indicates the record attributes and follows its file
description entry.

DATA DIVISION.
FILE SECTION.
* The input file
FD INFILE. [File Description]
01 INREC. [Record Description]
03 IN-REC-TYPE PIC X.
03 IN-NAME PIC X(20).
03 IN-DOB PIC 9(8).

Each record description must start with a Group Level item, which names the record. In
our example, these are 01 INREC and 01 OUTREC.

INREC shows the structure of a record on the input file, and OUTREC similarly
represents the fields on the output record. Only one record appears for each file. We
are going to deal only with one record at a time, so this is logical.

Important note: You cannot use the VALUE clause to preset fields in the File Section.
Why do you think this is? The VALUE clause cannot be used to preset fields in the File
Section, because the contents of the input and/or output data is moved into this area.

6.7. Accessing Sequential Files


This section discusses how to use the following verbs in the PROCEDURE DIVISION to
access sequential files:

• OPEN

Información Confidencial | Información Propietaria de Gladius Technology | Página 75 de


176
• CLOSE
• READ
• WRITE

The OPEN Verb

Before the program can access a file, it needs to be OPENed. Input files are OPENed
INPUT, and output files are normally OPENed OUTPUT. Use the OPEN verb in the
following format:

OPEN [Type of Access] Filename.

Two types of access include INPUT and OUTPUT; there are other types, but we need
only these two. The following code shows an example.

PROCEDURE DIVISION.
PROG.
[other code]
OPEN INPUT INFILE.
OPEN OUTPUT OUTFILE.

Notice again that the names used with the verbs are those associated with both the
SELECT and FD entries.

We could rewrite the above code as follows, where the words have been spaced for
clarity.

OPEN INPUT INFILE


OUTPUT OUTFILE.

OPEN can be used to open as many files as necessary in one statement.

There is an alternative to OUTPUT for sequential files. You may remember that we
mentioned that by default COBOL clears output files if they exist. This is what OPEN
OUTPUT does. If you instead write OPEN EXTEND, a pointer is positioned at the end of
any existing records, and new records are added to the end of the file.

Use the OPEN statement to identify which files should be accessed and to make them
available to your program. If you do not OPEN a file, any program actions on the file
generate an error.

The CLOSE Verb

Logically, CLOSE statements belong at the end of the program logic, just as OPEN
statements belong at the beginning. The following code shows how we might use the
CLOSE verb.

Información Confidencial | Información Propietaria de Gladius Technology | Página 76 de


176
CLOSE INFILE.
CLOSE OUTFILE.

However, the following code shows how it would normally be written.

CLOSE INFILE
OUTFILE.

CLOSE, like OPEN, can be used on many files at once. While files can be opened in
different ways, they are all closed in the same way. So, the format of the CLOSE
statement is simpler. Closing a file releases the file back to the operating system so that
other programs can use it.

The READ Verb

Having opened the files, the program needs to know how to read a record. In fact the
program does not read a record; it reads a file. At the same time, the program should
indicate what happens if the read fails because there aren't any, or any more, records.
The following code shows how to use the READ verb and how to add an action when
the program reaches the end of the file.

READ INFILE
AT END MOVE 1 TO WS-END-OF-FILE
END-READ

In other words, whenever we write a READ statement for a sequential file, we always
specify the actions to be taken if the READ fails.

In the above case, the following actions apply:

• If the READ succeeds, that is, if there is a record or another record, the contents
of that record will go into the 01 description specified. In our case, the contents
go into the record description of INREC as shown in our code previously. (This
area is known as the record buffer.) WS-END-OF-FILE will not be touched.
• If the read fails, WS-END-OF-FILE will be set to 1. The contents of INREC may be
undefined (if there has never been a record) or those of the last record read (if
there have been previous records). Logically, we should not look at them
anyway, because there is no new record to read.

Why do we read the file, rather than the record? It is possible that a file may contain
records of two or more types. Because this is an input file, we have no idea what
record type is coming in next. All we can do is read the file. We shall examine multiple
record types later.

The WRITE Verb

Información Confidencial | Información Propietaria de Gladius Technology | Página 77 de


176
The converse of READ is WRITE. While the verb READ moves data from the file to
storage, WRITE moves data from storage to a record in the file. Unlike READ's target,
the program writes a record, not a file.

MOVE IN-NAME TO OUT-NAME.


MOVE IN-DOB TO OUT-DOB.
WRITE OUTREC.

Why do we WRITE a record? For the same reason that we READ a file: multiple record
types. Since this is output, we are creating the record. If there more than one type
exists, we need to specify which one we are writing. Again, we shall discuss this later.

Notice above that prior to WRITEing, we need to have built up the output record in its
record buffer. The data names on the input and output buffers have been made similar,
purely to lessen the chance of making mistakes when moving values.

6.8. Putting It All Together


Let's now look at coding the example program from Module 5, where an input file
contains two types of record: A and B. Previously, we had to write pseudo-code for the
file-handling elements. Now, we can code everything in full, as shown in the following
program.

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE61.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM-370.
OBJECT-COMPUTER. IBM-370.
INPUT-OUTPUT SECTION .
FILE-CONTROL.
***************************************************
* Notice in following Select statements that the
* names assigned to the files are the same names
* used in the FD statements; INFILE and OUTFILE.
***************************************************
SELECT INFILE ASSIGN "INFILE61.DAT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS INFILE-FILE-STATUS.
SELECT OUTFILE ASSIGN "OUTFILE61.DAT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS OUTFILE-FILE-STATUS.
DATA DIVISION.
FILE SECTION.
********************************
* A file-handling program
********************************
FD INFILE .
01 INREC .
03 INREC-TYPE PIC X .

Información Confidencial | Información Propietaria de Gladius Technology | Página 78 de


176
03 INREC-NAME PIC X(20) .
03 INREC-GENDER PIC X .
FD OUTFILE .
01 OUTREC .
03 OUTREC-NAME PIC X(20) .
03 OUTREC-GENDER PIC X .
WORKING-STORAGE SECTION .
01 WS-END-OF-FILE PIC 9 VALUE 0 .
88 END-OF-FILE VALUE 1 .
01 WS-TYPE-B-COUNTER PIC 9(6) VALUE 0 .
01 INFILE-FILE-STATUS PIC X(02).
01 OUTFILE-FILE-STATUS PIC X(02).
PROCEDURE DIVISION.
*******************************************************
* In the following Perform statement, both input and
* output files are opened; INFILE and OUTFILE.
* An OPEN is required before a file can be READ.
*******************************************************
PROG SECTION.
PERFORM INIT-PARA.
PERFORM BOD-PARA.
PERFORM END-PARA.

INIT-PARA SECTION.
DISPLAY "START OF PROGRAM".
INITIALIZE WS-END-OF-FILE
WS-TYPE-B-COUNTER
*******************************************************
* Once the file is open, OPEN INPUT INFILE, the data
* can be accessed using the data names defined
* in the '01 INREC' under FD entry.
*******************************************************
OPEN INPUT INFILE
IF INFILE-FILE-STATUS NOT = ZERO THEN
DISPLAY "INVALID INFILE FILE"
INFILE-FILE-STATUS
GOBACK
END-IF
OPEN OUTPUT OUTFILE.
IF OUTFILE-FILE-STATUS NOT = ZERO THEN
DISPLAY "INVALID OUTFILE FILE"
OUTFILE-FILE-STATUS
GOBACK
END-IF
PERFORM READ-FILE.
INIT-PARA-EXIT.
EXIT.
BOD-PARA SECTION.
PERFORM UNTIL END-OF-FILE
IF INREC-TYPE = "A"
PERFORM TYPE-A-ACTIONS
ELSE
PERFORM TYPE-B-ACTIONS
END-IF
PERFORM READ-FILE
END-PERFORM.
BOD-PARA-EXIT.
EXIT.

Información Confidencial | Información Propietaria de Gladius Technology | Página 79 de


176
END-PARA SECTION.
DISPLAY WS-TYPE-B-COUNTER
" 'B' RECORDS READ" .
CLOSE INFILE
OUTFILE .
END-PARA-EXIT.
GOBACK.
********************************************************
* This SECTION is PERFORMED from the SECTION
* "BOD-PARA". It is performed for each record in the
* file. Notice, that since the input file INFILE has
* been opened, the data names can be used to
* reference the data on the records, i.e. INREC-
* TYPE,INREC-NAME
********************************************************
TYPE-A-ACTIONS SECTION.
MOVE INREC-NAME TO OUTREC-NAME .
MOVE INREC-GENDER TO OUTREC-GENDER .
WRITE OUTREC .
TYPE-A-ACTIONS-EXIT.
EXIT.
TYPE-B-ACTIONS SECTION.
ADD 1 TO WS-TYPE-B-COUNTER .
TYPE-B-ACTIONS-EXIT.
EXIT.
READ-FILE SECTION.
READ INFILE
AT END SET END-OF-FILE TO TRUE
END-READ.
READ-FILE-EXIT.
EXIT.

The finished code is based strictly on the program structure we saw previously, and this
means that there is only a small amount of code in each paragraph. This means that it
is both easy to follow and to debug if any logic problems are detected later. In fact, if
the program is designed correctly, logic problems cannot occur, except through simple
transcription errors, such as writing the wrong paragraph in a PERFORM statement.

6.9. The Full READ Statement


The READ statement also has an optional NOT AT END clause and an END-READ, similar
to the AT END clause. The following code shows the READ NOT AT END and the END-
READ.

READ INFILE
AT END MOVE 1 TO WS-EOF
NOT AT END PERFORM GOT-A-RECORD
END-READ.
READ INFILE
AT END SET END-OF-FILE TO TRUE
NOT AT END PERFORM GOT-A-RECORD
END-READ.

Información Confidencial | Información Propietaria de Gladius Technology | Página 80 de


176
6.10. READ INTO and WRITE FROM
After reading a record, the program can immediately move its contents somewhere
else. Alternatively, we might design the program to move other elements, for example,
a working-storage group field to the output record buffer. Then, write it. The following
code includes a MOVE immediately after READ.

READ INFILE
AT END [ ]
MOVE INREC TO WS-REC
END-READ.

MOVE WS-REC TO OUTREC


WRITE OUTREC.
This can be done more simply by writing the following code.
READ INFILE
AT END [ ]
WRITE OUTREC FROM WS-REC
END-READ.

6.11. More Examples


Let's look at a couple of more practical examples. In the first one, the input record is 30
bytes long, but we only want the last 18 bytes of this on the output record.

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE62.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION .
FILE-CONTROL.
SELECT INFILE ASSIGN "INFILE62.DAT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS INFILE-FILE-STATUS.

SELECT OUTFILE ASSIGN "OUTFILE62.DAT"


ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS OUTFILE-FILE-STATUS.
DATA DIVISION.
FILE SECTION.

FD INFILE .
01 INREC PIC X(30) .
FD OUTFILE .
01 OUTREC PIC X(18).

WORKING-STORAGE SECTION .

01 WS-END-OF-FILE PIC 9.
88 END-OF-FILE VALUE 1 .
01 INFILE-FILE-STATUS PIC X(02).
01 OUTFILE-FILE-STATUS PIC X(02).

Información Confidencial | Información Propietaria de Gladius Technology | Página 81 de


176
01 WS-REC.
05 FILLER PIC X(12) .
05 WS-USEFUL-PART PIC X(18) .

PROCEDURE DIVISION .
PROG SECTION.
PERFORM INIT-PARA .
PERFORM BOD-PARA .
PERFORM END-PARA .

INIT-PARA SECTION.
DISPLAY "START OF PROGRAM" .
INITIALIZE WS-END-OF-FILE
OPEN INPUT INFILE
IF INFILE-FILE-STATUS NOT = ZERO
DISPLAY "INVALID OUTFILE FILE"
INFILE-FILE-STATUS
GOBACK
END-IF
OPEN OUTPUT OUTFILE .
IF OUTFILE-FILE-STATUS NOT = ZERO
DISPLAY "INVALID OUTFILE FILE"
OUTFILE-FILE-STATUS
GOBACK
END-IF
READ INFILE INTO WS-REC
AT END SET END-OF-FILE TO TRUE
END-READ.
INIT-PARA-EXIT.
EXIT.
BOD-PARA SECTION.
PERFORM UNTIL END-OF-FILE
Display "WS-USEFUL-PART = " WS-USEFUL-PART
WRITE OUTREC FROM WS-USEFUL-PART
* WRITE OUTREC FROM inrec
READ INFILE INTO WS-REC
AT END SET END-OF-FILE TO TRUE
END-READ
END-PERFORM.
BOD-PARA-EXIT.
EXIT.
END-PARA SECTION.
CLOSE INFILE
OUTFILE.
END-PARA-EXIT.
GOBACK.

This performs exactly as we want.

If we had wanted only the first 18 bytes, this would have been even simpler. We would
keep the same record buffers (INREC and OUTREC) as above, but rewrite the code as
shown in the following program.

READ INFILE
AT END [ ]

Información Confidencial | Información Propietaria de Gladius Technology | Página 82 de


176
END-READ.
[other code]
WRITE OUTREC FROM INREC

There is no need for an intermediate working-storage field. The MOVE implicit in


WRITE…FROM truncates the record in the way we want.

6.12. Multiple Record Types


It is very common to find a file with more than one type of record. COBOL can cope
with this easily, as long as there is some way of determining the record type.

Let's look at an example used for personnel information. Our input file can have one of
two record types: Type A or Type B.

Let's create the Type A file that appears as this:

"A" name salary emp_no

This would require the following:

• 1 character, set to 'A'


• 20 characters, representing a person's name
• 7 characters, representing a person's salary (5 digits, plus two decimal places)
• 6 characters, representing a person's employee number (6 digits)

Let's create the Type B file as follows:

"B" emp_no leaving_date

• 1 character, set to 'B'


• 6 characters, representing a person's employee number
• 8 characters, representing a leaving date (8 digits)

The following illustration shows the information diagrammatically.

Información Confidencial | Información Propietaria de Gladius Technology | Página 83 de


176
The program needs two definitions of the same record buffer. This is very simple to
accomplish as shown in the following code, where the entries are in the DATA
DIVISION.

DATA DIVISION.
FILE SECTION.
FD INFILE.
* Type 'A' record
01 INREC-TYPE-A.
03 INREC-TYPE PIC X.
03 INREC-NAME PIC X(20).
03 INREC-SALARY PIC 9(5)V99.
03 INREC-EMP-NO-A PIC 9(6).
* Type 'B' record
01 INREC-TYPE-B.
03 INREC-TYPE-B PIC X.
03 INREC-EMP-NO-B PIC 9(6).
03 INREC-LEAVING-DATE PIC 9(8).

In the Working-Storage section, two such 01s would signify that two separate items or
groups were being declared. That is not the case here.

The 01s map onto the same record. This is called implicit redefinition and makes the
handling of multiple record types very simple.

Let us assume that a record is read in. Which definition of the record – which 01 level –
does it end up in, A or B? The answer is both.

Having multiple 01 record types defined is like having many windows all looking onto
the same data – each allowing us to see the data in a different way.

To know which definition we should use, we just need to test the first byte of the
record, which in the previous program is given a name only in the first definition ("A"
or "B"). We can always test that byte using the name INREC-TYPE. If we have a record
type A, we use the fields appropriate to that record, and if type B, those fields instead.

Información Confidencial | Información Propietaria de Gladius Technology | Página 84 de


176
Input Record

Before looking at multiple output record types, let us design and code a program that
uses multiple input record types.

Let us say that we want to design a program that will read in a file of records and then
deal with them in different ways depending on the type of record we find. The
following describes the input record.

• The input file may have any number of records (including 0).
• There are two types of input records: type A and type B. (There is a PIC X field
on the record that we can test.)
• If we find a type A record, we create an output record on one file based on that
record and write it out. We also add 1 to a counter.
• If we find a type B record, we create an output record on another file based on
that record and write it out. We add 1 to a (different) counter.

We can diagram the input file in the following way.

This time there are two output files, as shown in the next illustration. Each record in
each file corresponds to one of the input records.

Información Confidencial | Información Propietaria de Gladius Technology | Página 85 de


176
The following program structure is familiar, though there are more actions this time.

The actions are shown below.

Información Confidencial | Información Propietaria de Gladius Technology | Página 86 de


176
This gives us the COBOL program seen next.

The counters have been set up as elementary items, set to binary zero by MOVING THE
VALUE LOW-VALUES TO the group field.

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE63.
AUTHOR. TRAINING.
INSTALLATION. MARS.
DATE-WRITTEN. 18/10/2005.
DATE-COMPILED.
SECURITY. MICROFOCUS.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM-370.
OBJECT-COMPUTER. IBM-370.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INFILE ASSIGN "INFILE63.DAT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS INFILE-FILE-STATUS.

SELECT OUTFILE-A ASSIGN "OUTA63.DAT"


ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS OUTA-FILE-STATUS.

SELECT OUTFILE-B ASSIGN "OUTB63.DAT"


ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS OUTB-FILE-STATUS.

DATA DIVISION.
FILE SECTION.
FD INFILE.
01 INREC-TYPE-A.
03 INREC-TYPE PIC X.
88 TYPE-A-RECORD VALUE "A".
03 INREC-NAME PIC X(20).
03 INREC-SALARY PIC 9(5)V99.
03 INREC-EMP-NO-A PIC 9(6).

01 INREC-TYPE-B.
03 FILLER PIC X.
03 INREC-EMP-NO-B PIC 9(6).
03 INREC-LEAVING-DATE PIC 9(8).

FD OUTFILE-A.
01 OUTREC-A.
03 OUTREC-NAME PIC X(20).
03 OUTREC-EMP-NO-A PIC 9(6).
FD OUTFILE-B.
01 OUTREC-B.

Información Confidencial | Información Propietaria de Gladius Technology | Página 87 de


176
03 OUTREC-EMP-NO-B PIC 9(6).
03 OUTREC-LEAVING-DATE PIC 9(8).
WORKING-STORAGE SECTION.
01 OUTB-FILE-STATUS PIC X(02).
01 OUTA-FILE-STATUS PIC X(02).
01 INFILE-FILE-STATUS PIC X(02).

01 WS-END-OF-FILE-FLAG PIC 9.
88 END-OF-FILE VALUE 1.

01 WS-COUNTERS.
03 WS-A-COUNTER PIC 9(4).
03 WS-B-COUNTER PIC 9(4).
03 WS-C-COUNTER PIC 9(4).

PROCEDURE DIVISION.
PROG SECTION.
PERFORM INIT-PARA.
PERFORM BOD-PARA.
PERFORM END-PARA.

INIT-PARA SECTION.
DISPLAY "PROGRAM STARTING".
MOVE ZERO TO WS-COUNTERS
MOVE SPACE TO OUTB-FILE-STATUS
OUTA-FILE-STATUS
INFILE-FILE-STATUS
OPEN INPUT INFILE
IF INFILE-FILE-STATUS NOT = ZERO
DISPLAY "INVALID INFILE FILE"
INFILE-FILE-STATUS
GOBACK
END-IF
OPEN OUTPUT OUTFILE-A
IF OUTA-FILE-STATUS NOT = ZERO
DISPLAY "INVALID OUTFILEa FILE"
OUTA-FILE-STATUS
GOBACK
END-IF
OPEN OUTPUT OUTFILE-B
IF OUTB-FILE-STATUS NOT = ZERO
DISPLAY "INVALID OUTFILEb FILE"
OUTB-FILE-STATUS
GOBACK
END-IF
PERFORM READ-FILE.
INIT-PARA-EXIT.
EXIT.
BOD-PARA SECTION.
PERFORM UNTIL END-OF-FILE
IF TYPE-A-RECORD THEN
PERFORM TYPE-A-RECORDS
ELSE
PERFORM TYPE-B-RECORDS
END-IF
PERFORM READ-FILE
END-PERFORM.
BOD-PARA-EXIT.

Información Confidencial | Información Propietaria de Gladius Technology | Página 88 de


176
EXIT.
END-PARA SECTION.
DISPLAY "NUMBER OF TYPE A RECORDS " WS-A-COUNTER.
DISPLAY "NUMBER OF TYPE B RECORDS " WS-B-COUNTER.
CLOSE INFILE
OUTFILE-A
OUTFILE-B.
END-PARA-EXIT.
GOBACK.

TYPE-A-RECORDS SECTION.
MOVE INREC-NAME TO OUTREC-NAME

MOVE INREC-EMP-NO-A TO OUTREC-EMP-NO-A

WRITE OUTREC-A.
ADD 1 TO WS-A-COUNTER.
TYPE-A-RECORDS-EXIT.
EXIT.

TYPE-B-RECORDS SECTION.
MOVE INREC-EMP-NO-B TO OUTREC-EMP-NO-B.
MOVE INREC-LEAVING-DATE TO OUTREC-LEAVING-DATE.
WRITE OUTREC-B.
ADD 1 TO WS-B-COUNTER.
TYPE-B-RECORDS-EXIT.
EXIT.
READ-FILE SECTION.
READ INFILE
AT END SET END-OF-FILE TO TRUE
END-READ.
READ-FILE-EXIT.
EXIT.

Output Record Types

Creating multiple output record types is reasonably straightforward. The output


appears something like the following code.

FD OUTFILE.
01 OUTREC-1.
03 OUTREC-NAME PIC X(20).
03 OUTREC-EMP-NO PIC 9(6).
01 OUTREC-2.
03 OUTREC-COUNTER PIC 9(4).

The records could be pictured like the following illustration.

Información Confidencial | Información Propietaria de Gladius Technology | Página 89 de


176
A full example should make this clear. Let us assume that we are writing a program that
reads in a file of records and does the following:

• The input file may have any number of records (including 0).
• All input records are treated the same way, and one normal output record is
created for each input record (so that reading 1000 input records should
guarantee that there are 1000 output records)
• As a safeguard to ensure data integrity, we need to write a final record to the
output file, containing a count of all records written (apart from itself). In other
words, if this last record contains 500, then there should be 501 records on the
file. If the input file should happen to be empty, then the output file will contain
this one special record, containing the number zero.

In terms of designing the program, the input file can be represented very simply, as
shown next.

The output file is interesting, consisting of a sequence. First, there is an iteration of


normal records (that number may be zero), followed by the final record, which is
always present, as diagramed below.

Información Confidencial | Información Propietaria de Gladius Technology | Página 90 de


176
Each ordinary output record corresponds to an input record, and the final record will
need to be written at the end.

This produces the following program structure.

The actions are shown below.

Información Confidencial | Información Propietaria de Gladius Technology | Página 91 de


176
This results in the following program. Just for variety, this time we have used a PIC X
flag instead of a PIC 9. Recall that we READ a file (because we don't know what record
type is coming in), yet WRITE a record (as we have to be able to specify just what is
written out).

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE64.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INFILE ASSIGN "INFILE64.DAT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS INFILE-FILE-STATUS.
SELECT OUTFILE ASSIGN "OUTFILE64.DAT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS OUTFILE-FILE-STATUS.
DATA DIVISION.
FD INFILE.
01 INREC.
03 INREC-EMP-NO PIC 9(6).
03 INREC-START-DATE PIC 9(8).
03 INREC-NAME PIC X(20).
FD OUTFILE.
01 OUTREC-1.
03 OUTREC-NAME PIC X(20).
03 OUTREC-EMP-NO PIC 9(6).
01 OUTREC-2.
03 OUTREC-COUNTER PIC 9(4).
WORKING-STORAGE SECTION.

01 WS-END-OF-FILE PIC 9.
88 END-OF-FILE VALUE 1.
01 WS-RECORD-COUNTER PIC 9(4).
01 OUTFILE-FILE-STATUS PIC X(02).
01 INFILE-FILE-STATUS PIC X(02).

PROCEDURE DIVISION.
PROG SECTION.
PERFORM INIT-PARA.
PERFORM BOD-PARA.
PERFORM END-PARA.
*******************************************************
Once the file is open, OPEN INPUT INFILE, the data
can be accessed using the data names defined
in the '01 INREC' under FD entry.
********************************************************
INIT-PARA SECTION.
DISPLAY "PROGRAM STARTING".
MOVE ZERO TO WS-END-OF-FILE
WS-RECORD-COUNTER
MOVE SPACE TO OUTFILE-FILE-STATUS
INFILE-FILE-STATUS
OPEN INPUT INFILE
IF INFILE-FILE-STATUS NOT = ZERO THEN

Información Confidencial | Información Propietaria de Gladius Technology | Página 92 de


176
DISPLAY "INVALID INFILE FILE"
INFILE-FILE-STATUS
GOBACK
END-IF
OPEN OUTPUT OUTFILE
IF OUTFILE-FILE-STATUS NOT = ZERO THEN
DISPLAY "INVALID OUTFILE FILE"
OUTFILE-FILE-STATUS
GOBACK
END-IF
PERFORM READ-FILE.
INIT-PARA-EXIT.
EXIT.
BOD-PARA SECTION.
PERFORM UNTIL END-OF-FILE
MOVE INREC-EMP-NO TO OUTREC-EMP-NO
MOVE INREC-NAME TO OUTREC-NAME
WRITE OUTREC-1
ADD 1 TO WS-RECORD-COUNTER
PERFORM READ-FILE
END-PERFORM.
BOD-PARA-EXIT.
EXIT.
END-PARA SECTION.
MOVE SPACE TO OUTREC-1
MOVE WS-RECORD-COUNTER TO OUTREC-COUNTER.
WRITE OUTREC-2.
DISPLAY "ALL DONE!".
CLOSE INFILE
OUTFILE.
END-PARA-EXIT.
GOBACK.
********************************************************
This SECTION is PERFORMED from the SECTION
"BOD-PARA".
It is performed for each record in the file.
Notice, that since the input file INFILE has been
opened, the data names can be used to
reference the data on the records, i.e. INREC-TYPE,
INREC-NAME.
********************************************************
PROCESS-REC SECTION.
MOVE INREC-EMP-NO TO OUTREC-EMP-NO.
MOVE INREC-NAME TO OUTREC-NAME.
WRITE OUTREC-1.
ADD 1 TO WS-RECORD-COUNTER.
PROCESS-REC-EXIT.
EXIT.
READ-FILE SECTION.
READ INFILE
AT END SET END-OF-FILE TO TRUE
END-READ.
READ-FILE-EXIT.
EXIT.

Información Confidencial | Información Propietaria de Gladius Technology | Página 93 de


176
6.13. Summary
In this module we have examined the following topics:

• The Environment Division and Data Division entries necessary in a COBOL


program to handle sequential files.
• The way in which files are OPENed and CLOSEd.
• The format of a sequential READ statement, including testing for an end-of-file
condition.
• The format of a WRITE statement.
• The way in which COBOL deals with multiple record types on the same file.
• The design and coding of COBOL programs that handle sequential files.

6.14. Exercise: Reformatting Data


Introduction

The purpose of this program is to read the employee records and create two files. One
will contain the 'normal' employee records, TYPE N. This file will be formatted different
than the employee record.

The second file created will contain all records on the employee file and a special
record for each employee leaving the company, TYPE X.

Both types of records created will be formatted different than the employee record.

This program will also count and display the number of records written to both output
files.

Details

1. Start your editor.

2. Open PROGRAM6 located in X:\CLASS\MODULE6\NETX

3. Design and code a COBOL program to do the following:

• Read in a file of records, and then deal with them in different ways depending on the type of
record found. The input file may have any number of records (including 0).
• The input records will either be of type N (normal) or type X (leaving).
• An input record type N will have a one-character field for type, a twenty-character field for the

Información Confidencial | Información Propietaria de Gladius Technology | Página 94 de


176
name, a seven-digit field for salary (five digits, two decimal places), and finally, a six-digit
employee number.
• An input record type X will have a one-character field for type, a six-digit employee number, and
an eight-digit leaving date.
• There will be two output files, one dealing with the type N input records and one for the type X
input records.
• The first output file records will have all the fields from the type N input record (apart from the
'type' field), preceded by a four-digit field containing the record number. (You can assume that
there are never going to be more than 9999 type N records on the input file.)
• The second output file will contain two types of records, a normal record and a special record.
• The normal records will contain all the fields found on the type X input records, apart from the
single character showing 'type'.
• The special record will show how many type X records were found. This number could be zero,
meaning that this last record will always be written to the file.

4. Some sort of start-up message should display at the beginning of the program. Record counters for

both record types should display at the end.

5. Save the program in the X:\CLASS\MODULE\NETX directory and provide the program name

PROGRAM6.

6. Compile and test the program.

The output from the Run is

PROGRAM STARTING
NUMBER OF 'N' RECORDS PROCESSED: 0002
NUMBER OF 'X' RECORDS PROCESSED: 0001
ALL DONE!
Output-N
0001Vlad the Impaler 6587000228279
0002Joanna Lumley 4456977025611
Output X
10000018112005
0001

7. Module 7: Decision Logic


Implementing the required decision logic effectively means higher quality programs,
shorter testing time, and better maintenance productivity. Here, we understand the
different conditional constructs available in COBOL and understand when and how to
use each of them.

Información Confidencial | Información Propietaria de Gladius Technology | Página 95 de


176
7.1. Objectives
Upon successful completion of this module, you will be able to:

• Use the verb EVALUATE and the IF condition as well as the Level 88 construct in
testing conditions.
• Describe the different types of conditions.
• Explain the advantages and disadvantages of different ways of condition testing.
• Write a COBOL program using different types of condition testing.

7.2. Decisions in Programs


Most programming requires making a choice. For example, if one condition occurs, the
program should do this task. If a different condition occurs, the program should do a
different task.

In COBOL the flow of a program is controlled almost entirely by IF-ELSE statements, the
PERFORM verb, and the GO TO verb. Use the IF verb to make decisions, which change
the flow of a program.

7.3. The IF Statement


Let's look at an IF-ELSE statement. The IF verb has the following format:

IF [condition] (THEN)
[do one or more statements]
or
[NEXT SENTENCE] OR [CONTINUE]
(ELSE
[do one or more statements]
or
[NEXT SENTENCE])
OR
[CONTINUE]
(END-IF).

The entries in brackets [ ] are optional.

This code indicates that if a is true, then perform an action. Otherwise (if the condition
is false), do a different action. Lastly, END-IF marks the end of the conditional
statement.

We have met this statement, both with and without the ELSE.
NEXT SENTENCE means drop through to whatever follows this IF statement. It is less

Información Confidencial | Información Propietaria de Gladius Technology | Página 96 de


176
commonly used. Use it with an IF statement that ends with a period, but not with a
statement that ends with an END-IF.

7.4. Condition Statements


We can test the following different types of conditions used with the IF statement.

• Relational conditions
• Class conditions
• Sign conditions
• Condition-name conditions (Level 88s)
• Compound conditions
• Nested conditions

Types of Data Affect Evaluating Conditions

Different types of data are evaluated differently. Alphanumeric data items and literals
are evaluated from left to right and spaces on the end are not evaluated. "ABC" is the
same as "ABC ". Numeric data is compared by values; 3.00 is equal to 3.

Relational Conditions

In previous modules we used relational conditions, when two operands are compared
with operators such as =, >, or <. Here is a sample evaluating whether WS-NUMBER is
greater than 4.

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE71.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-NUMBER PIC 9(4)V99.
PROCEDURE DIVISION.
MAINLINE SECTION.
PERFORM INIT-PARA.
PERFORM LOOP-PARA.
PERFORM END-PARA.

INIT-PARA SECTION.
DISPLAY "A SIMPLE NUMEBER TEST".
INIT-PARA-EXIT.
EXIT.
LOOP-PARA SECTION.
DISPLAY "PLEASE ENTERED THE NUMBER?".
ACCEPT WS-NUMBER.
IF WS-NUMBER > 4 THEN

Información Confidencial | Información Propietaria de Gladius Technology | Página 97 de


176
DISPLAY "WS-NUMBER GREATER THAN 4"
END-IF
IF WS-NUMBER NOT > 4 THEN
DISPLAY "WS-NUMBER NOT GREATER THAN 4"
END-IF.
IF WS-NUMBER NOT = 6 THEN
DISPLAY "WS-NUMBER NOT EQUAL TO 6"
END-IF.
IF WS-NUMBER UNEQUAL 6 THEN
DISPLAY "WS-NUMBER UNEQUAL TO 6"
END-IF.
IF WS-NUMBER IS NOT EQUAL TO 6 THEN
DISPLAY "WS-NUMBER IS NOT EQUAL TO 6"
END-IF.
LOOP-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "MANY THANKS!".
END-PARA-EXIT.
GOBACK.

We can also use NOT to make each statement negative, as shown in the fourth line of
the previous code.

In some cases we might want to determine whether a data is not equal to something.
No equivalent exists for <>, which means not equal; however, we could express it in
one of the following ways.

IF WS-TOTAL NOT = 6 THEN


IF WS-TOTAL UNEQUAL 6 THEN
IF WS-TOTAL [IS] NOT EQUAL [TO] 6 THEN

Testing numbers is easy, but what about strings of different lengths? Which is greater,
"FRED" or "FREDA"? Fortunately the answer is predictable and consistent. The two
strings are tested character by character, starting at the left. For the first four bytes
"FRED" and "FREDA" are equal. At the fifth byte, "A" is compared with space, since
"FRED" does not contain any more real characters that can be checked. (This still
happens if the string holding "FRED" has no bytes that are unoccupied.) Since hex 20
represents space in the ASCII character set, and hex 41 represents "A", "FRED" is less
than "FREDA".

Class Conditions

Class conditions allow the programmer to test for a specific type of data, for example,
ALPHABETIC or NUMERIC. Such a test would use the following format.

Exercise ( Check to numeric and entered a negative number )

Información Confidencial | Información Propietaria de Gladius Technology | Página 98 de


176
IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE72.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
01 WS-NUMBER-X PIC X(02).
01 WS-NUMBER-N PIC 9(02).
PROCEDURE DIVISION.
MAINLINE SECTION.
PERFORM INIT-PARA.
PERFORM LOOP-PARA.
PERFORM END-PARA.
INIT-PARA SECTION.
DISPLAY "A SIMPLE NUMEBER TEST".
INIT-PARA-EXIT.
EXIT.
LOOP-PARA SECTION.
DISPLAY "PLEASE ENTERED THE NUMBER?".
ACCEPT WS-NUMBER-X.
IF WS-NUMBER-X IS ALPHABETIC THEN
DISPLAY "NUMBER IS ALPHABETIC "
END-IF
IF WS-NUMBER-X IS NUMERIC THEN
MOVE WS-NUMBER-X TO WS-NUMBER-N
DISPLAY "NUMBER IS NUMERIC"
IF WS-NUMBER-N IS NEGATIVE THEN
DISPLAY "NUMBER IS NEGATIVE"
END-IF
END-IF
LOOP-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "MANY THANKS!".
END-PARA-EXIT.
GOBACK.

Again, use NOT to reverse the test.

Sign Conditions

Use sign conditions with numeric fields. Sign conditions allow the programmer to test
for POSITIVE, NEGATIVE, or ZERO. The following code shows how you could test for a
negative value.

…[for example]
01 WS-CUSTOMER-BALANCE PIC S9(5)V99.

IF WS-CUSTOMER-BALANCE (IS) NEGATIVE


PERFORM SEND-THREATENING-LETTER.

Condition-name Conditions (Level 88s)

Información Confidencial | Información Propietaria de Gladius Technology | Página 99 de


176
To improve IF condition tests, use Level 88, a special level number in COBOL programs.
A level 88 is always associated with another variable. It may seem on first glance as if
we are setting a VALUE clause; however, we are not. Instead of moving a value to a
field, we are declaring one or more values against which to test. This makes the IF
statement shorter and possibly more meaningful.

Level 88 conditions use a condition name that can be tested. Condition names are also
called flags. For example, if FEMALE (the condition name), then perform the next
statement. Condition names are coded by writing the condition name followed by
information that indicates what value makes the condition true. For example, a
program might read a file and encounter a field that indicates gender as "F" or "M". In
the following statement, FEMALE is true if the value is "F".

88 FEMALE VALUE "F".

The following code shows how to reference the INREC-GENDER field by using the field
name FEMALE or MALE. If FEMALE, the value of INREC-GENDER is equal to "F".

Exercise ( Add code for both male and female)

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE73.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-GENDER PIC X.
88 FEMALE value "F" "f".
88 MALE value "M" "m".
PROCEDURE DIVISION.
MAINLINE SECTION.
PERFORM INIT-PARA.
PERFORM LOOP-PARA.
PERFORM END-PARA.

INIT-PARA SECTION.
DISPLAY "A SIMPLE GENDER TEST".
INIT-PARA-EXIT.
EXIT.
LOOP-PARA SECTION.
DISPLAY "PLEASE ENTERED MALE OR FEMALE ?"
ACCEPT WS-GENDER.
IF FEMALE THEN
DISPLAY "Code entered is female"
END-IF
IF MALE THEN
DISPLAY "Code entered is male"
END-IF.
LOOP-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "MANY THANKS!".
END-PARA-EXIT.

Información Confidencial | Información Propietaria de Gladius Technology | Página 100 de


176
GOBACK.

Using Level 88 for set several values against a field

Use 88 levels also to set several valid values against a field, as shown in the following
code.

Exercise (Convert to a evaluate statement)

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE74.
AUTHOR. TRAINING.
INSTALLATION. MARS.
DATE-WRITTEN. 18/10/2005.
DATE-COMPILED.
SECURITY. MICROFOCUS
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM-370.
OBJECT-COMPUTER. IBM-370.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
01 INREC.
03 INREC-TYPE PIC X.
88 VALID-TYPES VALUE
"A" THRU "E" "G" "Z".
88 CEO VALUE "A".
88 VICE-PRESIDENT VALUE "B".
88 SENIOR-MANAGER VALUE "C".
88 MANAGER VALUE "D".
88 TEAM-MEMBER VALUE "E".
88 JANITOR VALUE "G".
88 TRAINER VALUE "Z".
03 INREC-SALARY PIC 9(6)V99.
PROCEDURE DIVISION.
MAINLINE SECTION.
PERFORM INIT-PARA.
PERFORM LOOP-PARA.
PERFORM END-PARA.
INIT-PARA SECTION.
DISPLAY "A EMPLOYEE SALARY".
INIT-PARA-EXIT.
EXIT.
LOOP-PARA SECTION.
DISPLAY "PLEASE ENTER EMPLOYEE CODE?"
ACCEPT INREC-TYPE .
IF NOT VALID-TYPES
DISPLAY "INVALID RECORD TYPE "
INREC-TYPE "!"
GOBACK
END-IF
IF CEO
MOVE 100 TO INREC-SALARY

Información Confidencial | Información Propietaria de Gladius Technology | Página 101 de


176
DISPLAY "THE SALARY FOR THE CEO IS "
INREC-SALARY
END-IF
IF VICE-PRESIDENT
MOVE 90 TO INREC-SALARY
DISPLAY
"THE SALARY FOR THE VICE-PRESIDENT IS "
INREC-SALARY
END-IF
IF SENIOR-MANAGER
MOVE 80 TO INREC-SALARY
DISPLAY
"THE SALARY FOR THE SENIOR-MANAGER IS "
INREC-SALARY
END-IF
IF MANAGER
MOVE 70 TO INREC-SALARY
DISPLAY "THE SALARY FOR THE MANAGER IS "
INREC-SALARY
END-IF
IF TEAM-MEMBER
MOVE 60 TO INREC-SALARY
DISPLAY "THE SALARY FOR THE TEAM-MEMBER IS "
INREC-SALARY
END-IF
IF JANITOR
MOVE 50 TO INREC-SALARY
DISPLAY "THE SALARY FOR THE JANITOR IS "
INREC-SALARY
END-IF
IF TRAINER
MOVE 40 TO INREC-SALARY
DISPLAY "THE SALARY FOR THE TRAINER IS "
INREC-SALARY
END-IF
LOOP-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "MANY THANKS!".
END-PARA-EXIT.
GOBACK.

The previous code shows several level 88s used on one field, firstly for validation. If the
field is not set to any of "A" to "E" ("THRU" can also be spelled "THROUGH"), "G", or
"Z", then the record is invalid. Once that test has been carried out, the field can be
tested for separate values, each of which can have a meaningful name.

Such use of level 88s can help avoid compound conditions, described in the next
section.

Using Level 88 to signify end of file

One very common use of the 88 levels is on the flag used to signify the end of the file,
as shown in the following code. Using LEVEL 88's encourages more English-like

Información Confidencial | Información Propietaria de Gladius Technology | Página 102 de


176
statements in the PROCEDURE DIVISION. The code "PERFORM PROCESS-REC UNTIL NO-
MORE-RECORDS" is clearer than "PERFORM PROCESS-REC UNTIL WS-END-OF-FILE is
not equal to 0."

Exercise ( add checking for valid record )

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE75.
AUTHOR. TRAINING.
INSTALLATION. MARS.
DATE-WRITTEN. 18/10/2005.
DATE-COMPILED.
SECURITY. MICROFOCUS.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM-370.
OBJECT-COMPUTER. IBM-370.

INPUT-OUTPUT SECTION .
FILE-CONTROL.
SELECT INFILE ASSIGN "INFILE75.DAT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS INFILE-FILE-STATUS.
DATA DIVISION.

FILE SECTION.
FD INFILE .
01 INREC .
03 INREC-TYPE PIC X(01).
03 INREC-NAME PIC X(20) .
03 INREC-GENDER PIC X(01).
WORKING-STORAGE SECTION .

01 WS-END-OF-FILE PIC 9(01).


88 NO-MORE-RECORD VALUE 1 .
01 WS-TYPE-B-COUNTER PIC 9(6).
01 WS-TYPE-A-COUNTER PIC 9(6).
01 INFILE-FILE-STATUS PIC X(02).

PROCEDURE DIVISION .
PROG .
PERFORM INIT-PARA .
PERFORM BOD-PARA .
PERFORM END-PARA .

INIT-PARA SECTION.

DISPLAY "START OF PROGRAM" .

INITIALIZE WS-END-OF-FILE
WS-TYPE-B-COUNTER
INFILE-FILE-STATUS
WS-TYPE-A-COUNTER

OPEN INPUT INFILE

Información Confidencial | Información Propietaria de Gladius Technology | Página 103 de


176
IFINFILE-FILE-STATUS NOT = ZERO THEN
DISPLAY "INVALID INFILE75 FILE"
INFILE-FILE-STATUS
GOBACK
END-IF
PERFORM READ-FILE.
INIT-PARA-EXIT.
EXIT.
BOD-PARA SECTION.
PERFORM UNTIL NO-MORE-RECORD
PERFORM PROCESS-REC
PERFORM READ-FILE
END-PERFORM.
BOD-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY WS-TYPE-B-COUNTER
" 'B' RECORDS READ" .
DISPLAY WS-TYPE-A-COUNTER
" 'A' RECORDS READ" .
CLOSE INFILE.
END-PARA-EXIT.
GOBACK.
PROCESS-REC SECTION.
IF INREC-TYPE = "A"
PERFORM TYPE-A-ACTIONS
ELSE
PERFORM TYPE-B-ACTIONS
END-IF.
PROCESS-REC-EXIT.
EXIT.
TYPE-A-ACTIONS SECTION.
ADD 1 TO WS-TYPE-A-COUNTER .
TYPE-A-ACTIONS-EXIT.
EXIT.
TYPE-B-ACTIONS SECTION.
ADD 1 TO WS-TYPE-B-COUNTER .
TYPE-B-ACTIONS-EXIT.
EXIT.
READ-FILE SECTION.
READ INFILE
AT END SET NO-MORE-RECORD TO TRUE
END-READ.
READ-FILE-EXIT.
EXIT.

Using the SET verb in conditions

As an alternative way to "switching on" the condition name, use the verb SET, which
changes a LEVEL 88 or the value of any field. In the example below, the SET moves a
value of 1 to WS-END-OF–FILE.

READ INFILE
AT END SET NO-MORE-RECORDS TO TRUE
END-READ

Información Confidencial | Información Propietaria de Gladius Technology | Página 104 de


176
Both statements work equally well; however, use only one in any particular program to
avoid confusion.

Compound Conditions

To test more than one condition at once, use compound conditions in your IF
statement, as shown in the following examples.

IF WS-NUMBER = 6 AND WS-NUMBER-2 < 5


or
IF WS-TOT-3 = 5 OR WS-SUM-X > 22
or
IF WS-TOTAL > 23 AND WS-SUM = 200
OR WS-FINAL = 444

When an IF includes an OR condition, either condition can be true to make the entire IF
condition true. When code includes an AND condition, both conditions must be true.
OR conditions are evaluated after AND conditions

When using AND and OR in the same test always use bracketsso that the condition in
brackets is evaluated before anything else.

Nested Conditions

It is possible to nest IF statements, as shown in the following code.

IF INREC-JOB-TITLE = "MANAGER"
IF INREC-SALARY > 50000
IF INREC-START-DATE < 20000101
[actions]
ELSE
[actions]
ELSE
[actions]
ELSE
[actions].

Such statements, even when indented as shown, can be difficult to understand (even
by the person who wrote them) and should be avoided. For example, the above three
IFs can be replaced by one (IF….AND….AND), as shown in the following revised code.

IF INREC-JOB-TITLE = "MANAGER"
and INREC-SALARY > 50000
and INREC-START-DATE < 20000101
[actions]
ELSE
[actions]
ELSE
[actions]

Información Confidencial | Información Propietaria de Gladius Technology | Página 105 de


176
ELSE
[more code].

7.5. The EVALUATE Statement


Whereas IF dates from the first days of COBOL, more recent methods of testing
conditions use the EVALUATE verb. Conditions that would be clumsy or complex as an
IF statement can often be better expressed with the newer verb.

The EVALUATE statement looks at a series of nested IF statements that can have
compound conditions. The subsequent action depends on the results of these
evaluations.

EVALUATE exists in three formats.

• Simple EVALUATE statement


• EVALUATE condition statement
• Compound EVALUATE statement

The Simple EVALUATE Statement

Use the simple EVALUATE for several tests in one statement, as shown in the following
code.

EVALUATE INREC-TYPE
WHEN "A" THRU "D"
PERFORM MANAGER-STUFF
WHEN "E"
PERFORM OTHER-CODE
WHEN "G"
PERFORM JANITOR-CODE
WHEN "Z"
PERFORM TRAINER-FUNCTIONS
WHEN OTHER
PERFORM INVALID-RECORD
END-EVALUATE.

The WHEN OTHER clause is very useful in an EVALUATE statement, as it is a "catch-all"


for when none of the conditions specified are met. This often this indicates invalid data
or, at the very least, something the programmer did not expect to happen.

Although it is not required, always use END-EVALUATE at the end of your EVALUATE
statement to help make your program easier to read.

The EVALUATE [condition] Statement

Información Confidencial | Información Propietaria de Gladius Technology | Página 106 de


176
Use this form of EVALUATE to test different conditions, including condition-names (88
levels), in one statement. It exists either as an EVALUATE TRUE or EVALUATE [condition]
format.

First, let us look at EVALUATE TRUE. The following code tests three conditions: end of
file, when the counter equals 99, or when another condition is true (the catch all).
When one of these conditions is true, then the EVALUATE is true and the condition-
specific action is taken

EVALUATE TRUE
WHEN END-OF-FILE
PERFORM UNEXPECTED-EOF
WHEN WS-COUNTER = 99
DISPLAY "Too many records"
GOBACK.
WHEN OTHER
PERFORM NORMAL-ACTIONS
END-EVALUATE.

To understand the code, let's look at the same code using IF statements.

The Compound EVALUATE Statement

To test multiple subjects in an EVALUATE statement, use an ALSO clause instead of


AND. The following code shows an example of the EVALUATE ALSO. In the following
code the job type and salary level determine the actions performed. ( SEE EXAMPLE
7.6)

EVALUATE IN-JOB-TYPE ALSO TRUE


WHEN "MANAGER" ALSO IN-SALARY > 250000
PERFORM REWARD-TOP-EXECUTIVES
WHEN "TEAM LEADER" ALSO IN-SALARY > 80000
PERFORM BENEFIT-MIDDLE-PEOPLE
WHEN "EMPLOYEE" ALSO IN-SALARY < 50000
PERFORM EMPLOYEE-BENEFITS
END-EVALUATE.

This is exactly equivalent to the following code.

IF JOB-TYPE = "MANAGER"
AND IN-SALARY > 250000 THEN
PERFORM REWARD-TOP-EXECUTIVES
ELSE IF JOB-TYPE = "TEAM LEADER"
AND IN-SALARY > 80000
PERFORM BENEFIT-MIDDLE-PEOPLE
ELSE IF JOB-TYPE ="EMPLOYEE"
AND IN-SALARY < 50000
PERFORM EMPLOYEE-BENEFITS
END-IF
END-IF
END-IF.

Información Confidencial | Información Propietaria de Gladius Technology | Página 107 de


176
Although the second code is accurate, we might find the first sample code easier to
follow.

The CONTINUE Clause

To indicate that a program should do nothing when a particular condition is true, use
the CONTINUE clause, which tells the program to execute the next statement after the
EVALUATE.

The following program code uses EVALUATE CONTINUE. If the program encounters
"MR", the CONTINUE clause indicates to do nothing with the MR data and continue
executing the next statement.

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE77.
SECURITY. MICROFOCUS
ENVIRONMENT DIVISION.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
01 WS-CUSTOMER-TITLE PIC X(04).
88 MR-TITLE VALUE "MR" "mr".
88 FEMALE-TITLE VALUE "MRS" "mrs" "MISS"
"miss" "MS" "ms".
PROCEDURE DIVISION.
MAINLINE SECTION.
PERFORM INIT-PARA.
PERFORM LOOP-PARA.
PERFORM END-PARA.
INIT-PARA SECTION.
DISPLAY "A SIMPLE GENDER TEST".
INIT-PARA-EXIT.
EXIT.
LOOP-PARA SECTION.
DISPLAY "PLEASE ENTERED CUSTOMER TITLE?"
ACCEPT WS-CUSTOMER-TITLE.
EVALUATE TRUE
WHEN MR-TITLE
CONTINUE
WHEN FEMALE-TITLE
DISPLAY "FEMALE CUSTUMER"
WHEN OTHER
DISPLAY "INVALID-TITLE"
END-EVALUATE.
LOOP-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "MANY THANKS!".
END-PARA-EXIT.

GOBACK.

Información Confidencial | Información Propietaria de Gladius Technology | Página 108 de


176
7.6. Using Different Conditions
Let us write a program that reads in a file of records, evaluates conditions, and
executes statements based on those evaluations. Let's analyze the requirements and
the conditions, design the logic, and write the code that supports the logic.

• The input file may have any number of records (including 0).
• All input records contain a one-character type, a name field (20 characters), an
eight-digit start date, and an eight-digit salary field (six digits, two decimal
places).
• If the type field is set to anything other than "A", "B", "C", "E", "J" or "T", reject
the record and display the details. Similarly, if the name field is blank, reject the
record in the same way. Keep a count of all such invalid records.
• If the type field is "A", "B" or "C", write out the record details unchanged to an
output file. Another output file will contain unchanged details of all records
where the salary is greater than 75,000. So, a particular record may be on both
files.
• Keep record counts of types 'A' and 'C' (one count), 'B', 'E' and 'T' (another
count), and 'J' (a third count). Display these counts at the end of the program.

The following illustration suggests the program design.

The actions are as follows.

Información Confidencial | Información Propietaria de Gladius Technology | Página 109 de


176
Review the following issues.

1. The multiple choices due to the conditions will not necessarily have to mean
separate paragraphs in COBOL, as shown in the design. However, it is best to show all
the important details at the design stage, simplifying things later if appropriate.

2. The Valid Start box holds the code for adding to the appropriate valid record
count.

3. The boxes Record Body and Record End have been inserted, because this helps
greatly with the next Read of the input file. In the diagram, it is tempting to put an
action "4" (read) on all the Yes and No boxes, as well as on the Invalid box. However,
this is incorrect, because the second condition would never be tested. Creating the
Record End box gives you somewhere to do the Read. In other modules we shall see
that a Record Start box can be similarly useful.

The following code implements the design, using both IF and EVALUATE statements.

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE78.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL .
SELECT INFILE ASSIGN "INFILE78.DAT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS INFILE-FILE-STATUS.
SELECT OUTFILE-ABC ASSIGN "ABCOUT78.DAT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS ABCOUT-FILE-STATUS.
SELECT OUTFILE-BIGSAL ASSIGN "BIGSALOUT78.DAT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL

Información Confidencial | Información Propietaria de Gladius Technology | Página 110 de


176
FILE STATUS IS BIGSALOUT-FILE-STATUS.
DATA DIVISION .
FILE SECTION .
FD INFILE .
01 INREC .
******* Now the 88 levels for the field
03 IN-TYPE PIC X .
88 VALID-REC VALUE "A" THRU "C"
"E" "J" "T" .
88 ABC-REC VALUE "A" THRU "C" .
88 AC-REC VALUE "A" "C" .
88 BET-REC VALUE "B" "E" "T" .
88 J-REC VALUE "J" .
03 IN-NAME PIC X(20) .
03 IN-START-DATE PIC 9(8) .
03 IN-SALARY PIC 9(6)V99 .
FD OUTFILE-ABC.
**** No fields on the record are accessed
01 OUTREC-ABC PIC X(37) .
FD OUTFILE-BIGSAL .
01 OUTREC-BIGSAL PIC X(37) .
WORKING-STORAGE SECTION .
01 WS-EOF PIC 9.
88 END-OF-FILE VALUE 1 .
01 COUNTS.
03 WS-A-C-COUNT PIC 9(4) .
03 WS-B-E-T-COUNT PIC 9(4) .
03 WS-J-COUNT PIC 9(4) .
03 WS-INVALID-COUNT PIC 9(4) .
01 BIGSALOUT-FILE-STATUS PIC X(02).
01 INFILE-FILE-STATUS PIC X(02).
01 ABCOUT-FILE-STATUS PIC X(02).

PROCEDURE DIVISION .
PROG SECTION.
PERFORM INIT-PARA .
PERFORM BOD-PARA .
PERFORM END-PARA .

********************************************************
* INIT-PARA is only performed on time. It opens the
* input and output files and reads the first record.
******************************************************
INIT-PARA SECTION.
DISPLAY "STARTING" .
INITIALIZE COUNTS
BIGSALOUT-FILE-STATUS
INFILE-FILE-STATUS
ABCOUT-FILE-STATUS
WS-EOF
OPEN INPUT INFILE
IF INFILE-FILE-STATUS NOT = ZERO
DISPLAY "INVALID INFILE75 FILE"
INFILE-FILE-STATUS
GOBACK
END-IF
OPEN OUTPUT OUTFILE-ABC
IF ABCOUT-FILE-STATUS NOT = ZERO

Información Confidencial | Información Propietaria de Gladius Technology | Página 111 de


176
DISPLAY "INVALID ABCOUT78 FILE"
ABCOUT-FILE-STATUS
GOBACK
END-IF
OPEN OUTPUT OUTFILE-BIGSAL
IF BIGSALOUT-FILE-STATUS NOT = ZERO
DISPLAY "INVALID BIGSALOUT78 FILE"
BIGSALOUT-FILE-STATUS
GOBACK
END-IF

PERFORM REC-END.
INIT-PARA-EXIT.
EXIT.
BOD-PARA SECTION.
PERFORM UNTIL END-OF-FILE
PERFORM PROCESS-REC
END-PERFORM.
BOD-PARA-EXIT.
EXIT.
*********************************************************
* END-PARA is only perform when all the records on
* the file have been read
********************************************************
END-PARA SECTION.
DISPLAY "FINISHED" .
DISPLAY "NUMBER OF 'A' AND 'C' RECORDS: "
WS-A-C-COUNT .
DISPLAY "NUMBER OF 'B', 'E' AND 'T' RECORDS: "
WS-B-E-T-COUNT .
DISPLAY "NUMBER OF 'J' RECORDS: "
WS-J-COUNT .
DISPLAY "NUMBER OF INVALID RECORDS: "
WS-INVALID-COUNT .
CLOSE INFILE
OUTFILE-ABC
OUTFILE-BIGSAL .
END-PARA-EXIT.
GOBACK.
PROCESS-REC SECTION.
PERFORM REC-BOD.
PERFORM REC-END.
PROCESS-REC-EXIT.
EXIT.
********************************************************
* REC-BOD is performed on each input record
* It checks for a valid record code
********************************************************

REC-BOD SECTION.
IF VALID-REC AND IN-NAME UNEQUAL SPACES THEN
PERFORM VALID-RECORD
ELSE
PERFORM INVALID-RECORD
END-IF.
REC-BOD-EXIT.
EXIT.
********************************************************

Información Confidencial | Información Propietaria de Gladius Technology | Página 112 de


176
* REC-END reads all the records on the input file
********************************************************
REC-END SECTION.
READ INFILE
AT END SET END-OF-FILE TO TRUE
END-READ.
REC-END-EXIT.
EXIT.
********************************************************
* Valid-RECORD is performed for each valid type.
* this is where all the counters are incremented
********************************************************
VALID-RECORD SECTION.
EVALUATE TRUE
WHEN AC-REC
ADD 1 TO WS-A-C-COUNT
WHEN BET-REC
ADD 1 TO WS-B-E-T-COUNT
WHEN J-REC
ADD 1 TO WS-J-COUNT
WHEN OTHER
CONTINUE
END-EVALUATE
IF ABC-REC THEN
WRITE OUTREC-ABC FROM INREC
END-IF
IF IN-SALARY > 75000 THEN
WRITE OUTREC-BIGSAL FROM INREC
END-IF .
VALID-RECORD-EXIT.
EXIT.
INVALID-RECORD SECTION.
DISPLAY "THE FOLLOWING INPUT RECORD IS INVALID:" .
DISPLAY INREC .
ADD 1 TO WS-INVALID-COUNT .
INVALID-RECORD-EXIT.
EXIT.

Note that in the case of the output files, there was no need to define any of the record
fields, because in both cases the record is a copy of the input. WRITE FROM can be
used for the same reason.

In the following code, the WRITE FROM moves the contents from INREC into the record
area defined by OUTREC-ABC before writing the record. This requires less coding in the
FILE SECTION.

WRITE OUTREC-ABC FROM INREC

7.7. Summary
In this module we have examined the following topics:

• The EVALUATE verb and IF clause used in testing conditions

Información Confidencial | Información Propietaria de Gladius Technology | Página 113 de


176
• Various formats of EVALUATE
• Different types of conditions, including condition names (88 levels)
• Advantages and disadvantages of different ways of condition testing
• The writing of a COBOL program that uses different types of condition testing

7.8. Exercise 1: Using the EVALUATE statement


The EVALUATE verb is clearly very powerful, and this is particularly true when handling
logic derived from decision tables. Let's look at an example and determine how we
could use an EVALUATE statement in a program that provides a solution.

Introduction

Erasers Ltd sells office supplies ordered over the Internet. Companies can pay to
become a member of a scheme that gives them increased discounts. The discount
awarded depends upon how much they purchased in the previous 12 months, the
number of items in their current order, and their membership status.

Details

1. Start your editor.

2. Open PROGRAM71 located in X: \CLASS\MODULE7\NETX.

3. ADD THE CODE THE THE FOLLOWING SECTION

4. CURRENT-RECORD SECTION

5. NOT-CURRENT-RECOR

Write an EVALUATE statement that implements the logic in the decision table below to calculate the

level of discount applied.

For customers with a valid membership use the following discount structure:

# of items Value of purchases Apply the

Información Confidencial | Información Propietaria de Gladius Technology | Página 114 de


176
ordered… over a 12-month following
IN-ORDERS- period… discount…
PENDING IN-VALUE-OVER-12 OUT-DISCONT
1 – 5 $0 – 500 2%
6 - 16 $0 – 500 3%
> 16 $0 – 500 5%
1 – 5 $501 – 2000 7%
6 - 16 $501 - 2000 12%
> 16 $501 - 2000 18%
1 – 5 > $2000 10%
6 - 16 > $2000 23%
> 16 > $2000 35%

For customers with an expired membership use:

# of items Value of purchases Apply the


ordered… over a 12-month following
IN-ORDERS- period… discount…
PENDING IN-VALUE-OVER-12 OUT-DISCONT
1 – 5 $0 - 500 1%
6 - 16 $0 - 500 2%
> 16 $0 - 500 3%
1 – 5 $501 - 2000 5%
6 - 16 $501 - 2000 10%
> 16 $501 - 2000 15%
1 – 5 > $2000 8%
6 - 16 > $2000 23%
> 16 > $2000 28%

OUTPUT FROM RUN IS

STARTING
FINISHED
NUMBER OF CUSTOMER: 0008
NUMBER OF ORDERS : 0033
TOTAL VALUE OF ORDERS 000292.30

7.9. Exercise 2: Evaluating Salaries

Información Confidencial | Información Propietaria de Gladius Technology | Página 115 de


176
Introduction

The purpose of this program is to read the employee records and create three output
files. Each will contain records of employee's within a range of salaries; either low
medium or high.

This program should also count and display the number of employee's in each
category.

Additionally, this program should evaluate the "TYPE" code on each record, rejecting
and displaying invalid records.

Details

1. Start your editor.

2. Open PROGRAM72 located in X: \CLASS\MODULE7\NETX.

3. Please design and code a COBOL program to do the following.

• Read in a file of records, and then deal with them in different ways depending on the type of
record found. The input file may have any number of records (including 0).
• All input records contain a one-character type, a name field (20 characters), an eight-digit start
date, and an eight-digit salary field (six digits, two decimal places).
• If the type field is set to anything other than "A", "B", "C", "E", "R" or "T", reject the record and
display the details. Similarly, if the name field is blank, reject the record in the same way. Keep a
count of all such invalid records.
• If the salary is less than 25,000, write the record details unchanged to an output file. At the end
of the program write a special record to that file containing the total number of records written
(excluding that one). This record could contain the number zero.
• Include in another output file unchanged details of all records where the salary is between
25,000 and 64,999.99. Again, write a special record, containing the number of this type of
record written.
• Include all unchanged details of all other salaries in a third output file. Again, write a special
record at the end of the program.

4. Save the program in the X: \CLASS\MODULE7\NETX directory and provide the program name

PROGRAM72.CBL .

5. Compile and test the program.

Output from the Run is

Información Confidencial | Información Propietaria de Gladius Technology | Página 116 de


176
STARTING
THE FOLLOWING INPUT RECORD IS INVALID:
YTOMMY GUNN 1992041940000000
THE FOLLOWING INPUT RECORD IS INVALID:
JDEE LILER 1991010106800000
THE FOLLOWING INPUT RECORD IS INVALID:
JELLI FANT 1996091200800000
THE FOLLOWING INPUT RECORD IS INVALID:
A 1999113072800000
FINISHED
NUMBER OF LOW SALARIES: 0002
NUMBER OF MEDIUM SALARIES: 0007
NUMBER OF HIGH SALARIES: 0006
NUMBER OF INVALID RECORDS: 0004

8. Module 8: Data Manipulation


Understanding the full range of the data manipulation constructs available in COBOL
means more efficient programming and maintenance. This chapter examines the
powerful set of COBOL verbs available to manipulate both arithmetic and character
data.

8.1. Objectives
Upon successful completion of this module, you will be able to:

• Explain the functionality of the INITIALIZE verb.


• Use the various arithmetic COBOL verbs, such as ADD, SUBTRACT, MULTIPLY,
DIVIDE and COMPUTE.
• Use the verbs for manipulating character data, such as INSPECT, STRING and
UNSTRING.
• Explain the role of reference modification.
• Write a COBOL program demonstrating the above points.

8.2. Manipulating Data


The COBOL verbs available for data manipulation fall into three distinct groups:

• The INITIALIZE verb, which can be used on both numeric and character data.
• The arithmetic verbs ADD, SUBTRACT, MULTIPLY, DIVIDE and COMPUTE.
• The string handling verbs INSPECT, STRING and UNSTRING. This chapter also
explains how to extract a substring from a string using "reference modification."

8.3. The INITIALIZE Verb

Información Confidencial | Información Propietaria de Gladius Technology | Página 117 de


176
The INITIALIZE verb, as its name implies, sets elementary or group data items to an
initial value or resets values for fields. For example, if you write an income report and
the program calculates the total income, you might want to clear values and reset
them to "0" in order to begin subsequent income reporting.

Because this can be done with one or more VALUE clauses, INITIALIZE can be used
anywhere in the program. So, it can be executed many times during the program.
Furthermore, it will always "intelligently" decide what constitutes a sensible initial
value. INITIALIZE sets alphanumeric data items to spaces and numeric data items to
zeros, if no other value is specified.

The example below illustrates how INITIALIZE determines the initial value depending
on the field's attributes.

01 WS-DATA-ITEMS.
03 WS-NAME PIC X(20).
03 WS-SALARY PIC 9(6)V99.
03 WS-RECORD-COUNT PIC 9(4) COMP.
03 FILLER PIC X(40).
03 WS-ADDRESS PIC X(80).
[other code]
INITIALIZE WS-DATA-ITEMS.

In this example, WS-NAME and WS-ADDRESS will be set to spaces. WS-SALARY will be
set to zeros and WS-RECORD-COUNT to binary zeros.

The forty-character filler will be left untouched. INITIALIZE is therefore a very useful
and powerful verb.

It is also possible to INITIALIZE a field or fields to a different value, as shown in the next
example that uses the REPLACING clause. The REPLACING clause lets you specify the
type of field that should be initialized.

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE81.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-DATA-ITEMS.
03 WS-NAME PIC X(20).
03 WS-SALARY PIC 9(6)V99.
03 WS-RECORD-COUNT PIC 9(4) COMP.
03 FILLER PIC X(40).
03 WS-ADDRESS PIC X(80).
PROCEDURE DIVISION.
MAINLINE SECTION.
PERFORM INIT-PARA.
PERFORM LOOP-PARA.
PERFORM END-PARA.
INIT-PARA SECTION.

Información Confidencial | Información Propietaria de Gladius Technology | Página 118 de


176
DISPLAY "A SIMPLE INITIALIZE TEST".
INIT-PARA-EXIT.
EXIT.
LOOP-PARA SECTION.
DISPLAY "TEST 1:BEFORE INITIALIZE WS-DATA-ITEMS"
DISPLAY WS-DATA-ITEMS
DISPLAY "TEST 1:AFTER INITIALIZE WS-DATA-ITEMS "
INITIALIZE WS-DATA-ITEMS
DISPLAY WS-DATA-ITEMS
DISPLAY " "
DISPLAY "TEST 2:AFTER INITIALIZE WS-DATA-ITEMS "
INITIALIZE WS-DATA-ITEMS
REPLACING ALPHANUMERIC DATA BY ALL "?"
NUMERIC DATA BY ALL "6".
DISPLAY WS-DATA-ITEMS
DISPLAY " ".
LOOP-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "MANY THANKS!".
END-PARA-EXIT.
GOBACK.

This statement will set WS-NAME and WS-ADDRESS to twenty and eighty "?"
characters, respectively. WS-SALARY will contain 6666.00 (not 6666.66) and WS-
RECORD-COUNT will contain 6666. Again, the FILLER will be left untouched.

8.4. Arithmetic Statements


You can code simple to very complex mathematical operations. The four main verbs to
consider are ADD, SUBTRACT, MULTIPLY, and DIVIDE. We will also look at COMPUTE,
which is unlike the first four in format and allows a more equation-driven approach.

You must use only numeric data in arithmetic operations.

Before examining these verbs, keep these two points in mind.

1. By default, there is no rounding. Rounding has to be specified. So, 35 divided by


12 will by default return 2.

2. COBOL does not automatically check for the result of a calculation going out of
range. However, you can specify that this check takes place. Should an out-of-range
event occur with no check in place, the results of the calculation are undefined.

The ADD Verb

Información Confidencial | Información Propietaria de Gladius Technology | Página 119 de


176
There are two formats for using the ADD statement. Data items and/or numeric literals
can be added to an existing data item as in format 1 or data items and/or numeric
literals can be added to existing data but results are stored in another data item, as
seen in format 2.

Format 1: Simple

Here is an example using the Simple ADD format.

ADD WS-WEEKLY-SALES TO WS-MONTHLY-SALES.


ADD WS-MONTHLY-SALES TO WS-YEARLY-SALES
WS-CENTURY-SALES.
ADD RESULT-1 RESULT-2 10000 TO TOTAL.
ADD 2000 TO EMPLOYEES-SALARY.

This means that the operand or operands to the left of the "TO" are added to the field
or fields to the right of the "TO," incrementing them. The fields or literals to the left are
unchanged. The receiving field or fields (to the right of the "TO") are formatted
according to their PICTURE clauses.

Using ROUNDED, not surprisingly, rounds the answer according to the number of
decimal places specified in the receiving field (though rounding errors should not occur
on an ADD). The following statement will round WS-DECIMAL2 to its specified decimal
places.

ADD WS-DECIMAL-1 TO WS-DECIMAL2 ROUNDED.

Format 2: Giving

The following example illustrates the Giving ADD format.

ADD WS-WEEKLY-SALES TO WS-MONTHLY-SALES


GIVING WS-TOTAL-SO-FAR.
ADD WS-WEEK1 WS-WEEK2 WS-WEEK3
WS-WEEK4 250 TO WS-ALL-WEEKS
GIVING WS-TOTAL1 WS-TOTAL2.
ADD 100 200 300 TO 400 GIVING WS-ADDITION.

Here the operand or operands to the left of the "TO" together with the one operand to
the right of the "TO" are added together, and then the operand or operands after the
GIVING are updated by that amount.

Again, ROUNDED after a receiving field rounds the answer. The next statement uses
ROUNDED.

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE82.

Información Confidencial | Información Propietaria de Gladius Technology | Página 120 de


176
CONFIGURATION SECTION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-DATA-ITEMS.
03 WS-WEEKLY-SALES PIC S9(4)V99.
03 WS-MONTHLY-SALE PIC S9(4)V99.
03 WS-MONTHLY-SALES PIC S9(4)V99.
03 WS-YEARLY-SALES PIC S9(4)V99.
03 WS-CENTURY-SALES PIC S9(4)V99.
03 TOTAL PIC 9(6).
03 RESULT-1 PIC 9(6).
03 RESULT-2 PIC 9(6).
03 EMPLOYEES-SALARY PIC 9(6).
03 WS-DECIMAL-1 PIC S9(4)V99.
03 WS-DECIMAL-2 PIC S9(4)V99.
03 WS-WEEK1 PIC S9(4)V99.
03 WS-WEEK2 PIC S9(4)V99.
03 WS-WEEK3 PIC S9(4)V99.
03 WS-WEEK4 PIC S9(4)V99.
03 WS-ALL-WEEKS PIC S9(4)V99.
03 WS-TOTAL1 PIC S9(4)V99.
03 WS-TOTAL2 PIC S9(4)V99.
03 WS-ADDITION PIC 9(6).
03 WS-ANSWER PIC 9(6).
03 WS-TOTAL-SO-FAR PIC S9(4)V99.

PROCEDURE DIVISION.
MAINLINE SECTION.
PERFORM INIT-PARA.
PERFORM LOOP-PARA 5 TIMES.
PERFORM END-PARA.
INIT-PARA SECTION.
DISPLAY "A SIMPLE ADDITION TEST".
INITIALIZE WS-DATA-ITEMS.
MOVE 12.2 TO WS-WEEKLY-SALES
RESULT-1
RESULT-2
MOVE 2.45 TO WS-DECIMAL-1
MOVE 10 TO WS-WEEK1
MOVE 3 TO WS-WEEK2
MOVE 3 TO WS-WEEK3
MOVE 2 TO WS-WEEK4
.

INIT-PARA-EXIT.
EXIT.
LOOP-PARA SECTION.
Format 1: Simple
ADD WS-WEEKLY-SALES TO WS-MONTHLY-SALES
DISPLAY "WS-WEEKLY-SALES = " WS-WEEKLY-SALES
DISPLAY "WS-MONTHLY-SALES = "
WS-MONTHLY-SALES
DISPLAY " "

ADD WS-MONTHLY-SALES TO WS-YEARLY-SALES


WS-CENTURY-SALES.

DISPLAY "WS-MONTHLY-SALES = "

Información Confidencial | Información Propietaria de Gladius Technology | Página 121 de


176
WS-MONTHLY-SALES
DISPLAY "WS-YEARLY-SALES = "
WS-YEARLY-SALES
DISPLAY "WS-CENTURY-SALES = "
WS-CENTURY-SALES
DISPLAY " "

ADD RESULT-1 RESULT-2 10000 TO TOTAL.


DISPLAY "RESULT-1 = " RESULT-1
DISPLAY "RESULT-2 = " RESULT-2
DISPLAY "TOTAL = " TOTAL
DISPLAY " "

ADD 2000 TO EMPLOYEES-SALARY.


DISPLAY "EMPLOYEES-SALARY = "
EMPLOYEES-SALARY
DISPLAY " "
Rounding
ADD WS-DECIMAL-1 TO WS-DECIMAL-2 ROUNDED.
DISPLAY "ROUNDED WS-DECIMAL-1 = "
WS-DECIMAL-1
DISPLAY "ROUNDED WS-DECIMAL-2 = "
WS-DECIMAL-2
DISPLAY " "
Format 2: Giving

ADD WS-WEEKLY-SALES TO WS-MONTHLY-SALES


GIVING WS-TOTAL-SO-FAR.

DISPLAY "WS-WEEKLY-SALES = " WS-WEEKLY-SALES


DISPLAY "WS-MONTHLY-SALES = "
WS-MONTHLY-SALES
DISPLAY "WS-TOTAL-SO-FAR = " WS-TOTAL-SO-FAR
DISPLAY " "

ADD WS-WEEK1 WS-WEEK2 WS-WEEK3


WS-WEEK4 250 TO WS-ALL-WEEKS
GIVING WS-TOTAL1 WS-TOTAL2.

DISPLAY "WS-WEEK1 = " WS-WEEK1


DISPLAY "WS-WEEK2 = " WS-WEEK2
DISPLAY "WS-WEEK3 = " WS-WEEK3
DISPLAY "WS-WEEK4 = " WS-WEEK4
DISPLAY "WS-ALL-WEEKS = " WS-ALL-WEEKS
DISPLAY "WS-TOTAL1 = " WS-TOTAL1
DISPLAY "WS-TOTAL2 = " WS-TOTAL2
DISPLAY " "

ADD 100 200 300 TO 400 GIVING WS-ADDITION.


DISPLAY "WS-ADDITION = " WS-ADDITION
DISPLAY " "

Rounding
ADD 123.456 TO 654.321
GIVING WS-ANSWER ROUNDED.
DISPLAY "WS-ANSWER = " WS-ANSWER
DISPLAY " "
DISPLAY " ".

Información Confidencial | Información Propietaria de Gladius Technology | Página 122 de


176
LOOP-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "MANY THANKS!".
END-PARA-EXIT.
GOBACK.
GIVING WS-ANSWER ROUNDED.

The SUBTRACT Verb

This verb also has two formats, again with and without GIVING.

Format 1: Simple

The following example uses the SUBTRACT verb without GIVING.

SUBTRACT 10 FROM WS-COUNT-1 WS-COUNT-2.


SUBTRACT TAXES-1 TAXES-2 FROM WS-SALARY.

The value in the field or fields to the left of the "FROM" are added together if
appropriate. That total value is subtracted from the field or fields to the right of the
"FROM."

Format 2: Giving

The following example uses the SUBTRACT verb with GIVING.

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE83.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
FILE-CONTROL.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-DATA-ITEMS.
03 WS-COUNT-1 PIC 9(6).
03 WS-COUNT-2 PIC 9(6).
03 WS-SALARY PIC 9(6).
03 TAXES-1 PIC 9(6).
03 TAXES-2 PIC 9(6).
03 WS-COUNT-3 PIC 9(6).
03 WS-GROSS-SALARY PIC 9(6)V9(2).
03 WS-NETT-SALARY PIC 9(6)V9(2).
03 WS-NUM PIC 9(2).
PROCEDURE DIVISION.
MAINLINE SECTION.
PERFORM INIT-PARA.
PERFORM LOOP-PARA 5 TIMES.
PERFORM END-PARA.

INIT-PARA SECTION.
DISPLAY "A SIMPLE SUBTRACT TEST".

Información Confidencial | Información Propietaria de Gladius Technology | Página 123 de


176
INITIALIZE WS-DATA-ITEMS.
MOVE 100 TO WS-COUNT-1
MOVE 33 TO WS-COUNT-2
MOVE 33000 TO WS-SALARY
MOVE 200 TO TAXES-1
MOVE 300 TO TAXES-2
MOVE 300 TO WS-COUNT-3
MOVE 44000 TO WS-GROSS-SALARY.
INIT-PARA-EXIT.
EXIT.
LOOP-PARA SECTION.
*This verb also has two formats, again with and without
GIVING.
*Format 1: Simple
*The following example uses the SUBTRACT verb without GIVING.

SUBTRACT 10 FROM WS-COUNT-1


WS-COUNT-2.

DISPLAY "WS-COUNT-1 = " WS-COUNT-1


DISPLAY "WS-COUNT-2 = " WS-COUNT-2

SUBTRACT TAXES-1
TAXES-2 FROM WS-SALARY.

DISPLAY "TAXES-1 = " TAXES-1


DISPLAY "TAXES-2 = " TAXES-2
DISPLAY "WS-SALARY = " WS-SALARY
*Format 2: Giving
*The following example uses the SUBTRACT verb with GIVING.

SUBTRACT 10 FROM WS-COUNT-1


GIVING WS-COUNT-2
WS-COUNT-3.

DISPLAY "WS-COUNT-1= " WS-COUNT-1


DISPLAY "WS-COUNT-2= " WS-COUNT-2
DISPLAY "WS-COUNT-3= " WS-COUNT-3

SUBTRACT TAXES-1
TAXES-2
FROM WS-GROSS-SALARY
GIVING WS-NETT-SALARY.

DISPLAY "TAXES-1 " TAXES-1


DISPLAY "TAXES-2 " TAXES-2
DISPLAY "WS-GROSS-SALARY " WS-GROSS-SALARY
DISPLAY "WS-NETT-SALARY " WS-NETT-SALARY

SUBTRACT 12 FROM 24 GIVING WS-NUM.


DISPLAY "WS-NUM " WS-NUM
DISPLAY " ".
LOOP-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "MANY THANKS!".
END-PARA-EXIT.

Información Confidencial | Información Propietaria de Gladius Technology | Página 124 de


176
GOBACK.

Here the operand or operands to the left of the "FROM" are added together, and their
combined value is subtracted from the one operand after the "FROM." The result is
moved to the field or fields after the GIVING.

Again, the word ROUNDED after a receiving field ensures that rounding takes place.

NOTE: Ensure that all fields from which you are SUBTRACTing are signed fields. If not,
results that should be negative remain positive with potentially catastrophic results.

The MULTIPLY Verb

This verb has the same two formats as ADD and SUBTRACT.

Format 1: Simple

The following example uses the MULTIPLY verb without GIVING.

MULTIPLY WS-INTEREST-RATE BY WS-SUM.


MULTIPLY 1.01 BY EMPLOYEE-SALARY.

In this format, the value of the operand (field or literal) before the "BY" is multiplied by
the values in the field or fields after the "BY," and the result is moved there.

The following would be incorrect using this format.

MULTIPLY EMPLOYEE-SALARY BY 1.01

Why not? Format 1 stores the results of the multiply in the operand after the BY. Also,
1.01 is a literal and cannot be used to store data.

As shown in the next example, you can also include multiple fields after the "BY" so
that the operand before the BY is multiplied by the fields after the "BY."

MULTIPLY 1.01 BY EMPLOYEE-SALARY MANAGER-SALARY.

The results are stored in both EMPLOYEE-SALARY and MANAGER-SALARY.

Format 2: Giving

The following example uses the MULTIPLY verb with GIVING.

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE84.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.

Información Confidencial | Información Propietaria de Gladius Technology | Página 125 de


176
INPUT-OUTPUT SECTION.
FILE-CONTROL.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
01 WS-DATA-ITEMS.
03 EMPLOYEE-SALARY PIC 9(6)V9(2).
03 MANAGER-SALARY PIC 9(6)V9(2).
03 WS-INTEREST-RATE PIC 9V99.
03 WS-TOTAL PIC 9(6)V9(2).
03 WS-ANSWER PIC 9(6)V9(2).
03 WS-TOTAL-2 PIC 9(6)V9(2).
03 WS-SUM PIC 9(6)V9(2).
PROCEDURE DIVISION.
MAINLINE SECTION.
PERFORM INIT-PARA.
PERFORM LOOP-PARA 5 TIMES.
PERFORM END-PARA.
INIT-PARA SECTION.
DISPLAY "A SIMPLE MULTIPLY TEST".
INITIALIZE WS-DATA-ITEMS.
MOVE 100.00 TO EMPLOYEE-SALARY
MOVE 200.00 TO MANAGER-SALARY
MOVE 0.2 TO WS-INTEREST-RATE
MOVE 33000 TO WS-TOTAL
MOVE 6 TO WS-SUM.
INIT-PARA-EXIT.
EXIT.
LOOP-PARA SECTION.
*The following example uses the MULTIPLY verb
*without GIVING.
MULTIPLY WS-INTEREST-RATE BY WS-SUM.
DISPLAY " WS-INTEREST-RATE = "
WS-INTEREST-RATE
DISPLAY " WS-SUM = "
WS-SUM
DISPLAY " "

MULTIPLY 1.01 BY EMPLOYEE-SALARY.


DISPLAY " EMPLOYEE-SALARY = "
EMPLOYEE-SALARY
DISPLAY " "
MULTIPLY 1.01 BY EMPLOYEE-SALARY
MANAGER-SALARY.
DISPLAY " EMPLOYEE-SALARY = "
EMPLOYEE-SALARY
DISPLAY " MANAGER-SALARY = "
MANAGER-SALARY
DISPLAY " "

*The results are stored in both EMPLOYEE-SALARY


*and MANAGER-SALARY

*Format 2: Giving
*The following example uses the MULTIPLY
*verb with GIVING.

MULTIPLY WS-INTEREST-RATE

Información Confidencial | Información Propietaria de Gladius Technology | Página 126 de


176
BY WS-SUM GIVING WS-ANSWER.

DISPLAY " WS-INTEREST-RATE = "


WS-INTEREST-RATE
DISPLAY " WS-SUM = "
WS-SUM
DISPLAY " WS-ANSWER = "
WS-ANSWER
DISPLAY " "
*
MULTIPLY WS-TOTAL BY 4 GIVING WS-TOTAL-2.
DISPLAY " WS-TOTAL = " WS-TOTAL
DISPLAY " WS-TOTAL-2 = " WS-TOTAL-2
DISPLAY " "
*
DISPLAY " BEFORE EMPLOYEE-SALARY = "
EMPLOYEE-SALARY
DISPLAY " "

MULTIPLY EMPLOYEE-SALARY
BY 1.01 GIVING EMPLOYEE-SALARY.

DISPLAY " AFTER EMPLOYEE-SALARY = "


EMPLOYEE-SALARY
DISPLAY " ".
LOOP-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "MANY THANKS!".
END-PARA-EXIT.
GOBACK.

In this format, only one field or literal can be before the "BY" and one after; however,
the result can be moved to one or more fields (which can include a field already used in
the MULTIPLY).

The word ROUNDED can be inserted after the name of a receiving field.

Preventing an Out-of-Range Condition

As a general rule, a MULTIPLY statement is more likely than an ADD statement to result
in a field not being large enough for the calculation result. Trap this out-of-range
condition by using an ON SIZE ERROR clause, discussed later in this chapter.

The DIVIDE Verb

The DIVIDE statement has a total of five formats. In all cases ROUNDED can be used
after any receiving operand.

• Format 1: The simple format (DIVIDE INTO)


• Format 2: The GIVING format (DIVIDE INTO… GIVING)

Información Confidencial | Información Propietaria de Gladius Technology | Página 127 de


176
• Format 3: DIVIDE … BY
• Format 4: DIVIDE INTO… GIVING, yielding a remainder
• Format 5: DIVIDE … BY, yielding a remainder

Format 1: DIVIDE ... INTO

The following example uses the DIVIDE verb with INTO and without GIVING.

DIVIDE WS-COUNT INTO WS-TOTAL.

This results in WS-TOTAL being divided by WS-COUNT. There can be only one operand
(data item or literal) before the INTO, but there may be many operands after the INTO.
Each operand will have the same division carried out on it.

Format 2: DIVIDE INTO ... GIVING

The following example uses the DIVIDE verb with INTO and with GIVING.

DIVIDE WS-COUNT INTO WS-TOTAL


GIVING WS-NUM-1.

This time the result goes into the field or fields after the GIVING.

Format 3: DIVIDE ... BY

This format reverses the operands and uses DIVIDE…BY, as shown in the next example.

DIVIDE WS-TOTAL BY WS-COUNT


GIVING WS-NUM-1.

This yields the same result as the Format 2 statement above. Again multiple receiving
fields can exist after the GIVING.

Format 4: DIVIDE INTO… GIVING, yielding a remainder

Formats 4 and 5 add a REMAINDER clause. The following example uses the DIVIDE verb
with INTO without GIVING.

DIVIDE WS-COUNT INTO WS-TOTAL


GIVING WS-NUM-1 REMAINDER WS-REM.

Format 5: DIVIDE … BY, yielding a remainder

The following example uses the DIVIDE verb with BY with GIVING also yielding a
remainder.

IDENTIFICATION DIVISION.

Información Confidencial | Información Propietaria de Gladius Technology | Página 128 de


176
PROGRAM-ID. EXAMPLE85.
AUTHOR. TRAINING.
INSTALLATION. MARS.
DATE-WRITTEN. 18/10/2005.
DATE-COMPILED.
SECURITY. MICROFOCUS
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM-370.
OBJECT-COMPUTER. IBM-370.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
01 WS-DATA-ITEMS.
03 WS-COUNT PIC 9(6)V9(2).
03 WS-NUM-1 PIC 9(6).
03 WS-REM PIC 9(6)V9(2).
03 WS-TOTAL PIC 9(6)V9(2).
03 WS-ANSWER PIC 9(6)V9(2).
03 WS-TOTAL-2 PIC 9(6)V9(2).
03 WS-SUM PIC 9(6)V9(2).
PROCEDURE DIVISION.
MAINLINE SECTION.
PERFORM INIT-PARA.
PERFORM LOOP-PARA 5 TIMES.
PERFORM END-PARA.
INIT-PARA SECTION.
DISPLAY "A SIMPLE DIVIDE TEST".
INITIALIZE WS-DATA-ITEMS.
MOVE 100.00 TO WS-COUNT
MOVE 200.00 TO WS-NUM-1
MOVE 0.2 TO WS-REM
MOVE 33000 TO WS-TOTAL
MOVE 6 TO WS-SUM.
INIT-PARA-EXIT.
EXIT.
LOOP-PARA SECTION.
*Format 1: DIVIDE ... INTO
DISPLAY "BEFORE "
DISPLAY "WS-COUNT = " WS-COUNT
DISPLAY "WS-TOTAL = " WS-TOTAL

DIVIDE WS-COUNT INTO WS-TOTAL.


DISPLAY "AFTER "
DISPLAY "WS-COUNT = " WS-COUNT
DISPLAY "WS-TOTAL = " WS-TOTAL
*Format 2: DIVIDE INTO ... GIVING
DISPLAY "BEFORE "
DISPLAY "WS-COUNT = " WS-COUNT
DISPLAY "WS-TOTAL = " WS-TOTAL
DISPLAY "WS-NUM-1 = " WS-NUM-1

DIVIDE WS-COUNT INTO WS-TOTAL


GIVING WS-NUM-1.
DISPLAY "after "
DISPLAY "WS-COUNT = " WS-COUNT

Información Confidencial | Información Propietaria de Gladius Technology | Página 129 de


176
DISPLAY "WS-TOTAL = " WS-TOTAL
DISPLAY "WS-NUM-1 = " WS-NUM-1
*Format 3: DIVIDE ... BY
DISPLAY "BEFORE "
DISPLAY "WS-COUNT = " WS-COUNT
DISPLAY "WS-TOTAL = " WS-TOTAL
DISPLAY "WS-NUM-1 = " WS-NUM-1
DIVIDE WS-TOTAL BY WS-COUNT
GIVING WS-NUM-1.
DISPLAY "after"
DISPLAY "WS-COUNT = " WS-COUNT
DISPLAY "WS-TOTAL = " WS-TOTAL
DISPLAY "WS-NUM-1 = " WS-NUM-1

*Format 4: DIVIDE INTO… GIVING, yielding a remainder

DISPLAY "BEFORE "


DISPLAY "WS-COUNT = " WS-COUNT
DISPLAY "WS-TOTAL = " WS-TOTAL
DISPLAY "WS-NUM-1 = " WS-NUM-1
DISPLAY "WS-REM = " WS-REM.
DIVIDE WS-COUNT INTO WS-TOTAL
GIVING WS-NUM-1 REMAINDER WS-REM.
DISPLAY "after "
DISPLAY "WS-COUNT = " WS-COUNT
DISPLAY "WS-TOTAL = " WS-TOTAL
DISPLAY "WS-NUM-1 = " WS-NUM-1
DISPLAY "WS-REM = " WS-REM.

*Format 5: DIVIDE … BY, yielding a remainder


DISPLAY "BEFORE "
DISPLAY "WS-COUNT = " WS-COUNT
DISPLAY "WS-TOTAL = " WS-TOTAL
DISPLAY "WS-NUM-1 = " WS-NUM-1
DISPLAY "WS-REM = " WS-REM.
DIVIDE WS-TOTAL BY WS-COUNT
GIVING WS-NUM-1 REMAINDER WS-REM
DISPLAY "after "
DISPLAY "WS-COUNT = " WS-COUNT
DISPLAY "WS-TOTAL = " WS-TOTAL
DISPLAY "WS-NUM-1 = " WS-NUM-1
DISPLAY "WS-REM = " WS-REM.
DISPLAY " ".
LOOP-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "MANY THANKS!".
END-PARA-EXIT.
GOBACK.

ADD, SUBTRACT, MULTIPLY, and DIVIDE Summary

In summary, we can format the four verbs for arithmetic operations as follows.

ADD data-item TO receiving-field


SUBTRACT data-item FROM receiving-field

Información Confidencial | Información Propietaria de Gladius Technology | Página 130 de


176
MULTIPLY data-item BY receiving-field
DIVIDE data-item INTO receiving-field

Additionally, each verb can use the GIVING format, such as the following:

ADD data_item-1 or literal TO data_item-2


GIVING data_item-3

The COMPUTE Verb

The COMPUTE statement has a completely different format than the other arithmetic
statements. It uses the standard operators +, -, / (divide), *(multiply), and **
(exponentiation, for example 2**3 represents 2 to the 3rd power), as shown in the
next example.

COMPUTE WS-TOTAL =
(WS-NET-PAY + (WS-OVERTIME * WS-OT-HRS))
* (100 -WS-TAX-RATE)

More than one field name can be placed after the COMPUTE and before the equal sign.

COMPUTE is a comparatively inefficient verb. So it is best to use the other verbs for
simple calculations. For example, ADD 1 TO TOTAL is better than COMPUTE TOTAL =
TOTAL + 1.

Note: An intermediate working storage field may be necessary after the COMPUTE
clause for certain mainframe COBOL dialects.

Order of Evaluation

The order in which items are evaluated makes a difference to the result of the
expression.

Items are evaluated in the following order:

• Items within parentheses


• Exponentiation
• Multiplication and division (same priority)
• Addition and subtraction (same priority)
• Left to right, when the operators are of equal priority

In practice, use brackets, wherever possible, to clarify order to you and anyone else
who may have to amend your code later.

NOTE: Specify ROUNDED after a receiving field in the normal way.

Información Confidencial | Información Propietaria de Gladius Technology | Página 131 de


176
The ON SIZE ERROR Clause

The ON SIZE ERROR clause can be used with any arithmetic statement to trap a
numeric calculation going out of range, including division by zero.

The following example shows how to use the ON SIZE ERROR clause.

COMPUTE WS-INVOICE-AMT =
WS-ITEM-PRICE * WS-QUANTITY
ON SIZE ERROR
DISPLAY "ERROR – TOTAL IS TOO LARGE".

In the above example the program will continue if the calculation is within range.
However, if the WS-INVOICE-AMT becomes larger than its PICTURE clause allows, ON
SIZE ERROR displays the error message.

Alternatively, use the NOT ON SIZE ERROR clause as well. This would be necessary if the
COMPUTE statement were within the scope of another conditional statement such as
an IF statement.

The following example uses both the ON SIZE ERROR and the NOT ON SIZE ERROR
clauses.

COMPUTE WS-INVOICE-AMT =
WS-ITEM-PRICE * WS-QUANTITY
ON SIZE ERROR
PERFORM ERROR-ACTIONS
NOT ON SIZE ERROR
PERFORM SET-UP-INVOICE
END-COMPUTE

Example 8.6

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE86.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
01 WS-DATA-ITEMS.
03 WS-NET-PAY PIC 9(6)V9(2).
03 WS-OVERTIME PIC 9(6)V9(2).
03 WS-OT-HRS PIC 9(6)V9(2).
03 WS-TAX-RATE PIC 9(6)V9(2).
03 WS-total PIC 9(6)V9(2).
03 total PIC 9(6).
03 WS-INVOICE-AMT PIC 9(1)V9(2).
03 WS-ITEM-PRICE PIC 9(6)V9(2).
03 WS-QUANTITY PIC 9(6).

Información Confidencial | Información Propietaria de Gladius Technology | Página 132 de


176
PROCEDURE DIVISION.
MAINLINE SECTION.
PERFORM INIT-PARA.
PERFORM LOOP-PARA 5 TIMES.
PERFORM END-PARA.
INIT-PARA SECTION.
DISPLAY "A SIMPLE COMPUTE TEST".
INITIALIZE WS-DATA-ITEMS.
MOVE 100.00 TO WS-NET-PAY
MOVE 10.00 TO WS-OVERTIME
MOVE 34 TO WS-OT-HRS
MOVE 47.5 TO WS-TAX-RATE
MOVE 344.99 TO WS-ITEM-PRICE
MOVE 9999 TO WS-QUANTITY.
INIT-PARA-EXIT.
EXIT.
LOOP-PARA SECTION.
DISPLAY "BEFORE "
DISPLAY "WS-TOTAL = " WS-TOTAL

COMPUTE WS-TOTAL =
(WS-NET-PAY + (WS-OVERTIME * WS-OT-HRS))
* (100 - WS-TAX-RATE)

DISPLAY "AFTER "


DISPLAY "WS-TOTAL = " WS-TOTAL

DISPLAY "TOTAL = " TOTAL


ADD 1 TO TOTAL

DISPLAY "TOTAL = " TOTAL

COMPUTE TOTAL = TOTAL + 1.


DISPLAY "TOTAL = " TOTAL

* The ON SIZE ERROR Clause

COMPUTE WS-INVOICE-AMT =
WS-ITEM-PRICE * WS-QUANTITY
END-COMPUTE.

DISPLAY " WS-INVOICE-AMT = " WS-INVOICE-AMT

COMPUTE WS-INVOICE-AMT =
WS-ITEM-PRICE * WS-QUANTITY
ON SIZE ERROR
DISPLAY "ERROR - TOTAL IS TOO LARGE"
END-COMPUTE.

DISPLAY " WS-INVOICE-AMT = " WS-INVOICE-AMT

COMPUTE WS-INVOICE-AMT =
WS-ITEM-PRICE * WS-QUANTITY

Información Confidencial | Información Propietaria de Gladius Technology | Página 133 de


176
ON SIZE ERROR
DISPLAY "ERROR - TOTAL IS TOO LARGE"
NOT ON SIZE ERROR
DISPLAY "PROCESS INVOICE"
END-COMPUTE

DISPLAY " "


.
LOOP-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "MANY THANKS!".
END-PARA-EXIT.
GOBACK.

8.5. Verbs for String Handling


This module so far has discussed how to deal with numeric data, not alphanumeric
data. COBOL deals not just with numbers, but also with strings of alphanumeric data. A
string is a set of characters.

Three verbs manipulate such data: INSPECT, STRING and UNSTRING.

The INSPECT Verb

This statement can be used to look at a string of data and optionally to manipulate it.
There are four formats.

• The first format uses INSPECT with TALLYING to count occurrences of a


character or characters within a field.
• The second format uses INSPECT with REPLACING to change a character or
characters.
• The third format uses INSPECT with both TALLYING and REPLACING.
• The forth format uses INSPECT with CONVERTING to change a character or
characters.

In these examples we shall use the following data items.

01 WS-CNTS COMP VALUE LOW-VALUES.


03 WS-CNT-1 PIC 99.
03 WS-CNT-2 PIC 99.
03 WS-CNT-3 PIC 99.
01 WS-STRING PIC X(20)
VALUE "AARDVARK EXTRA".

Format 1: INSPECT ... TALLYING

The following example looks for three conditions in a string.

Información Confidencial | Información Propietaria de Gladius Technology | Página 134 de


176
INSPECT WS-STRING
TALLYING WS-CNT-1 FOR LEADING "A"
WS-CNT-2 FOR ALL "R"
WS-CNT-3 FOR CHARACTERS.

This format allows you to look through a string for one or more characters or
combination of characters.

This example counts the following three separate things:

• WS-CNT-1 ends up with the value of 2 (there are two 'A's at the beginning of
the string)
• WS-CNT-2 contains 3.
• WS-CNT-3 contains 14 characters in the "AARDVARK EXTRA" string.

If you wish to use FOR CHARACTERS as well as counting something else, specify the
clause last. If you put it first, the INSPECT will count through the whole string for
characters, and its internal pointer will then be at the end of the string, and any other
TALLYING counts will be set to zero.

Format 2: INSPECT... REPLACING

The following example inspects strings and replaces characters.

INSPECT WS-STRING
REPLACING FIRST "A" BY "B"
ALL "R" BY "S".

This sets WS-STRING to "BASDVASK EXTSA".

Format 3: INSPECT... TALLYING... REPLACING

This example combines the first two. It counts and replaces.

INSPECT WS-STRING
TALLYING WS-CNT-1 FOR ALL "A"
REPLACING LEADING "A" BY "B"
ALL "R" BY "S".

This sets WS-STRING to "BBSDVASK EXTSA"; however, WS-CNT-1 will contain 4, as there
were four A's in the string at the time. (The TALLYING happens before the REPLACING.)

Format 4: INSPECT ... CONVERTING

This example converts data in the field WS-STRING.

Información Confidencial | Información Propietaria de Gladius Technology | Página 135 de


176
INSPECT WS-STRING
CONVERTING "RVX" TO "QUW".

Every "R" changes to "Q", every "V" to "U" and every "X" to "W".
WS-STRING will therefore be set to "AAQDUAQK EWTQA".

The BEFORE and AFTER Clauses

The BEFORE and AFTER clauses can be used with all four formats of INSPECT. The
clauses enable selection of only part of the string for processing.

The following code uses the BEFORE clause with the INSPECT verb.

INSPECT WS-STRING
TALLYING WS-CNT-1
FOR ALL "A" BEFORE SPACE.

The code inspects the string and sets WS-CNT-1 to 3, totaling the three A's before the
space in the "AARDVARK EXTRA" string.

The following code uses the AFTER clause with the INSPECT verb.

INSPECT WS-STRING
TALLYING WS-CNT-2
FOR ALL "R" AFTER "K".

The code inspects the string and sets WS-CNT-1 to 1, totaling the one "R" after the "K"
in the "AARDVARK EXTRA" string.

The following code counts the characters AFTER the "D", but BEFORE the "T".

INSPECT WS-STRING
TALLYING WS-CNT-3 FOR CHARACTERS
AFTER "D" BEFORE "T".
WS-CNT-3 becomes 7.

Example 8.7

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE87.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
01 WS-CNTS.
03 WS-CNT-1 PIC 99.
03 WS-CNT-2 PIC 99.
03 WS-CNT-3 PIC 99.

Información Confidencial | Información Propietaria de Gladius Technology | Página 136 de


176
01 WS-STRING PIC X(20).
PROCEDURE DIVISION.
MAINLINE SECTION.
PERFORM INIT-PARA.
PERFORM LOOP-PARA
PERFORM END-PARA.

INIT-PARA SECTION.
DISPLAY "A SIMPLE INSPECT VERB".
INIT-PARA-EXIT.
EXIT.
LOOP-PARA SECTION.

*Format 1: INSPECT ... TALLYING

INITIALIZE WS-CNTS
MOVE "AARDVARK EXTRA" TO WS-STRING

INSPECT WS-STRING
TALLYING WS-CNT-1 FOR LEADING "A"
WS-CNT-2 FOR ALL "R"
WS-CNT-3 FOR CHARACTERS.

DISPLAY "ws-string = " ws-string


DISPLAY "WS-CNT-1 = " WS-CNT-1
DISPLAY "WS-CNT-2 = " WS-CNT-2
DISPLAY "WS-CNT-3 = " WS-CNT-3

*Format 2: INSPECT... REPLACING

INITIALIZE WS-CNTS
MOVE "AARDVARK EXTRA" TO WS-STRING

DISPLAY "BEFORE WS-STRING = " WS-STRING


INSPECT WS-STRING
REPLACING FIRST "A" BY "B"
ALL "R" BY "S".

DISPLAY "AFTER WS-STRING = " WS-STRING

*Format 3: INSPECT... TALLYING... REPLACING

INITIALIZE WS-CNTS
MOVE "AARDVARK EXTRA" TO WS-STRING

INSPECT WS-STRING
TALLYING WS-CNT-1 FOR ALL "A"
REPLACING LEADING "A" BY "B"
ALL "R" BY "S".

DISPLAY "ws-string = " ws-string


DISPLAY "WS-CNT-1 = " WS-CNT-1
DISPLAY "WS-CNT-2 = " WS-CNT-2
DISPLAY "WS-CNT-3 = " WS-CNT-3

Información Confidencial | Información Propietaria de Gladius Technology | Página 137 de


176
*Format 4: INSPECT ... CONVERTING

INITIALIZE WS-CNTS
MOVE "AARDVARK EXTRA" TO WS-STRING

INSPECT WS-STRING
CONVERTING "RVX" TO "QUW".

DISPLAY "ws-string = " ws-string


DISPLAY "WS-CNT-1 = " WS-CNT-1
DISPLAY "WS-CNT-2 = " WS-CNT-2
DISPLAY "WS-CNT-3 = " WS-CNT-3

*the BEFORE and AFTER Clauses


INITIALIZE WS-CNTS
MOVE "AARDVARK EXTRA" TO WS-STRING

INSPECT WS-STRING
TALLYING WS-CNT-1
FOR ALL "A" BEFORE SPACE.

DISPLAY "ws-string = " ws-string


DISPLAY "WS-CNT-1 = " WS-CNT-1
DISPLAY "WS-CNT-2 = " WS-CNT-2
DISPLAY "WS-CNT-3 = " WS-CNT-3
INITIALIZE WS-CNTS
MOVE "AARDVARK EXTRA" TO WS-STRING
INSPECT WS-STRING
TALLYING WS-CNT-2
FOR ALL "R" AFTER "K".
DISPLAY "ws-string = " ws-string
DISPLAY "WS-CNT-1 = " WS-CNT-1
DISPLAY "WS-CNT-2 = " WS-CNT-2
DISPLAY "WS-CNT-3 = " WS-CNT-3
INITIALIZE WS-CNTS
MOVE "AARDVARK EXTRA" TO WS-STRING
INSPECT WS-STRING
TALLYING WS-CNT-3 FOR CHARACTERS
AFTER "D" BEFORE "T".

DISPLAY "ws-string = " ws-string


DISPLAY "WS-CNT-1 = " WS-CNT-1
DISPLAY "WS-CNT-2 = " WS-CNT-2
DISPLAY "WS-CNT-3 = " WS-CNT-3.
LOOP-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "MANY THANKS!".
END-PARA-EXIT.
GOBACK.

The STRING Format

Use the STRING format to build up a field from several other fields.

Información Confidencial | Información Propietaria de Gladius Technology | Página 138 de


176
The following example does not use the STRING format, but might yield unnecessary
spaces in the results.

01 WS-FIELDS.
03 WS-FIRST-NAME PIC X(12)
VALUE "BEOWULF".
03 WS-SURNAME PIC X(20)
VALUE "SHAEFFER".
03 WS-SALARY PIC 9(6)V99.
01 WS-OUTPUT-NAME PIC X(30) VALUE SPACES.

The two-character strings will contain trailing spaces, five in the case of WS-FIRST-
NAME and twelve for WS-SURNAME. It would be useful to have the name complete,
but with just one space between the "F" of the first name and the surname.

STRING achieves this with the help of INSPECT afterwards, as used in the following
code.

STRING
WS-FIRST-NAME DELIMITED BY SPACE
"*" DELIMITED BY SIZE
WS-SURNAME DELIMITED BY SPACE
INTO WS-OUTPUT-NAME
END-STRING.

INSPECT WS-OUTPUT-NAME
REPLACING ALL "*" BY SPACE.

In the example STRING places the first name and surname into WS-OUTPUT-NAME.

Here, "DELIMITED BY SPACE" means to process all the characters in the string until a
space is encountered. So, WS-FIRST-NAME and WS-SURNAME are truncated to the
right length. However, we want a space between the two. We can't specify " ", as
DELIMITED BY SPACE will instantly remove it. Instead, we specify an asterisk or any
other character that will not be found in either part of the name. Because "*" does not
contain a space, the whole thing is moved.

We could also have said DELIMITED BY SIZE for this literal, which means "move the
whole field." INSPECT would then turn that asterisk back into a space.

POINTER and ON OVERFLOW Clauses

As you might recall from discussions about the MOVE verb, MOVE spacefills a receiving
field if the value received is too small. Since STRING does not do this, it is best to
initialize the receiving field, and then use POINTER and ON OVERFLOW clauses, as
illustrated in the following code.

01 WS-POINTER PIC 9(4).


[other code]
INITIALIZE WS-OUTPUT-NAME.

Información Confidencial | Información Propietaria de Gladius Technology | Página 139 de


176
MOVE 1 TO WS-POINTER.
STRING
WS-FIRST-NAME DELIMITED BY SPACE
"*" DELIMITED BY SIZE
WS-SURNAME DELIMITED BY SPACE
INTO WS-OUTPUT-NAME
POINTER WS-POINTER
ON OVERFLOW PERFORM TOO-BIG
END-STRING

After this statement, POINTER contains 17, the number of the next free byte (which is
why we set it to 1 at the beginning). Note: Specifying POINTER in this way requires
setting it to a positive value at the start, or nothing will appear in the output string.

The ON OVERFLOW clause is triggered if the STRING is impossible because the number
of characters being transferred is too large for the receiving field. ON OVERFLOW will
also be triggered if a POINTER clause cannot occur, which would happen if the pointer
field is less than 1 or greater than the number of bytes in the receiving field.

NOT ON OVERFLOW Clause

There is also a NOT ON OVERFLOW clause, as used in the following code.

STRING
WS-FIRST-NAME DELIMITED BY SPACE
"*" DELIMITED BY SIZE
WS-SURNAME DELIMITED BY SPACE
INTO WS-OUTPUT-NAME
POINTER WS-POINTER
ON OVERFLOW PERFORM TOO-BIG
NOT ON OVERFLOW PERFORM OK-ACTIONS
END-STRING

Example 8.8

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE88.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-FIELDS.
03 WS-FIRST-NAME PIC X(12).
03 WS-SURNAME PIC X(20).
03 WS-SALARY PIC 9(6)V99.
01 WS-POINTER PIC 9(4).
01 WS-OUTPUT-NAME PIC X(30).
PROCEDURE DIVISION.
MAINLINE SECTION.
PERFORM INIT-PARA.
PERFORM LOOP-PARA
PERFORM END-PARA.

INIT-PARA SECTION.

Información Confidencial | Información Propietaria de Gladius Technology | Página 140 de


176
DISPLAY "A SIMPLE string TEST".
INITIALIZE WS-OUTPUT-NAME
MOVE "BEOWULF" TO WS-FIRST-NAME
MOVE "SHAEFFER" TO WS-SURNAME.
INIT-PARA-EXIT.
EXIT.
LOOP-PARA SECTION.

*Format 1:

INITIALIZE WS-OUTPUT-NAME
WS-POINTER
MOVE "BEOWULF" TO WS-FIRST-NAME
MOVE "SHAEFFER" TO WS-SURNAME

STRING
WS-FIRST-NAME DELIMITED BY SPACE
"*" DELIMITED BY SIZE
WS-SURNAME DELIMITED BY SPACE
INTO WS-OUTPUT-NAME
END-STRING

DISPLAY "WS-OUTPUT-NAME AFTER STRING = "


WS-OUTPUT-NAME

INSPECT WS-OUTPUT-NAME
REPLACING ALL "*" BY SPACE.
DISPLAY "AFTER INSPECT WS-OUTPUT-NAME = "
WS-OUTPUT-NAME

*Format 2:

INITIALIZE WS-OUTPUT-NAME
MOVE 1 TO WS-POINTER
MOVE "BEOWULF" TO WS-FIRST-NAME
MOVE "SHAEFFER" TO WS-SURNAME

STRING
WS-FIRST-NAME DELIMITED BY SPACE
"*" DELIMITED BY SIZE
WS-SURNAME DELIMITED BY SPACE
INTO WS-OUTPUT-NAME
POINTER WS-POINTER
ON OVERFLOW PERFORM TOO-BIG
END-STRING

DISPLAY "AFTER WS-OUTPUT-NAME = "


WS-OUTPUT-NAME

INITIALIZE WS-OUTPUT-NAME
MOVE 20 TO WS-POINTER
MOVE "BEOWULF" TO WS-FIRST-NAME
MOVE "SHAEFFER" TO WS-SURNAME

STRING
WS-FIRST-NAME DELIMITED BY SPACE
"*" DELIMITED BY SIZE
WS-SURNAME DELIMITED BY SPACE

Información Confidencial | Información Propietaria de Gladius Technology | Página 141 de


176
INTO WS-OUTPUT-NAME
POINTER WS-POINTER
ON OVERFLOW PERFORM TOO-BIG
END-STRING

*Format 3:

INITIALIZE WS-OUTPUT-NAME
MOVE 1 TO WS-POINTER
MOVE "BEOWULF" TO WS-FIRST-NAME
MOVE "SHAEFFER" TO WS-SURNAME

STRING
WS-FIRST-NAME DELIMITED BY SPACE
"*" DELIMITED BY SIZE
WS-SURNAME DELIMITED BY SPACE
INTO WS-OUTPUT-NAME
POINTER WS-POINTER
ON OVERFLOW PERFORM TOO-BIG
NOT OVERFLOW PERFORM OK-ACTIONS
END-STRING

DISPLAY "AFTER WS-OUTPUT-NAME = "


WS-OUTPUT-NAME.
LOOP-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "MANY THANKS!".
END-PARA-EXIT.
GOBACK.
TOO-BIG SECTION.
DISPLAY "TO BIG".
TOO-BIG-EXIT.
EXIT.
OK-ACTIONS SECTION.
DISPLAY "OK-ACTIONS ".
OK-ACTIONS-EXIT.
EXIT.

The UNSTRING Format

The UNSTRING format, as you might expect, works in the opposite way to STRING. Use
it to divide up a string of characters. It works by recognizing delimiter characters. So,
even more than with STRING, delimiters help to ensure that the receiving fields contain
the correct information.

The following code uses UNSTRING to divide up the INPUT-NAME string.

01 INPUT-NAME PIC X(30)


[which contains 'PATRICIA**HUMPHREYS']
01 RECEIVING-FIELDS.
03 R-FIELD-1 PIC X(12).
03 R-FIELD-2 PIC X(12).
03 R-FIELD-3 PIC X(12).
[other code]
UNSTRING INPUT-NAME

Información Confidencial | Información Propietaria de Gladius Technology | Página 142 de


176
DELIMITED BY "*"
INTO
R-FIELD-1 R-FIELD-2 R-FIELD-3
END-UNSTRING.

After this statement, R-FIELD-1 contains "PATRICIA", R-FIELD-2 is blank (there is nothing
before the next delimiter), and R-FIELD-3 contains "HUMPHREYS".

To UNSTRING a string with more than one contiguous occurrence of a delimiter as just
one character, use the following code.

UNSTRING INPUT-NAME
DELIMITED BY ALL "*"
INTO R-FIELD-1 R-FIELD-2 R-FIELD-3
END-UNSTRING

This case results in 'HUMPHREYS' now ending up in R-FIELD-2.

The full syntax of UNSTRING is shown in the following code.

UNSTRING [field]
DELIMITED BY (ALL) [literal or field name]
OR (ALL) [literal or field name] etc.)
INTO [field name]
(DELIMITER [field name])
(COUNT [field name])
INTO [field name]
(DELIMITER [field name])
(COUNT [field name] etc)
(POINTER [field name])
(TALLYING IN [field name])
(ON OVERFLOW [action(s)])
(NOT ON OVERFLOW [action()s])
(END-UNSTRING)

This code performs as follows:

• UNSTRING can use many different potential delimiters to separate out each
substring.
• In each case, the field specified by DELIMITER holds the actual delimiter used.
• The COUNT field records how many bytes were transferred.
• POINTER keeps track of the total number of bytes moved over. As with STRING,
set it to a positive value before the statement takes place.
• TALLYING IN keeps count of the total number of receiving fields that contain
data when the UNSTRING finishes.
• ON OVERFLOW and NOT ON OVERFLOW are as before.

Reference modification

Información Confidencial | Información Propietaria de Gladius Technology | Página 143 de


176
There is one more way to extract a substring from a string of characters. This is called
reference modification, which can be used only when the value contained in that string
is known. The following code provides an example of reference modification.

01 WS-ALPHABET PIC X(26)


VALUE "ABCDEFGHIJKLMNOPQRSTUVWXYZ".
01 WS-SMALLER-STRING PIC X(10).
[other code]
MOVE WS-ALPHABET (12:6)
TO WS-SMALLER-STRING.

This code results in six characters, starting at position 12, being copied across. WS-
SMALLER-STRING will therefore contain "LMNOPQ".

Example 8.9

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE89.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
01 INPUT-NAME PIC X(30).
01 RECEIVING-FIELDS.
03 R-FIELD-1 PIC X(12).
03 R-FIELD-2 PIC X(12).
03 R-FIELD-3 PIC X(12).
01 WS-TALLY PIC 9(4).
01 WS-OUTPUT-NAME PIC X(30).
01 WS-ALPHABET PIC X(26)
01 WS-SMALLER-STRING PIC X(10).
PROCEDURE DIVISION.
MAINLINE SECTION.
PERFORM INIT-PARA.
PERFORM LOOP-PARA
PERFORM END-PARA.

INIT-PARA SECTION.
DISPLAY "A SIMPLE UNstring TEST".
INIT-PARA-EXIT.
EXIT.
LOOP-PARA SECTION.
*Format 1:

INITIALIZE WS-OUTPUT-NAME
RECEIVING-FIELDS
MOVE "PATRICIA**HUMPHREYS" TO INPUT-NAME

UNSTRING INPUT-NAME
DELIMITED BY "*"
INTO
R-FIELD-1 R-FIELD-2 R-FIELD-3
END-UNSTRING

Información Confidencial | Información Propietaria de Gladius Technology | Página 144 de


176
DISPLAY "R-FIELD-1 = " R-FIELD-1
DISPLAY "R-FIELD-2 = " R-FIELD-2
DISPLAY "R-FIELD-3 = " R-FIELD-3
*Format 2:

INITIALIZE WS-OUTPUT-NAME
RECEIVING-FIELDS

MOVE "PATRICIA**HUMPHREYS" TO INPUT-NAME

UNSTRING INPUT-NAME
DELIMITED BY ALL "*"
INTO R-FIELD-1 R-FIELD-2 R-FIELD-3
END-UNSTRING

DISPLAY "R-FIELD-1 = " R-FIELD-1


DISPLAY "R-FIELD-2 = " R-FIELD-2
DISPLAY "R-FIELD-3 = " R-FIELD-3

*Format 3:

INITIALIZE WS-OUTPUT-NAME
RECEIVING-FIELDS
WS-TALLY

MOVE "PATRICIA**HUMPHREYS" TO INPUT-NAME

UNSTRING INPUT-NAME
DELIMITED BY ALL "*"
INTO R-FIELD-1 R-FIELD-2 R-FIELD-3
TALLYING IN WS-TALLY
END-UNSTRING

DISPLAY "R-FIELD-1 = " R-FIELD-1


DISPLAY "R-FIELD-2 = " R-FIELD-2
DISPLAY "R-FIELD-3 = " R-FIELD-3
DISPLAY "WS-TALLY = " WS-TALLY
*Reference modification
MOVE "ABCDEFGHIJKLMNOPQRSTUVWXYZ" TO
WS-ALPHABET
MOVE WS-ALPHABET (12:6) TO WS-SMALLER-STRING.
DISPLAY "WS-SMALLER-STRING = " WS-SMALLER-STRING.
LOOP-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "MANY THANKS!".
END-PARA-EXIT.
GOBACK.

8.6. Using Data Manipulation Verbs


Let us assume that we are writing a program that reads in a file of sales staff records
and does the following.

• The input file may have any number of records (including 0).

Información Confidencial | Información Propietaria de Gladius Technology | Página 145 de


176
• All input records contain a one-character region ("N", "S", "E" or "W"), and an
eight-digit sales total field (six digits, two decimal places).
• Generate four totals, one for each region. As each record is read, update the
appropriate total with the value in the sales total.
• At the end of the program, all totals display, along with average sales for each
region. We therefore need a record count for each region.

The program design is very simple, as the following graphic depicts.

Strictly speaking, all regions should be shown as separate, but because the actions are
identical for all, it will do no harm to group them together.

The graphic below lists the actions.

Información Confidencial | Información Propietaria de Gladius Technology | Página 146 de


176
The following example suggests one method of coding the program.

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE810.
ENVIRONMENT DIVISION .
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION .
FILE-CONTROL .
SELECT INFILE ASSIGN "INFILE810.DAT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS INFILE-FILE-STATUS.
DATA DIVISION .
FD INFILE .
01 INREC .
03 REGION PIC X .
88 NORTH VALUE "N" .
88 SOUTH VALUE "S" .
88 EAST VALUE "E" .
88 WEST VALUE "W" .
03 IN-TOTAL PIC 9(6)V99 .
WORKING-STORAGE SECTION .
01 INFILE-FILE-STATUS PIC X(02).
01 WS-EOF PIC 9.
88 END-OF-FILE VALUE 1 .
01 WS-NUMERICS.
03 WS-N-RECORDS PIC 9(4) .
03 WS-S-RECORDS PIC 9(4) .
03 WS-E-RECORDS PIC 9(4) .
03 WS-W-RECORDS PIC 9(4) .
03 WS-N-TOTAL PIC 9(10)V99 .
03 WS-S-TOTAL PIC 9(10)V99 .
03 WS-E-TOTAL PIC 9(10)V99 .
03 WS-W-TOTAL PIC 9(10)V99 .
03 WS-N-AVERAGE PIC 9(6)V99 .
03 WS-S-AVERAGE PIC 9(6)V99 .
03 WS-E-AVERAGE PIC 9(6)V99 .
03 WS-W-AVERAGE PIC 9(6)V99 .
01 WS-EDITED-FIELDS .
03 WS-EDITED-N PIC Z(5)9.99 .
03 WS-EDITED-S PIC Z(5)9.99 .
03 WS-EDITED-E PIC Z(5)9.99 .
03 WS-EDITED-W PIC Z(5)9.99 .
01 WS-MESSAGE PIC X(80) .
PROCEDURE DIVISION .
PROG-PARA SECTION.
PERFORM INIT-PARA .
PERFORM BOD-PARA .
PERFORM END-PARA .
INIT-PARA SECTION.
DISPLAY "STARTING CALCULATION PROGRAM" .
INITIALIZE INFILE-FILE-STATUS
WS-EOF
WS-NUMERICS
WS-MESSAGE
OPEN INPUT INFILE.
IF INFILE-FILE-STATUS NOT = ZERO
DISPLAY "INVALID INFILE810 FILE" INFILE-FILE-STATUS

Información Confidencial | Información Propietaria de Gladius Technology | Página 147 de


176
GOBACK
END-IF.
PERFORM READ-FILE.
INIT-PARA-EXIT.
EXIT.
BOD-PARA SECTION.
PERFORM UNTIL END-OF-FILE
PERFORM PROCESS-REC
END-PERFORM.
BOD-PARA-EXIT.
EXIT.
END-PARA SECTION.
IF WS-N-RECORDS > 0 THEN
DIVIDE WS-N-TOTAL BY WS-N-RECORDS
GIVING WS-N-AVERAGE ROUNDED
END-DIVIDE
END-IF
IF WS-S-RECORDS > 0 THEN
DIVIDE WS-S-TOTAL BY WS-S-RECORDS
GIVING WS-S-AVERAGE ROUNDED
END-DIVIDE
END-IF
IF WS-E-RECORDS > 0 THEN
DIVIDE WS-E-TOTAL BY WS-E-RECORDS
GIVING WS-E-AVERAGE ROUNDED
END-DIVIDE
END-IF
IF WS-W-RECORDS > 0 THEN
DIVIDE WS-W-TOTAL BY WS-W-RECORDS
GIVING WS-W-AVERAGE ROUNDED
END-DIVIDE
END-IF
INITIALIZE WS-MESSAGE
STRING WS-N-RECORDS DELIMITED BY SIZE
" " DELIMITED BY SIZE
"N RECORDS, " DELIMITED BY SIZE
WS-S-RECORDS DELIMITED BY SIZE
" " DELIMITED BY SIZE
"S RECORDS, " DELIMITED BY SIZE
WS-E-RECORDS DELIMITED BY SIZE
" " DELIMITED BY SIZE
"E RECORDS, " DELIMITED BY SIZE
WS-W-RECORDS DELIMITED BY SIZE
" " DELIMITED BY SIZE
"W RECORDS" DELIMITED BY SIZE
INTO WS-MESSAGE
END-STRING
DISPLAY WS-MESSAGE .
MOVE WS-N-AVERAGE TO WS-EDITED-N .
MOVE WS-S-AVERAGE TO WS-EDITED-S .
MOVE WS-E-AVERAGE TO WS-EDITED-E .
MOVE WS-W-AVERAGE TO WS-EDITED-W .
INITIALIZE WS-MESSAGE
STRING "N AVE = " DELIMITED BY SIZE
WS-EDITED-N DELIMITED BY SIZE
", " DELIMITED BY SIZE
"S AVE = " DELIMITED BY SIZE
WS-EDITED-S DELIMITED BY SIZE

Información Confidencial | Información Propietaria de Gladius Technology | Página 148 de


176
", " DELIMITED BY SIZE
"E AVE = " DELIMITED BY SIZE
WS-EDITED-E DELIMITED BY SIZE
", " DELIMITED BY SIZE
"W AVE = " DELIMITED BY SIZE
WS-EDITED-W DELIMITED BY SIZE
INTO WS-MESSAGE
END-STRING
DISPLAY WS-MESSAGE .
CLOSE INFILE .
END-PARA-EXIT.
GOBACK.
PROCESS-REC SECTION.
EVALUATE TRUE
WHEN NORTH
ADD 1 TO WS-N-RECORDS
ADD IN-TOTAL TO WS-N-TOTAL
WHEN SOUTH
ADD 1 TO WS-S-RECORDS
ADD IN-TOTAL TO WS-S-TOTAL
WHEN EAST
ADD 1 TO WS-E-RECORDS
ADD IN-TOTAL TO WS-E-TOTAL
WHEN WEST
ADD 1 TO WS-W-RECORDS
ADD IN-TOTAL TO WS-W-TOTAL
WHEN OTHER
CONTINUE
END-EVALUATE.

PERFORM READ-FILE.
PROCESS-REC-EXIT.
EXIT.
READ-FILE SECTION.
READ INFILE
AT END SET END-OF-FILE TO TRUE
END-READ.
READ-FILE-EXIT.
EXIT.

This produces output similar to the following:

Starting calculation program


0004 N records, 0006 S records, 0008 E records, 0006 W records
N ave = 10022.98, S ave = 41504.88, E ave = 84961.77, W ave =
36787.15

Consider the following points regarding this code.

• Before calculating any average, the program makes a check to ensure that
records were found for that region. This avoids a "divide by zero" error.
• STRING produces messages, which are stored in WS-MESSAGE and from there
DISPLAYed. Record counts employ normal fields, and so 4 displays as "0004".
However, to show the difference in appearance, edited fields are used for the

Información Confidencial | Información Propietaria de Gladius Technology | Página 149 de


176
averages. (A later module discusses edited fields.) Briefly, edited fields make a
number more readable. Each edited field uses the format Z(5)9.99, which
replaces any leading zeros with spaces (hence the Z). An explicit period (full
stop) is inserted before the decimal part of the field, thus giving a value of, for
example, 41504.88 instead of 04150488. Edited fields are very useful in making
numbers and results of calculations more legible. They are not designed for
calculation; therefore, numbers are moved to them after calculations are
complete.
• All the working-storage counts are PIC 9 DISPLAY rather than COMP. This is
because STRING manipulates only character data.

8.7. Summary
In this module we have examined the following topics:

• The INITIALIZE verb


• The arithmetic COBOL verbs ADD, SUBTRACT, MULTIPLY, DIVIDE and COMPUTE
• The verbs for manipulating character data INSPECT, STRING and UNSTRING
• Reference modification

8.8. Exercise: Using Calculations and


Accumulations
Introduction

The purpose of this program is to read the Sales Master file and accumulate the total
sales for each region and a grand total of all regions. This program should calculate the
average overall sale and average sales for each region

It should also calculate Sales for each region as a percentage (to two decimal places,
rounded) of the total sales. All of the totals and averages should be displayed.

Details

The program created by this exercise can use the program created in the last exercise
as a starting point.

1. Start your editor.

2. Open PROGRAM81.CBL located in X:\\CLASS\MODULE8\NETX

Información Confidencial | Información Propietaria de Gladius Technology | Página 150 de


176
3. Design and code a COBOL program to do the following:

• Read in a file of records, and then deal with them in different ways depending on the type of
record found. The input file may have any number of records, including zero.
• Each record should contain a one-character region ("N", "S", "E" or "W"), and an eight-digit
sales total field (six digits, two decimal places). Any record that does not have a valid region
code should be displayed. Do not take any further action with that record (meaning, do not
include any value in the sales field in the calculations shown below).
• Include four totals, one for each region. As the program reads each record, update the
appropriate total with the value in the sales total.
• At the end of the program, display the following:
• All record counts, including invalid records
• Grand total of sales
• Total sales for each region
• An average overall sale and average sales for each region
• Sales for each region as a percentage (to two decimal places, rounded) of the total sales

4. Run and test the program.

5. The displays produced by the program should have the same format as the following: (Note the

edit format fields)

Starting calculation program


Invalid record Q77777777
Invalid record L34873424
Invalid record Z00000001
Total records read: 00027
These comprise 0004 N, 0006 S, 0008 E, 0006 W, 0003 invalid
Grand sales total: $1189538.24
North sales total: $ 40091.93
South sales total: $ 249029.30
East sales total: $ 679694.13
West sales total: $ 220722.88
Overall average 49564.09
North average 10022.98
South average 41504.88
East average 84961.77
West average 36787.15
North percentage of total: 3.37%
South percentage of total: 20.93%
East percentage of total: 57.13%
West percentage of total: 18.55%

6. Save the program in the X:\CLASS\MODULE8\NETX directory and provide the program name

PROGRAM81.CBL.

9. Module 9: Handling Repeating Data


Información Confidencial | Información Propietaria de Gladius Technology | Página 151 de
176
Intelligent use of multi-dimensional tables can rapidly speed up program development
and add clarity to application logic for maintenance programmers. Here we become
familiar with the powerful COBOL constructs for defining and manipulating these
tables.

9.1. Objectives
At the end of this module you will be able to:

• Explain the need for representation of repeating data in COBOL.


• Use subscripts and indexes to manipulate tables of such data.
• Use PERFORM with repeating data.
• Use different forms of the SEARCH verb to access a table.
• Write COBOL programs demonstrating all of the above topics.

9.2. What is Repeating Data?


A very common business need is to be able to access and manipulate groups, or
occurrences, of data that are of the same size and type. For example, a monthly
salesperson record may need to show:

• Name
• Salary
• 5 sets of weekly sales figures

This group of data repeats. These could be expressed as shown in the following code.

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE91.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
01 SALES-RECORD.
03 SALES-NAME PIC X(20).
03 SALES-SALARY PIC 9(6)V99.
03 SALES-WEEK-1 PIC 9(5)V99.
03 SALES-WEEK-2 PIC 9(5)V99.
03 SALES-WEEK-3 PIC 9(5)V99.
03 SALES-WEEK-4 PIC 9(5)V99.
03 SALES-WEEK-5 PIC 9(5)V99.
01 MONTHLY-SALES PIC 9(10)V99.
PROCEDURE DIVISION.
MAINLINE SECTION.
PERFORM INIT-PARA.

Información Confidencial | Información Propietaria de Gladius Technology | Página 152 de


176
PERFORM LOOP-PARA.
PERFORM END-PARA.
INIT-PARA SECTION.
DISPLAY "A SIMPLE TABLE TEST".
INIT-PARA-EXIT.
EXIT.
LOOP-PARA SECTION.
DISPLAY "TEST 1:"
INITIALIZE SALES-RECORD
REPLACING ALPHANUMERIC DATA BY ALL "?"
NUMERIC DATA BY ALL "6".
MOVE ZERO TO MONTHLY-SALES
*This is acceptable for five occurrences,
*although
*it does not accurately reflect the fact
*that this is a repeating field.
*The code to accumulate the totals would be
*something like the following code.
ADD SALES-WEEK-1
SALES-WEEK-2
SALES-WEEK-3
SALES-WEEK-4
SALES-WEEK-5
GIVING MONTHLY-SALES
DISPLAY MONTHLY-SALES
DISPLAY " ".
LOOP-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "MANY THANKS!".
END-PARA-EXIT.
GOBACK.

This is clumsy and would become totally unworkable if it were necessary to store 52
such fields, say one for every week of the year.

9.3. What is a Table?


The answer is to use a table. A table holds a set of different data items that have the
same definition. The items in the table can be accessed using a reference to the item,
called a subscript. A table is defined using the OCCURS clause in the DATA DIVISION.

We could define the information in the previous code using a table, as follows.

Exercise ( add a for loop for the ADD statement).

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE92.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.

Información Confidencial | Información Propietaria de Gladius Technology | Página 153 de


176
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
01 SALES-RECORD.
03 SALES-NAME PIC X(20).
03 SALES-SALARY PIC 9(6)V99.
03 SALES-WEEK PIC 9(5)V99 occurs 5 times.
01 MONTHLY-SALES PIC 9(10)V99.
PROCEDURE DIVISION.
MAINLINE SECTION.
PERFORM INIT-PARA.
PERFORM LOOP-PARA.
PERFORM END-PARA.
INIT-PARA SECTION.
DISPLAY "A SIMPLE TABLE TEST".
INIT-PARA-EXIT.
EXIT.
LOOP-PARA SECTION.
DISPLAY "TEST 1:"
INITIALIZE SALES-RECORD
REPLACING ALPHANUMERIC DATA BY ALL "?"
NUMERIC DATA BY ALL "6".
MOVE ZERO TO MONTHLY-SALES
* The OCCURS clause indicates that the
* SALES-WEEK
* item occurs 5 times. Such an OCCURS can occur
* as a group or an elementary field, but not at
* the 01 level.
* To access a particular occurrence,
* one can use subscripts as in the following
* code.
* The subscript of a table shows in
* parentheses.
* The following represents the first occurrence
* of SALES-WEEK.SALES-WEEK(1)
* It would therefore be possible to perform
* an ADD on this occurrence, as shown
* in the following example.
ADD SALES-WEEK(1)
SALES-WEEK(2)
SALES-WEEK(3)
SALES-WEEK(4)
SALES-WEEK(5)
GIVING MONTHLY-SALES
DISPLAY MONTHLY-SALES.
LOOP-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "MANY THANKS!".
END-PARA-EXIT.
GOBACK.

Using Subscripts

However, there is a far better way to write this by using a variable as the subscript and
a form of the verb PERFORM, as shown in the following code.

Información Confidencial | Información Propietaria de Gladius Technology | Página 154 de


176
IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE93.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
01 SALES-RECORD.
03 SALES-NAME PIC X(20).
03 SALES-SALARY PIC 9(6)V99.
03 SALES-WEEK PIC 9(5)V99 OCCURS 5 TIMES.
01 WS-SUB PIC 99.
01 MONTHLY-SALES PIC 9(10)V99.
PROCEDURE DIVISION.
MAINLINE SECTION.
PERFORM INIT-PARA.
PERFORM LOOP-PARA.
PERFORM END-PARA.
INIT-PARA SECTION.
DISPLAY "A SIMPLE TABLE TEST".
INIT-PARA-EXIT.
EXIT.
LOOP-PARA SECTION.
DISPLAY "TEST 1:"
INITIALIZE SALES-RECORD
REPLACING ALPHANUMERIC DATA BY ALL "?"
NUMERIC DATA BY ALL "6".

MOVE ZERO TO MONTHLY-SALES


PERFORM VARYING WS-SUB FROM 1 BY 1
UNTIL WS-SUB > 5
ADD SALES-WEEK(WS-SUB) TO MONTHLY-SALES
END-PERFORM

DISPLAY MONTHLY-SALES.
LOOP-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "MANY THANKS!".
END-PARA-EXIT.
GOBACK.

The PERFORM verb starts by setting WS-SUB to 1, and as the subscript is not greater
than 5, SALES-WEEK(1) is added to MONTHLY-SALES (which should have been initialized
at some point). The loop goes around again. WS-SUB is incremented automatically (BY
1) and the second occurrence is added. This goes on until SALES-WEEK(5) has been
added. The next time around the UNTIL is now true, so the PERFORM stops.

Although this code takes up as many lines on the page as the explicit adding of all five
occurrences, it is far more logical. Furthermore, it would be very straightforward to
modify both the record and the code to cope with 52 entries, as shown next.

Exercise ( Write Display's to output file. Add file definitions code).

Información Confidencial | Información Propietaria de Gladius Technology | Página 155 de


176
IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE94.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
01 SALES-RECORD.
03 SALES-NAME PIC X(20).
03 SALES-SALARY PIC 9(6)V99.
03 SALES-WEEK PIC 9(5)V99 OCCURS 52 TIMES.
01 WS-SUB PIC 99.
01 YEARLY-SALES PIC 9(10)V99.
PROCEDURE DIVISION.
MAINLINE SECTION.
PERFORM INIT-PARA.
PERFORM LOOP-PARA.
PERFORM END-PARA.
INIT-PARA SECTION.
DISPLAY "A SIMPLE TABLE TEST".
INIT-PARA-EXIT.
EXIT.
LOOP-PARA SECTION.
DISPLAY "TEST 1:"
INITIALIZE SALES-RECORD
REPLACING ALPHANUMERIC DATA BY ALL "?"
NUMERIC DATA BY ALL "6".
MOVE ZERO TO YEARLY-SALES
PERFORM VARYING WS-SUB FROM 1 BY 1
UNTIL WS-SUB > 52
ADD SALES-WEEK(WS-SUB) TO YEARLY-SALES
END-PERFORM
DISPLAY YEARLY-SALES.
LOOP-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "MANY THANKS!".
END-PARA-EXIT.
GOBACK.

NOTE: When using tables, make sure that the subscript always keeps in range. For
example, when using OCCURS 10, the subscript pointing to the table should never go
below 1 or exceed 10, or it will try and access memory used by something else. At
runtime this could cause the program to crash.

A related error is to use a subscript that is too small. For example, a table that OCCURS
100 must have a subscript PIC 999. It is a common beginner's mistake to make the
subscript PIC 99, which works perfectly until the subscript is 99 and 1 is added. The
subscript then resets to zero. At the very least the program will do something wrong.

9.4. Using REDEFINES Clauses in Tables

Información Confidencial | Información Propietaria de Gladius Technology | Página 156 de


176
OCCURS clauses cannot have VALUE clauses directly associated with them. This may
seem to cause a problem, because it is very useful to be able to have something like
the following table example that shows an item number, item description, and cost.

01 Dog Food Large 27.99


02 Cat Food Large 23.99
03 Dog Food Medium 17.50
04 Cat Food Medium 16.50
05 Dog Food Small 9.99
06 Cat Food Small 8.99

Here the number (01-06) could be read in from a file. Next, we want to look through
the table, finding a match. So, if 04 is on the input record, we want to use "Cat Food
Medium" and 16.50, perhaps on an invoice.

This needs both predefined entries (in other words, VALUE clauses) and an occurring
table. However, both cannot exist in the same place. We can use the REDEFINES clause
to initialize the values in a table. Use the REDEFINES in the WORKING STORAGE section.

The following shows how we might define the data using VALUE clauses and then load
the table using a REDEFINES clause.

01 WS-PETFOOD.
03 FILLER PIC X(22)
VALUE "01Dog Food Large 2799".
03 FILLER PIC X(22)
VALUE "02Cat Food Large 2399".
03 FILLER PIC X(22)
VALUE "03Dog Food Medium 1750".
03 FILLER PIC X(22)
VALUE "04Cat Food Medium 1650".
03 FILLER PIC X(22)
VALUE "05Dog Food Small 0999".
03 FILLER PIC X(22)
VALUE "06Cat Food Small 0899".
01 WS-PETFOOD-REDEF REDEFINES WS-PETFOOD.
03 WS-PET-DETAILS OCCURS 6.
05 WS-TABLE-NUM PIC 99.
05 WS-FOOD-DESCRIPTION
PIC X(16).
05 WS-PRICE PIC 99V99.

Here is a complete sample program, showing how the table could be used.

Exercise (Add code to create total and add the result to the file) The answer is
1008.71

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE95.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.

Información Confidencial | Información Propietaria de Gladius Technology | Página 157 de


176
SELECT INFILE ASSIGN "INFILE95.DAT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS INFILE-FILE-STATUS.
SELECT OUTFILE ASSIGN "OUTFILE95.DAT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS OUTFILE-FILE-STATUS.
DATA DIVISION.
FILE SECTION.
FD INFILE.
01 INREC.
03 IN-PRODUCT-NUM PIC 99.
03 IN-QTY PIC 99.
FD OUTFILE.
01 OUTREC.
03 OUT-PRODUCT-DESC PIC X(15).
03 OUT-QTY PIC 99.
03 OUT-PRICE PIC 9(4)V99.
WORKING-STORAGE SECTION.
01 OUTFILE-FILE-STATUS PIC X(02).
01 INFILE-FILE-STATUS PIC X(02).
01 WS-EOF PIC 9.
88 END-OF-FILE VALUE 1.
01 WS-PETFOOD.
03 FILLER PIC X(22)
VALUE "01DOG FOOD LARGE 2799".
03 FILLER PIC X(22)
VALUE "02CAT FOOD LARGE 2399".
03 FILLER PIC X(22)
VALUE "03DOG FOOD MEDIUM 1750".
03 FILLER PIC X(22)
VALUE "04CAT FOOD MEDIUM 1650".
03 FILLER PIC X(22)
VALUE "05DOG FOOD SMALL 0999".
03 FILLER PIC X(22)
VALUE "06CAT FOOD SMALL 0899".
01 WS-PETFOOD-REDEF REDEFINES WS-PETFOOD.
03 WS-PET-DETAILS OCCURS 6.
05 WS-TABLE-NUM PIC 99.
05 WS-FOOD-DESCRIPTION
PIC X(16).
05 WS-PRICE PIC 99V99.
01 WS-SUB PIC 9.

PROCEDURE DIVISION.
PROG SECTION.
PERFORM INIT-PARA.
PERFORM BOD-PARA.
PERFORM END-PARA.

INIT-PARA SECTION.
DISPLAY "PROGRAM STARTING".
INITIALIZE INFILE-FILE-STATUS
WS-EOF
WS-SUB
OPEN INPUT INFILE
IF INFILE-FILE-STATUS NOT = ZERO THEN

Información Confidencial | Información Propietaria de Gladius Technology | Página 158 de


176
DISPLAY "INVALID INFILE95 FILE"
INFILE-FILE-STATUS
GOBACK
END-IF
OPEN OUTPUT OUTFILE.
IF OUTFILE-FILE-STATUS NOT = ZERO THEN
DISPLAY "INVALID OUTFILE95 FILE"
OUTFILE-FILE-STATUS
GOBACK
END-IF
PERFORM READ-FILE.
INIT-PARA-EXIT.
EXIT.
BOD-PARA SECTION.
PERFORM UNTIL END-OF-FILE

PERFORM PROCESS-REC
PERFORM READ-FILE
END-PERFORM.
BOD-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "FINISHED.".
CLOSE INFILE
OUTFILE.
END-PARA-EXIT.
GOBACK.
PROCESS-REC SECTION.
PERFORM VARYING WS-SUB FROM 1 BY 1
UNTIL WS-SUB > 6
IF WS-TABLE-NUM(WS-SUB)
= IN-PRODUCT-NUM
MOVE WS-FOOD-DESCRIPTION(WS-SUB)
TO OUT-PRODUCT-DESC
MOVE IN-QTY TO OUT-QTY
COMPUTE OUT-PRICE =
OUT-QTY * WS-PRICE(WS-SUB)
WRITE OUTREC
EXIT PERFORM
END-IF
END-PERFORM.
PROCESS-REC-EXIT.
EXIT.
READ-FILE SECTION.
READ INFILE
AT END SET END-OF-FILE TO TRUE
END-READ.
READ-FILE-EXIT.
EXIT.

Let's look at the logic. Each input record contains a product number. A PERFORM loop
goes through the table looking for a match. When the PERFORM loop finds a match,
the corresponding description is copied across to an output record, an invoice amount
is calculated from the quantity (originally from the input record), and the price is
calculated from the table. Once a match has been found, we can use the very useful

Información Confidencial | Información Propietaria de Gladius Technology | Página 159 de


176
EXIT PERFORM (which forces an immediate jump out of the loop) to avoid wasting time
looking at any entries of the table further down.

9.5. Indexed Tables


Instead of using a subscript to access a table, you can use an index. This requires
slightly different code, as we shall see.

Indexes have two advantages over subscripts:

• Indexes hold a pointer to each table entry, providing more efficient access. For
example, imagine a table of ten elements, each four bytes long. If the index is
set to 6, the pointer will contain 20, with the last byte of the element before the
present position (the fifth). Setting the index to 10 will internally set the pointer
to 36 (the last byte in the ninth element). Setting it to 1 will make the internal
value 0.

17-20 33-36
1-4 5-8 9-12 13-16 21-24 25-28 29-32 37-40

ê ê

.... .... .... .... .... .... .... .... .... ....

1 2 3 4 5 6 7 8 9 10

• If an indexed table is sorted (as the pet food example was), then it can be
searched very efficiently, using the so-called "binary chop" method. This finds,
for example, any element in a thousand-element table in a maximum of ten
steps.

NOTE: To move a value to an index, do not use the MOVE statement; instead, use SET.
We shall see this later.

To specify that a table should be indexed rather than subscripted, the OCCURS
statement needs to be slightly different, as shown next. Specify the index by using the
INDEXED BY clause after the OCCURS clause. Use a unique data name (for example,
PET-IX) after INDEXED BY.

01 WS-PETFOOD-REDEF REDEFINES WS-PETFOOD.


03 WS-PET-DETAILS OCCURS 6
ASCENDING KEY WS-TABLE-NUM
INDEXED BY PET-IX.
05 WS-TABLE-NUM PIC 99.

Información Confidencial | Información Propietaria de Gladius Technology | Página 160 de


176
05 WS-FOOD-DESCRIPTION
PIC X(16).
05 WS-PRICE PIC 99V99.

The index is declared implicitly, so you must not define it elsewhere in working storage.
The ASCENDING (or DESCENDING) KEY clause should only be included if the table is
actually sorted; the clause specifies which field in the table is the one to be searched
against.

Using the SEARCH VERB

Use the SEARCH verb to access the tables. Use SEARCH ALL for sorted tables or SEARCH
for unsorted. SEARCH starts at the beginning of the table and searches to the end,
which is not efficient across large tables.

SEARCH ALL is more efficient because it performs a binary search starting in the middle
determining whether the value is greater or less than the item being searched. This
splitting process continues until the SEARCH ALL is complete. To use SEARCH ALL, the
table must be indexed and the elements of the table must be in ascending or
descending sequence.

The following example uses SEARCH ALL.

Exercise (Add the GST to all the prices in the file)

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE97.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
SELECT INFILE ASSIGN "INFILE97.DAT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS INFILE-FILE-STATUS.

SELECT OUTFILE ASSIGN "OUTFILE97.DAT"


ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS OUTFILE-FILE-STATUS.
DATA DIVISION.
FILE SECTION.
FD INFILE.
01 INREC.
03 IN-PRODUCT-NUM PIC 99.
03 IN-QTY PIC 99.

FD OUTFILE.
01 OUTREC.
03 OUT-PRODUCT-DESC PIC X(15).
03 OUT-QTY PIC 99.
03 OUT-PRICE PIC 9(4)V99.

Información Confidencial | Información Propietaria de Gladius Technology | Página 161 de


176
WORKING-STORAGE SECTION.
01 OUTFILE-FILE-STATUS PIC X(02).
01 INFILE-FILE-STATUS PIC X(02).
01 WS-EOF PIC 9.
88 END-OF-FILE VALUE 1.
01 WS-PETFOOD.
03 FILLER PIC X(22)
VALUE "01DOG FOOD LARGE 2799".
03 FILLER PIC X(22)
VALUE "02CAT FOOD LARGE 2399".
03 FILLER PIC X(22)
VALUE "03DOG FOOD MEDIUM 1750".
03 FILLER PIC X(22)
VALUE "04CAT FOOD MEDIUM 1650".
03 FILLER PIC X(22)
VALUE "05DOG FOOD SMALL 0999".
03 FILLER PIC X(22)
VALUE "06CAT FOOD SMALL 0899".
01 WS-PETFOOD-REDEF REDEFINES WS-PETFOOD.
03 WS-PET-DETAILS OCCURS 6
ASCENDING KEY IS WS-TABLE-NUM
INDEXED BY PET-IX.
05 WS-TABLE-NUM PIC 99.
05 WS-FOOD-DESCRIPTION
PIC X(16).
05 WS-PRICE PIC 99V99.
01 WS-SUB PIC 9.
PROCEDURE DIVISION.
PROG SECTION.
PERFORM INIT-PARA.
PERFORM BOD-PARA.
PERFORM END-PARA.
INIT-PARA SECTION.
DISPLAY "PROGRAM STARTING".
INITIALIZE OUTFILE-FILE-STATUS
INFILE-FILE-STATUS
WS-EOF
WS-SUB
OPEN INPUT INFILE
IF INFILE-FILE-STATUS NOT = ZERO THEN
DISPLAY "INVALID INFILE97 FILE ="
INFILE-FILE-STATUS
GOBACK
END-IF
OPEN OUTPUT OUTFILE.
IF OUTFILE-FILE-STATUS NOT = ZERO THEN
DISPLAY "INVALID OUTFILE97 FILE ="
OUTFILE-FILE-STATUS
GOBACK
END-IF
PERFORM READ-FILE.
INIT-PARA-EXIT.
EXIT.
BOD-PARA SECTION.
PERFORM UNTIL END-OF-FILE
PERFORM PROCESS-REC
PERFORM READ-FILE

Información Confidencial | Información Propietaria de Gladius Technology | Página 162 de


176
END-PERFORM.
BOD-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "FINISHED.".
CLOSE INFILE
OUTFILE.
END-PARA-EXIT.
GOBACK.
PROCESS-REC SECTION.
SEARCH ALL WS-PET-DETAILS
AT END DISPLAY "INVALID PRODUCT NUMBER "
IN-PRODUCT-NUM
GOBACK
WHEN WS-TABLE-NUM(PET-IX) = IN-PRODUCT-NUM
MOVE WS-FOOD-DESCRIPTION(PET-IX)
TO OUT-PRODUCT-DESC
MOVE IN-QTY TO OUT-QTY
COMPUTE OUT-PRICE = OUT-QTY *
WS-PRICE(PET-IX)
WRITE OUTREC
END-SEARCH.
PROCESS-REC-EXIT.
EXIT.
READ-FILE SECTION.
READ INFILE
AT END SET END-OF-FILE TO TRUE
END-READ.
READ-FILE-EXIT.
EXIT.

The program triggers the AT END clause when it does not find a match with the SEARCH
ALL (the match must be equal with SEARCH ALL).

There is no need to initialize the index with SEARCH ALL. To move a value to an index,
do not use the MOVE statement; instead, use SET. We shall see this later.

For an unsorted table the ASCENDING clause is not included. as shown below.

01 WS-PETFOOD-REDEF REDEFINES WS-PETFOOD.


03 WS-PET-DETAILS OCCURS 6
INDEXED BY PET-IX.
05 WS-TABLE-NUM PIC 99.
05 WS-FOOD-DESCRIPTION
PIC X(16).
05 WS-PRICE PIC 99V99.

Using the SET verb with SEARCH

Use the SET verb in the following instances:

• To set the index to an initial value


• To modify index values

Información Confidencial | Información Propietaria de Gladius Technology | Página 163 de


176
These examples initialize the index and modify its value.

SET PET-IX TO 1.
SET PET-IX UP by 2.

Use SET with Unsorted SEARCHes

One thing you must do with an unsorted SEARCH is to set the index to an initial value,
or the AT END clause will always occur.

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE98.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM-370.
OBJECT-COMPUTER. IBM-370.
INPUT-OUTPUT SECTION.
SELECT INFILE ASSIGN "INFILE98.DAT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS INFILE-FILE-STATUS.

SELECT OUTFILE ASSIGN "OUTFILE98.DAT"


ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS OUTFILE-FILE-STATUS.
DATA DIVISION.
FILE SECTION.
FD INFILE.
01 INREC.
03 IN-PRODUCT-NUM PIC 99.
03 IN-QTY PIC 99.

FD OUTFILE.
01 OUTREC.
03 OUT-PRODUCT-DESC PIC X(15).
03 OUT-QTY PIC 99.
03 OUT-PRICE PIC 9(4)V99.

WORKING-STORAGE SECTION.
01 OUTFILE-FILE-STATUS PIC X(02).
01 INFILE-FILE-STATUS PIC X(02).
01 WS-EOF PIC 9.
88 END-OF-FILE VALUE 1.
01 WS-PETFOOD.
03 FILLER PIC X(22)
VALUE "01DOG FOOD LARGE 2799".
03 FILLER PIC X(22)
VALUE "02CAT FOOD LARGE 2399".
03 FILLER PIC X(22)
VALUE "03DOG FOOD MEDIUM 1750".
03 FILLER PIC X(22)
VALUE "04CAT FOOD MEDIUM 1650".
03 FILLER PIC X(22)
VALUE "05DOG FOOD SMALL 0999".
03 FILLER PIC X(22)

Información Confidencial | Información Propietaria de Gladius Technology | Página 164 de


176
VALUE "06CAT FOOD SMALL 0899".
01 WS-PETFOOD-REDEF REDEFINES WS-PETFOOD.
03 WS-PET-DETAILS OCCURS 6
ASCENDING KEY IS WS-TABLE-NUM
INDEXED BY PET-IX.
05 WS-TABLE-NUM PIC 99.
05 WS-FOOD-DESCRIPTION
PIC X(16).
05 WS-PRICE PIC 99V99.
01 WS-SUB PIC 9.

PROCEDURE DIVISION.
PROG SECTION.
PERFORM INIT-PARA.
PERFORM BOD-PARA.
PERFORM END-PARA.

INIT-PARA SECTION.
DISPLAY "PROGRAM STARTING".
INITIALIZE OUTFILE-FILE-STATUS
INFILE-FILE-STATUS
WS-EOF
WS-SUB
OPEN INPUT INFILE
IF INFILE-FILE-STATUS NOT = ZERO
DISPLAY "INVALID INFILE98 FILE ="
INFILE-FILE-STATUS
GOBACK
END-IF
OPEN OUTPUT OUTFILE.
IF OUTFILE-FILE-STATUS NOT = ZERO
DISPLAY "INVALID OUTFILE98 FILE ="
OUTFILE-FILE-STATUS
GOBACK
END-IF
PERFORM READ-FILE.
INIT-PARA-EXIT.
EXIT.
BOD-PARA SECTION.
PERFORM UNTIL END-OF-FILE
PERFORM PROCESS-REC
PERFORM READ-FILE
END-PERFORM.
BOD-PARA-EXIT.
EXIT.
END-PARA SECTION.
DISPLAY "FINISHED.".
CLOSE INFILE
OUTFILE.

END-PARA-EXIT.
GOBACK.
PROCESS-REC SECTION.
SET PET-IX TO 1
SEARCH WS-PET-DETAILS
AT END DISPLAY "INVALID PRODUCT NUMBER "
IN-PRODUCT-NUM
GOBACK

Información Confidencial | Información Propietaria de Gladius Technology | Página 165 de


176
WHEN WS-TABLE-NUM(PET-IX) = IN-PRODUCT-NUM
MOVE WS-FOOD-DESCRIPTION(PET-IX)
TO OUT-PRODUCT-DESC
MOVE IN-QTY TO OUT-QTY

COMPUTE OUT-PRICE = OUT-QTY *


WS-PRICE(PET-IX)
WRITE OUTREC
END-SEARCH.
PROCESS-REC-EXIT.
EXIT.
READ-FILE SECTION.
READ INFILE
AT END SET END-OF-FILE TO TRUE
END-READ.
READ-FILE-EXIT.
EXIT.

Use SET to Modify Index Values

Always use the SET verb to modify index values, as shown next.

SET PET-IX TO 1.
SET TABLE-IX UP BY 1.
SET TABLE-IX DOWN BY WS-NUM.

Use SET for Subscripts

For subscripts you would probably write the following code.

MOVE 1 TO WS-SUB.
ADD 1 TO TABLE-SUB.
SUBTRACT WS-NUM FROM TABLE-SUB.

However, you could use SET with subscripts in the same way.

9.6. Multi-dimensional Tables


You can have tables within tables, thus creating a multi-dimensional table. Multi-
dimensional tables would have multiple OCCURS fields. OCCURS fields might contain
fields that might themselves occur, and so on. The following example shows tables
within tables.

01 WS-SALES-DATA.
03 WS-REGION OCCURS 10.
05 WS-REGION-NAME PIC X(20).
05 WS-SALESPERSON OCCURS 20.
07 WS-PERSONS-NAME PIC X(20).
07 WS-PERSONS-SALES PIC 9(5)V99
OCCURS 52.

Información Confidencial | Información Propietaria de Gladius Technology | Página 166 de


176
This provides information on ten regions, each with twenty salespeople and each of
them having 52 sets of sales results.

Everything can be held under one 01 level. Referencing data items in this sort of table
is not difficult: WS-SALESPERSON will need two subscripts or indexes, as shown next.
The highest level index appears first. Use commas to make the text clearer.

WS-SALESPERSON(4 6)
WS-SALESPERSON(4, 6) [Using commas]
WS-SALESPERSON (4 6) would refer to the 6th person in the fourth
region. WS-PERSONS-SALES will need three subscripts or indexes,
as shown next.
WS-PERSONS-SALES(19 14 1)

This would define the first set of sales figures for the 14th person in region 19.

In both the above examples, numeric literals (numbers) were used to reference the
items. These can be replaced with, or mixed with, data items, as shown in the next
example.

WS-PERSONS-SALES(WS-REGN-SUB, WS-PERS-SUB 12)

9.7. Variable Length Tables or Fields


The OCCURS clause can be used to define a variable length table or field. Create a
variable length table by using the DEPENDING ON clause in the OCCURS clause. The
number of items in the table depends on a data item, which is used in the DEPENDING
ON clause. When working with a variable length table, you must also specify the
maximum and minimum number of items in the table in the OCCURS clause. The
following example illustrates the OCCURS clause defining a variable length field.

01 OUTREC.
03 OUT-NAME PIC X(20).
03 OUT-ADDRESS.
05 OUT-ADDR-LINE PIC X(20) OCCURS 3.
03 OUT-COMMENT-COUNT PIC 999.
03 OUT-COMMENTS.
05 OUT-COMMENT-BYTE PIC X
OCCURS 0 TO 100
DEPENDING ON OUT-COMMENT-COUNT.

Here an output record contains a fixed 83 bytes, with a further field OUT-COMMENTS
that may be up to 100 bytes long or may even be missing completely. This gives us a
variable-length record file.

Before the record is written away, OUT-COMMENTS needs to be filled as appropriate


and the correct number of bytes put in OUT-COMMENT-COUNT. Using the POINTER

Información Confidencial | Información Propietaria de Gladius Technology | Página 167 de


176
clause on STRING could do this. If, say, 30 bytes are written to the field, the value of 30
should be inserted in OUT-COMMENT-COUNT.

If the program OPENs a variable-length record file for INPUT, the program reserves the
maximum possible space in the record buffer, since there is no way of knowing in
advance how big the variable portion will be.

The following example shows a variable length table.

01 CUSTOMER-RECORD.
03 CUSTOMER-NO PIC 9(6).
03 CUSTOMER-BALANCE PIC S9(8)V99.
03 CUSTOMER-INVOICE-CNT
PIC 999.
03 CUSTOMER-INVOICE OCCURS 1 TO 500
DEPENDING ON CUSTOMER-INVOICE-CNT.
05 INVOICE-NO PIC 9(6).
05 INVOICE-DATE PIC 9(8).
05 INVOICE-AMT PIC 9(6)V99.

This gives a record where space is allocated only as it is needed.

The program that produces a new customer invoice would use code similar to the
following. The program increments the current value of CUSTOMER-INVOICE-CNT,
which becomes the subscript for the next invoice.

PERFORM CALCULATE-INVOICE-AMT.
PERFORM CALCULATE-INVOICE-NO.
PERFORM GET-DATE.
ADD 1 TO CUSTOMER-INVOICE-CNT.
MOVE WS-INVOICE-NO
TO INVOICE-NO(CUSTOMER-INVOICE-CNT).
MOVE WS-TODAYS-DATE
TO INVOICE-DATE(CUSTOMER-INVOICE-CNT).
MOVE WS-INVOICE-AMT
TO INVOICE-AMT(CUSTOMER-INVOICE-CNT).

When using the OCCURS DEPENDING clause, the following rules apply.

• The minimum value must not be negative.


• The maximum value must be greater than the minimum.
• The field specified after DEPENDING ON must be an elementary numeric field
that must not be in the table itself.

9.8. Using Repeated Data


Let us assume that we are writing a program that reads in a file of records and does the
following:

Información Confidencial | Información Propietaria de Gladius Technology | Página 168 de


176
• The input file may have any number of records (including 0).
• All input records contain a one-character type, a name field (20 characters), an
eight-digit start date, and twelve monthly sales total fields (six digits plus two
decimal places).
• If the type field is set to anything other than "A", "B", "C", "E", "J" or "T", then
reject the record. Similarly if the name field is blank, reject the record in the
same way. Store the details of these rejected records and display them at the
end of the program.
• If the record is valid, total all twelve sales fields together and write them out to
an output record. That record should have the first three fields copied
unchanged from the input record, the fourth field being the total just
calculated.
• Keep record counts of valid types "A" and "C'" (one count), valid "B", "E" and "T"
(another count), and valid "J" (a third count). These counts display at the end of
the program.

The program code looks like this.

IDENTIFICATION DIVISION.
PROGRAM-ID. EXAMPLE99.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
SELECT INFILE ASSIGN "INFILE99.DAT"
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS INFILE-FILE-STATUS.

SELECT OUTFILE ASSIGN "OUTFILE99.DAT"


ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS OUTFILE-FILE-STATUS.
DATA DIVISION.
FILE SECTION.
FD INFILE .
01 INREC .
03 IN-TYPE PIC X .
88 VALID-TYPE VALUE "A" "B" "C" "E" "J" "T" .
88 A-C VALUE "A" "C" .
88 B-E-T VALUE "B" "E" "T" .
88 J VALUE "J" .
03 IN-NAME PIC X(20) .
03 IN-START-DATE PIC 9(8) .
03 IN-SALES-DETS .
05 IN-SALES PIC 9(6)V99 OCCURS 12 .
FD OUTFILE .
01 OUTREC .
03 OUT-TYPE PIC X .
03 OUT-NAME PIC X(20) .
03 OUT-START-DATE PIC 9(8) .
03 OUT-SALES PIC 9(8)V99 .

Información Confidencial | Información Propietaria de Gladius Technology | Página 169 de


176
WORKING-STORAGE SECTION.
01 OUTFILE-FILE-STATUS PIC X(02).
01 INFILE-FILE-STATUS PIC X(02).
01 WS-EOF PIC 9.
88 NO-MORE-RECORDS VALUE 1.
01 WS-VALID-COUNTS.
03 WS-A-C-COUNT PIC 9(4) .
03 WS-B-E-T-COUNT PIC 9(4) .
03 WS-J-COUNT PIC 9(4) .
01 WS-SALES-SUB PIC 99 .
01 WS-INVALID-COUNT PIC 9(3).
01 WS-INVALID-SUB PIC 9(3).
01 WS-INVALID-RECS.
03 WS-INVALID-DETS PIC X(125) OCCURS 100 .

PROCEDURE DIVISION.
PROG SECTION.
PERFORM INIT-PARA.
PERFORM BOD-PARA.
PERFORM END-PARA.

INIT-PARA SECTION.
DISPLAY "TABLE HANDLING PROGRAM STARTING" .
INITIALIZE OUTFILE-FILE-STATUS
INFILE-FILE-STATUS
WS-EOF
WS-VALID-COUNTS
WS-SALES-SUB
WS-INVALID-COUNT
WS-INVALID-SUB
WS-INVALID-RECS.
OPEN INPUT INFILE
IF INFILE-FILE-STATUS NOT = ZERO THEN
DISPLAY "INVALID INFILE99 FILE = "
INFILE-FILE-STATUS
GOBACK
END-IF
OPEN OUTPUT OUTFILE.
IF OUTFILE-FILE-STATUS NOT = ZERO THEN
DISPLAY "INVALID INFILE99 FILE = "
OUTFILE-FILE-STATUS
GOBACK
END-IF
PERFORM READ-FILE.
INIT-PARA-EXIT.
EXIT.
BOD-PARA SECTION.
PERFORM UNTIL NO-MORE-RECORDS
PERFORM PROCESS-REC
PERFORM READ-FILE
END-PERFORM.
BOD-PARA-EXIT.
EXIT.
END-PARA SECTION.
CLOSE INFILE
OUTFILE .

Información Confidencial | Información Propietaria de Gladius Technology | Página 170 de


176
DISPLAY "END OF PROGRAM" .
DISPLAY "NUMBER OF VALID A/C RECORDS "
WS-A-C-COUNT .
DISPLAY "NUMBER OF VALID B/E/T RECORDS "
WS-B-E-T-COUNT .
DISPLAY "NUMBER OF VALID J RECORDS "
WS-J-COUNT .
IF WS-INVALID-SUB > 0
PERFORM DISPLAY-INVALID-RECORDS
END-IF.
END-PARA-EXIT.
GOBACK.

PROCESS-REC SECTION.
IF VALID-TYPE AND IN-NAME UNEQUAL SPACES THEN
PERFORM VALID-RECORD
ELSE
PERFORM INVALID-RECORD
END-IF.
RECORD-BOD-EXIT.
EXIT.
VALID-RECORD SECTION.
EVALUATE TRUE
WHEN A-C
ADD 1 TO WS-A-C-COUNT
WHEN B-E-T
ADD 1 TO WS-B-E-T-COUNT
WHEN J
ADD 1 TO WS-J-COUNT
WHEN OTHER
CONTINUE
END-EVALUATE
MOVE IN-TYPE TO OUT-TYPE .
MOVE IN-NAME TO OUT-NAME .
MOVE IN-START-DATE TO OUT-START-DATE .
MOVE 0 TO OUT-SALES

PERFORM VARYING WS-SALES-SUB


FROM 1 BY 1 UNTIL WS-SALES-SUB > 12
ADD IN-SALES(WS-SALES-SUB) TO OUT-SALES
END-PERFORM
WRITE OUTREC .
VALID-RECORD-EXIT.
EXIT.
INVALID-RECORD SECTION.
ADD 1 TO WS-INVALID-SUB .
IF WS-INVALID-SUB > 100 THEN
DISPLAY "MORE THAN 100 INVALID RECORDS"
DISPLAY "PROGRAM TERMINATING"
GOBACK
END-IF
MOVE INREC TO WS-INVALID-DETS(WS-INVALID-SUB) .
INVALID-RECORD-EXIT.
EXIT.
DISPLAY-INVALID-RECORDS SECTION.
MOVE WS-INVALID-SUB TO WS-INVALID-COUNT .
DISPLAY "NUMBER OF INVALID RECORDS FOUND: "
WS-INVALID-SUB .

Información Confidencial | Información Propietaria de Gladius Technology | Página 171 de


176
DISPLAY "DETAILS:" .
PERFORM VARYING WS-INVALID-SUB FROM 1 BY 1
UNTIL WS-INVALID-SUB > WS-INVALID-COUNT
DISPLAY WS-INVALID-DETS(WS-INVALID-SUB)
END-PERFORM .
DISPLAY-INVALID-RECORDS-EXIT.
EXIT.
READ-FILE SECTION.
READ INFILE
AT END SET NO-MORE-RECORDS TO TRUE
END-READ.
READ-FILE-EXIT.
EXIT.

This previous program illustrates two uses of tables:

• Firstly, the input records contain twelve occurrences of IN-SALES, which are
totalled up into OUT-SALES using a PERFORM with a subscript – a subscript
loop. (The output field is used as a total. An alternative would have been to use
a working-storage field and move it.)
• The second use is the storing of invalid records. The specification decrees that
any such records should display at the end of the program, rather than when
they are encountered. The solution is to have an OCCURS 100, which will hold
that many invalid records. As the program finds an invalid record, the program
increments a subscript incremented and stores the record details. At the end of
the program the subscript is checked, and if non-zero, the records display. The
subscript value is passed to another count, so that a PERFORM VARYING loop
can be used from 1, until the correct number of records is processed.

The danger inherent in storing records in this way is that more may appear than
anticipated. If the subscript goes above 100, the program terminates. Another
approach would be to ignore every invalid record above the limit that can be stored
and set a flag showing that this has been done. At program end the first 100 records
could display along with a message indicating that only these records were processed.

9.9. Summary
In this module we have examined the following topics:

• The need for representation of repeating data in COBOL.


• The use of subscripts and indexes to manipulate tables of such data.
• Using PERFORM with repeating data.
• The different forms of the SEARCH verb to access a table.

Información Confidencial | Información Propietaria de Gladius Technology | Página 172 de


176
9.10. Exercise: Using Tables
Introduction

The purpose of this program is to read the Sales Master file and for all valid records,
total all twelve sales fields together and store them in a table.

Records that have determined not to be valid should be displayed.

At the end of the program display all valid records (in the order in which they were
found).

Details

The program created by this exercise can use the program created in previous exercise
as a starting point.

1. Start your editor.

2. Open PROGRAM91 located in x:\CLASS\MODULE9\NETX.

3. Please design and code a COBOL program to do the following:

• Read in a file of records and display them.


• All input records contain a one-character type, a name field (20 characters), an eight-digit start
date, and twelve monthly sales total fields (six digits, two decimal places).
• If the type field is set to anything other than "A", "B", "C", "E", "J" or "T", then reject and display
the record immediately. The details should be stored. Similarly if the name field is blank, reject
and display the record in the same way.
• If the record is valid, total all twelve sales fields together and store them in a table entry. That
table entry should have the first three fields copied unchanged from the input record. The
fourth field is the total just calculated. At the end of the program display all valid records (in the
order in which they were found).

4. Save the program in the X:\CLASS\NETMODULE9\NETX directory and provide the program name

PROGRAM91.CBL.

5. Run and test the program.

Output from the RUN is

Información Confidencial | Información Propietaria de Gladius Technology | Página 173 de


176
PROGRAM 9.1 TABLE HANDLING PROGRAM STARTING
THE FOLLOWING RECORD IS INVALID:
VVIV LAFRANCE
0000000000000000002457450007000076788000000700000675777007007700
0000000007700000000000000000000000000000
THE FOLLOWING RECORD IS INVALID:
A
2000110200007598000000150004354300000360475532140000055035544300
0005300056875000040068800011100000876570
THE FOLLOWING RECORD IS INVALID:
H
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000
END OF PROGRAM
NUMBER OF VALID A/C RECORDS 0004
NUMBER OF VALID B/E/T RECORDS 0004
NUMBER OF VALID J RECORDS 0002
NUMBER OF VALID RECORDS FOUND: 0010
DETAILS:
ATIM PANNIST 200011020077574900
BSUNNY D LIGHT 199808310050841300
AMARK TYME 198704090230400702
JANNA DAPTER 199912310170191531
CLOU ROWLES 198401010352292600
ACERISE ROWBE 199006100261539430
TMIKE ROWBE 198510060246164817
ESALLY ARMY 200202220287722705
JMILLIE TANT 199809120183174900
EMORGAN HORSE 200108060022584900

Información Confidencial | Información Propietaria de Gladius Technology | Página 174 de


176

You might also like