9. More Modifications
Let’s return to our very first program and consider what happens if we have over a hundred accounts on the file. If we run the program the report will have heading lines, followed by detail lines. It will fill up one page and then print the next one without any header lines. What we want to do is change the program so that there will be a title on each page, subheadings as before, page numbers and today’s date. Note the program name has been changed. To do this the complete program follows.
program-name: acctlist
define main-heading structure
print-month character(2)
field character value “/”
print-day character(2)
field character value “/”
print-year character(48)
field character(68) value “Account number report”
field character(5) value “Page”
page-number integer(3)
define sub-heading structure
field character(54) value “account # last name first name mi street ”
field character(68) value “address city state zip balance”
define print-line structure
print-account integer(9)
field character(4) value spaces
print-last-name character(22)
print-first-name character(19)
print-middle-initial character(5)
print-street-address character(29)
print-city character(19)
print-state character(6)
print-zip-code integer(5)
field character(2) value space
print-balance, mask($$$$,$$9.99-)
define file acctfile record account-record status acct-status key account-number structure
account-number integer(9)
last-name character(18)
first-name character(15)
middle-initial character
street-address character(25)
city character(15)
state character(2)
zip-code integer(5)
balance signed decimal(6.2)
define work-date character(8)
define record-counter integer(5) value 0
define page-counter integer(3) value 0
define line-counter integer(2) value 54
define error-msg character(60) value spaces
work-date = date
print-month = work-date(5:2)
print-day = work-date(7:2)
print-year = work-date(3:2)
account-number = 9
read-file: readnext acctfile
record-counter = record-counter + 1
if acct-status = 0
print-account-number = account-number
print-last-name = last-name
print-first-name = first-name
print-middle-initial = middle-initial
print-street-address = street-address
print-city = city
print-state = state
print-zip-code = zip-code
print-balance = balance
line-counter = line-counter + 1
if line-counter > 54
perform print-headings
end-if
print print-line
go to read-file
else
if acct-status not = 9
error-msg = “There was a problem with the account file”
end-if
end-if
go to end-program
print-headings: page-counter = page-counter + 1
page-number = page-counter
line-counter = 5
print page main-heading
print skip(2) sub-heading
print skip
end-program: record-counter = record-counter - 1
print skip(2) ‘the number of records read was ’ record-counter
print skip error-msg
end
You will note that we have a few more structures, one each for the main title, subheading and the print detail line. Most of this should be familiar and you can take for granted that I have all the spacing correct. For the main title line we’ll print the date in mm/dd/yy format at the leftmost portion of the line and the page number will be found at the rightmost portion of the same line, preceded by the literal, Page. The variable
main-heading
is set up to give us all we need. The first new keyword you see is
field,
which appears to be a variable. It is used mostly for literals or to separate one field from another. The first occurrence of it is
field character value “/”
and this is one position which is in the third column of the line which will always have a value of /. It is the separator between the month and day and the day and year in our date. It occurs twice because we need it twice. We’ve seen the keyword
value
before. It’s used to tell us that this one character field has a specific value. There will be other uses of the
value
keyword, for literals or constants – fields that don’t change. Though
field
is a keyword, we cannot refer to it in our program. For example, we couldn’t change its value. A few lines down you’ll see
field character(4) value spaces.
We could have written the statement as
field character(4) value “ ”,
which we used before. Each of the two statements, as well as
field character(4) value space
achieves the same result – even though one may not be grammatically incorrect. They represent spaces, a space, nothing, a single blank and blanks.
You will note that
field
occurs a few times in the program and just about each value is different. It represents either a certain amount of spaces for separation or a specific literal and is part of a structure, which enables us to use it. If we need to assign it a value that can change, we have to make it a variable and then we could reference it. Using
field1
or
field2
would do the job, although it would be better to give these fields more meaningful names.
So the beginning of the main title line is a two-character field that is
print-month,
but as you can tell it has no value. We’ll give it one in the program and do the same for
print-day
and
print-year,
all based on the current date. If you move down to the line
work-date = date
you will see how this will be accomplished. This line has another keyword
date
which represents today’s date in the format yyyymmdd. Thus if today is September 10, 2001, the field
date
will have the value
20010910.
Note that not only do we not have to define this variable, we actually couldn’t if we tried. What this statement does is assign the variable
work-date,
which we have defined as
character(8)
the value of the field
date.
This is done by the equal sign, which takes whatever is on the right side (today’s date in this case) and moves it to the field on the left side. Note that when this move is done, both fields will have a value of
20010910.
It’s more like a copy than a move. You have seen the equal sign before but there it was used as a logical operator in conjunction with the
if.
In this line and a few others in the program, this symbol is used as an assignment operator as it gives a field a value. We have another assignment in the line
print-month = work-date(5:2)
which moves the two characters in work-date starting in the fifth position to
print-month.
This is
09,
which happens to be the month. You can then see that
work-date(7:2)
turns out to be the two characters in
work-date
starting in position 7, which are
10,
which is the day. The statement after that takes two characters starting at position 3 or
01,
which is the last two digits of the year. So the four statements of our program after the last define statement get today’s date and format the date on the main heading line as
09/10/01.
Tomorrow it will be
09/11/01,
a day that will live in infamy – although I didn’t know it when I wrote this book or did the first revision on it.
The statements
account-number = 9
read-file: readnext acctfile
we’ve seen before. A sequential read of the file is being done, starting with the first record and subsequent reads until the end of the file is reached. You may ask if we could begin at the last record and read the entire file backwards with the first record on the file being the last record read. Think about it and I’ll provide the answer at the end of chapter 23.
The verb above is for sequential reads, while
read
is used for indexed reads. For reading sequentially, the status is 0 for good reads and 9 for end of file being reached. Anything else is a serious file error. For indexed reads, 0 status is a good read, 5 means the record wasn’t on the file anything else means deep trouble.
The next unfamiliar keyword is in the statement
perform print-headings.
It enables the printing of the headings, resulting in going to the label
print-headings,
where each statement is executed until another label is found. The keyword
perform
is different from a
go to
statement in that control will be returned to the line in the program after the
perform<