8 File Storage

Direct Word Access

Direct word access allows you to begin printing or reading data at any given word within a specified record of a data file. This enables you to define subrecords within each logical record.

The Direct-Word PRINT# Statement

PRINT# file number ,record number ,word pointer [;data list[,END] ]

The direct-word PRINT# statement stores data items in specific records of a file. The data is written to the specific file number and record number, starting at the word addressed by word pointer. The word pointer can be an integer expression in the range 1 through (bytes-per-record/2)+1. If the word pointer is exactly one greater than the highest word in the record, that word pointer will address the first word of the next record.

Example: If there are 256 bytes per record, and the word pointer is 129, the following would be equivalent:

  PRINT #1,1,129
  PRINT #1,2,1
The optional END parameter places an EOF after the last data item printed. When END is not used, the remainder of the record is left unchanged. Remember that ON END# and TYP can be used to detect EOFs, as explained later in this chapter.

Listed below is an example program which opens a 1,000-record file named STOCK. Each record can contain 256 bytes of data about each part to be stocked. For now the program enters only four items--part number, description, unit cost, and current quantity on hand.

10   !
20   !       OPEN NEW STOCK FILE
30   !
40   CREATE "STOCK",1000
50   DIM Part$[20],Desc$[20]
60   ASSIGN #1 TO "STOCK"
70   INPUT "TODAY'S DATE:";Date$
80   PRINT LIN(5),SPA(30),"PARTS SET UP FOR",Date$
90   PRINT "PART NO.     DESCRIPTION",TAB(40),"UNIT COST QTY. ON HAND",LIN(2)
100  FOR Record=1 TO 1000
110    INPUT "PART NUMBER?";Part$[1,20]
120    IF UPC$(Part$[1,4])="DONE" THEN 220
130    INPUT "DESCRIPTION?";Desc$[1,20]
140    INPUT "UNIT COST?";Cost
150    INPUT "INITIAL QUANTITY?";Qty
160    PRINT #1,Record,29;Qty
170    PRINT #1,Record,13;Desc$
180    PRINT #1,Record,25;Cost
190    PRINT #1,Record,1;Part$
200    PRINT Part$,Desc$;TAB(35);Cost,Qty
210  NEXT Record
220  PRINT "DONE",LIN(5)
230  END
Lines 80 and 90 print headings for a table of input data. The FOR-NEXT loop inputs four items to be printed in each record, prints each item into subrecord within the currently-specified record, and outputs the data on the standard printer. Line 120 exits the loop when the operator enters DONE (upper or lower case) for a part number.

Notice that the word pointer parameter within each PRINT# specifies the first word for each subrecord.

These four items use only 64 bytes of each defined record; there are still 192 bytes available in each record for extra data.

It is important to know the exact length of each string variable printed using direct-word PRINT#. For example, lines 110 and 130 in the last program generate 20-character strings, regardless of the number of characters input. This, in turn, ensures that 20-character (20 byte) subrecords will be printed in lines 170 and 190. If the subscripts were not used in the INPUT statements, the first two subrecords printed in each logical record would vary in size, depending on the current string length.

The Direct-Word READ# Statement

READ# file number ,record number ,word pointer [;data list]

The direct-word READ# statement reads numbers and strings into variables from a specified record, starting from a specified word.

As with serial and direct READ# statements, the variables into which you read data items do not need to have the same names from which you printed the data items on the record, but they must be the same type and the same order as the originals. When the data list is not used, the direct-word READ# resets the record pointer and word pointer to the specified record and word.

The previous example program opened a file to hold information on parts to be stored. The next program opens a file named ORDRPT (for order-point) and then searches the file STOCK for any item with a current quantity less than 10 (lines 120 through 150). When such an item is found, lines 160 through 180 read the part number, print the part number and quantity in file ORDRPT, and output the same data on the standard printer:


10   !
20   !         PRINT ORDER-POINT REPORT
30   !
40   CREATE "ORDRPT",1000
50   DIM Part$[20],Desc$[20]
60   ASSIGN #1 TO "STOCK"
70   ASSIGN #2 TO "ORDRPT"
80   INPUT "TODAY'S DATE:";Date$
90   PRINTER IS 0
100  PRINT LIN(5),SPA(20),"PARTS TO REORDER ON ",Date$
110  PRINT "PART NO.  DESCRIPTION   QTY. ON HAND",LIN(2)
120  FOR Part=1 TO 1000
130    READ #1,Part,29;Qty
140    IF Qty>=10 THEN Stokok
150    ! 10 or more items so no re-ordering needed.
160 Rd:READ #1,Part,1;Part$,Desc$
170    PRINT #2;Part$,Qty
180    PRINT Part$,Desc$,Qty
190  Stokok:!
200  NEXT Part
210  PRINT "DONE",LIN(5)
220  END
Notice that logical READ# (lines 130 and 160) enables you to read only the items required from a record, thus saving memory space and program execution time. Data is printed into file ORDRPT serially, since it need not be accessed separately.

As another example of direct-word access, the next program can be used to update the cost and quantity data for each record of file STOCK used in the previous programs. As in the first program, this program exits the input loop when the operator inputs "DONE" for a part number.

After the operator enters each set of data, the subroutine Search looks for the appropriate record in the file. After the record is found, lines 160 and 180 print the new cost and total quantity into that record. Line 190 then outputs the new data on the standard printer.

10    !
20    !   UPDATE STOCK FILE
30    !
40    DIM Part$[20], Desc$[20], Stock$[20]
50    ASSIGN #1 TO "STOCK"
60    INPUT "Today's Date: "; Date$
70    PRINTER IS 0
80    PRINT LIN(5), SPA(15); "Parts Received On "; Date$
90    PRINT "PART NO.      COST      QTY. RECEIVED      QTY. ON HAND", LIN(1)
100  FOR Part=1 TO 1000
110 In:INPUT "PART NUMBER:";Part$[1,20]
120     IF UPC$(Part$[1,4])="DONE" THEN Done
130     INPUT "QUANTITY RECEIVED:"; Qty1
140     INPUT "UNIT COST:"; Cost1
150     GOTO Search
160  Pr:PRINT #1, Record, 25; Cost1
170     READ #1, Record, 29; Qty
180     PRINT #1,Part,29; Qty+Qty1
190     PRINT Part$, Cost1, Qty, Qty+Qty1
200   NEXT Part
210  Done: PRINT "DONE", LIN(5)
220        STOP
230  Search:  ! Search for record to update
240   FOR Record=1 TO 1000
250     READ #1, Record,1;Stock$
260     IF Stock$=Part$ then Pr
270   NEXT Record
280   PRINT "!!PART NOT ON FILE!!"
290   WAIT 2000
300   GOTO In
310   END

Eloquence Language Manual - 19 DEC 2002