Many people have emailed-in saying that they were eager to know how to read back the lottery numbers that were being saved to file after generation. This is an important subject, as once you've mastered writing to, and reading from, OPL databases you'll be set to write all sorts of programs that require information to be saved.
You'll remember that each set of up 8 numbers has been faithfully saved
to file archive$ within the generate: procedure. Essentially MiLo just opens the
file, appends a row of new numbers, and then closes it again. By a similar
procedure (opening, reading a row at a time, and closing) we should be
able to get all the information back.
The first thing we need to do is to add an entry on the MiLo menu to
provide a way for the user to call the new function. Locate the section
starting mINIT and add an extra menu option to the first mCARD:
mCARD "Milo","Generate numbers",%g,"List previous",%l,"Exit",%x
Also, a few lines down, add a new entry to the list of tested values for
j%:
ELSEIF j%=%l
listprev:
Now for the new listprev: procedure itself. Go to the bottom of
the source code and enter the following:
PROC listprev:
REM To read back values from the archive file
IF EXIST(archive$)=0
gIPRINT "No previous numbers to list!"
ELSE
CLS
OPEN archive$,A,num1%,num2%,num3%,num4%,num5%,num6%,num7%,num8%
WHILE NOT EOF
PRINT A.num1%,A.num2%,A.num3%,A.num4%,A.num5%,A.num6%,A.num7%,A.num8%
NEXT
ENDWH
CLOSE
ENDIF
RETURN
ENDP
So what have we just typed in? The IF...ELSE...ENDIF structure is
obvious. If the archive file doesn't exist, flash up an error message and
return to the main code. If it does exist, open it and do the reading back of
the stored numbers.
The WHILE NOT EOF line is worth looking at in more detail. You'll have
gathered from previous sessions that the expression following the WHILE
command is a condition that gets evaluated each time the program runs round the
loop. Normally the condition is something obvious like i%<15 or j%=0 or
similar. The result of any condition is either 'true' (numeric value -1) or
'false' (numeric value 0) and I've simply used a useful technique here of
inserting one of OPL's file handling commands directly. The EOF command
returns 'true' if the currently open file has its internal pointer set to the
end-of-file and 'false' if the pointer is somewhere else within the file.
So every time through the loop, we use NEXT to advance the pointer to
the next record (row) of numbers. EOF is false at each point, meaning that NOT
EOF is 'true', so the WHILE loop carries on happily. Eventually the
last record has been read and printed. At that point the NEXT command
advances the pointer one last time onto the very end of the file. OPL takes us
back up to the start of the loop and the NOT EOF condition is evaluated.
EOF of course is true now and so NOT EOF is false and the condition
fails for the first time, dropping out of the loop.
Translate the program and try the new menu option.
The output's not terribly pretty, but we'll sort that out in
due course.
So you've learnt the basic principles of creating a data
file, writing to it, reading back from it, closing it again and handling
conditions like end-of-file. OPL can have up to 4 databases open at any one
time, using the 'handles' A,B,C and D. For example, a business application
might have one file open for customer details, one for purchase orders, one for
invoice details and one for program settings/preferences. Bear in mind also
that all four databases wouldn't typically be open all the time, meaning that
handles can be (re)assigned and used as required and that your program can use
as many databases as you require. Just make sure that you CLOSE every file that
you OPEN and that you don't get confused and try using a handle for two
databases at the same time! 8-)
Next week we'll make a friendly browser dialog to present the stored numbers in a more palatable fashion. See you then!
Go to next lesson | Programming index