home *** CD-ROM | disk | FTP | other *** search
-
-
-
- Data file handling
-
- You can use OPL to create data files (databases) like
- those used by the Database. You can store any kind of information
- in a data file, and retrieve it for display, editing or calculations.
-
- This chapter covers:
-
- Creating data files
-
- Adding and editing records
-
- Searching records
-
- Using a data file both in OPL and in the Database
-
-
-
-
- ****** Files, records and fields
-
- Data files (or databases)
- (picture)
-
- are made up of records
-
-
- (picture)
-
- For example, in a data file of names and addresses, each record might
- have a name field, a telephone number field, and separate fields for
- each line of the address.
-
- In OPL you can:
-
- *) Create a new file with CREATE, or open an
- existing file with OPEN, and copy, delete and rename files
- with COPY, DELETE and RENAME.
-
- *) Add a new record with APPEND, change an existing
- one with UPDATE, and remove a record with ERASE.
-
- *) Fill in a field by assigning a value to a field variable.
-
-
-
-
- ****** Creating a data file
-
- Use the CREATE command like this:
-
- CREATE filename$,logical name,field1,field2,...
-
- For example:
-
- CREATE "clients",B,nm$,tel$,ad1$,ad2$,ad3$
-
- creates a data file called "clients".
-
- The file name is a string, so remember to put quote marks around it.
- You can also assign the name string to a string variable (for example
- "fil$="clients"") and then use the variable name as the argument
- "CREATE fil$,A,field1,field2".
-
- *** Logical names
-
- You can have up to 4 data files open at a time. Each of these must
- have a logical name: "A", "B", "C" or "D". The logical
- name lets you refer to this file without having to keep using the
- full file name.
-
- A different logical name must be used for each data file opened
- one called "A", one called "B", one called "C" and one
- called "D". A file does not have to be opened with the same logical
- name as the last time it was opened. When a file is closed, its logical
- name is freed for use by another file.
-
- *** Fields
-
- "field1, field2",... are the field names up to 32 in any
- record. These are like variables, so use "%" "&" or "$"
- to make the appropriate types of fields for your data. You cannot
- use arrays. Do not specify the maximum length of strings that the
- string fields can handle. The length is automatically set at 255 characters.
-
- Field names may be up to 8 characters long, including any qualifier
- like "&".
-
- When referring to fields, add the logical file name to the front of
- the field name, to specify which opened file the fields belong to.
- Separate the two by a dot. For example, "A.name$" is the "name$"
- field of the file with logical name "A", and "C.age%" is the
- "age%" field of the file with logical name "C".
-
- The values of all the fields are 0 or null to start with. You can
- see this if you run this example program:
-
- PROC creatfil:
- CREATE "example",A,int%,long&,float,str$
- PRINT "integer=";a.int%
- PRINT "long=";a.long&
- PRINT "float=";a.float
- PRINT "string=";a.str$
- CLOSE
- GET
- ENDP
-
-
- ****** Opening a file
-
- When you first CREATE a data file it is automatically open,
- but it closes again when the program ends. If
- a file already exists, trying to CREATE it again will give
- an error- so if you ran the procedure "creatfil:" a second
- time you would get an error. To open an existing file, use the OPEN
- command.
-
- OPEN works in the same way as the CREATE command. For
- example:
-
- OPEN "clients",B,a$,b$,c$,d$,e$
-
- *) You must use the same filename as when you first created
- it.
-
- *) You must include in the OPEN command each of the
- fields you intend to alter or read. You can omit fields from the end
- of the list; you cannot miss one out from the middle of the
- list, for example "field1$,,name$" They must remain the same type
- of field, but you can change their names. So a file created with fields
- "name$,age%" could later be opened with the fields "a$,x%".
-
- *) Give the file a logical name. Up to 4 files may be open
- at any one time, with logical names "A", "B", "C" and
- "D". You can't have two files open simultaneously with the same
- logical name, so when opening the files, remember which logical names
- you have already used.
-
- You might make a new module, and type these two procedures into
- it:
-
- PROC openfile:
- IF NOT EXIST("example")
- CREATE "example",A,int%,lng&,fp,str$
- ELSE
- OPEN "example",A,int%,lng&,fp,str$
- ENDIF
- PRINT "Current values:"
- show:
- PRINT "Assigning values"
- A.int%=1
- A.lng&=&2**20 REM the 1st & avoids integer overflow
- A.fp=SIN(PI/6)
- PRINT "Give a value for the string:"
- INPUT A.str$
- PRINT "New values:"
- show:
- ENDP
-
-
- PROC show:
- PRINT "integer=";A.int%
- PRINT "long=";A.lng&
- PRINT "float=";A.fp
- PRINT "string=";A.str$
- GET
- ENDP
-
- *** Notes
-
- Opening/creating the file
- The IF...ENDIF checks to see if the file already exists, using
- the EXIST function. If it does, the file is opened; if it doesn't,
- the file is created.
-
- Giving values to the fields
- The fields can be assigned values just like variables. The field name
- must be used with the logical file name like this: "A.f%=1"
- or "INPUT A.f$".
-
- If you try to give the wrong type of value to a field (for example
- ""Davis"" to "f%") an error message will be displayed.
-
- You can access the fields from other procedures, just like global
- variables. Here the called procedure "show:" displays the values
- of the fields.
-
- Field names
- You must know the type of each field, and you must give each a separate
- name you cannot refer to the fields in any indexed way, eg
- as an array.
-
- Opening a file for sharing
- The OPENR command works in exactly the same way as OPEN,
- except that the file cannot be written to (with UPDATE or APPEND),
- only read. However, more than one running program can then look at
- the file at the same time.
-
-
- ****** Saving records
-
- The last example procedure did not actually save the field values
- as a record to a file. To do this you need to use the APPEND
- command. This program, for example, allows you to add records to the
- "example" data file:
-
- PROC count:
- LOCAL reply%
- OPEN "example",A,f%,f&,f,f$
- DO
- CLS
- AT 20,1 :PRINT "Record count=";COUNT
- AT 9,5 :PRINT "(A)dd a record"
- AT 9,7 :PRINT "(Q)uit"
- reply%=GET
- IF reply%=%q OR reply%=%Q
- BREAK
- ELSEIF reply%=%A OR reply%=%a
- add:
- ELSE
- BEEP 16,250
- ENDIF
- UNTIL 0
- ENDP
-
- PROC add:
- CLS
- PRINT "Enter integer field:";
- INPUT A.f%
- PRINT "Enter long integer field:";
- INPUT A.f&
- PRINT "Enter numeric field:";
- INPUT A.f
- PRINT "Enter string field:";
- INPUT A.f$
- APPEND
- ENDP
-
- BEEP
- The BEEP command makes a beep of varying pitch and length:
-
- BEEP duration%,pitch%
-
- The duration is measured in 1/32 s of a second, so "duration%=32"
- would give a beep a second long. Try "pitch%=50" for a high beep,
- or "500" for a low beep.
-
- *** The number of records
-
- The COUNT function returns the number of records in the file.
- If you use it just after creating a database, it will return 0. As
- you add records the count increases.
-
- *** How the values are saved
-
- Use the APPEND command to save a new record. This has no arguments.
- The values assigned to "A.f%", "A.f&", "A.f" and "A.f$"
- are added as a new record to the end of the "example" data file.
- If you only give values to some of the fields, not all, you won't
- see any error message. If the fields happen to have values, these
- will be used; otherwise null strings ("") will be given to string
- fields, and zero to numeric fields.
-
- New field values are always added to the end of the current data
- file as the last record in the file (if the file is a new
- one, it will also be the first record).
-
- At any time while a data file is open, the field names currently in
- use can be used like any other variable for example, in a
- PRINT statement, or a string or numeric expression.
-
- APPEND and UPDATE
- APPEND adds the current field values to the end of the file
- as a new record, whereas UPDATE deletes the current record
- and adds the current field values to the end of the file as a new
- record.
-
-
- ****** Moving from record to record
-
- When you open or create a file, the first record in the file is current.
- To read, edit, or erase another record, you must make that record
- current that is, move to it. Only one record is current at
- a time. To change the current record, use one of these commands:
-
- POSITION `moves to' a particular record, setting the field
- variables to the values in that record. For example, the instruction
- "POSITION 3" makes record 3 the current record. The first record
- is record 1.
-
- You can find the current record number by using the POS function,
- which returns the number of the current record.
-
- FIRST moves to the first record in a file.
-
- NEXT moves to the following record in a file. If the end of
- the file is passed, NEXT does not report an error, but the
- current record is a new, empty record. This case can be tested for
- with the EOF function.
-
- BACK moves to the previous record in the file. If the current
- record is the first record in the file then that first record stays
- current.
-
- LAST moves to the last record in the file.
-
- *** Deleting a record
-
- ERASE deletes the current record in the current
- file.
-
- The next record is then current. If the erased record was the last
- record in a file, then following this command the current record will
- be empty and EOF will return true.
-
-
- ****** Finding a record
-
- FIND makes current the next record which has a field matching
- your search string. Capitals and lower-case letters match. For example:
-
- r%=FIND("Brown")
-
- would select the first record containing a string field with the value
- "Brown", "brown" or "BROWN", etc. The number of that record is returned,
- in this case to the variable "r%". If the number returned is zero,
- no matching field was found. Any other number means that a match was
- found.
-
- The search includes the current record. So after finding a matching
- record, you need to use NEXT before you can continue searching
- through the following records.
-
- "FIND("Brown")" would not find a field "Mr Brown". To find this,
- use wildcards, as explained below.
-
- You can only search string fields, not number fields. For example,
- if you assigned the value 71 to the field "a%", you could not
- find this with FIND. But if you assigned the value "71" to
- "a$", you could find this.
-
- *** Wildcards
-
- "r%=FIND("*Brown*")" would make current the next record containing
- a string field in which "Brown" occurred for example,
- the fields "MR BROWN", "Brown A.R." and "Browns Plumbing"
- would be matched. The wildcards you can use are:
-
- ? matches any one character
-
- * matches any number of characters.
-
- Once you've found a matching record, you might display it on the screen,
- erase it or edit it. For example, to display all the records containing
- "BROWN":
-
- FIRST
- WHILE FIND("*BROWN*")
- PRINT a.name$, a.phone$
- NEXT
- GET
- ENDWH
-
- *** More controlled finding
-
- FINDFIELD, like FIND, finds a string, makes the record
- with this string the current record, and returns the number of this
- record. However you can also use it to do case-dependent searching,
- to search backwards through the file, to search from the first record
- (forwards) or from the last record (backwards), and to search in one
- or more fields only.
-
- You may experience some problems in using FINDFIELD with some
- versions of OPL. To ensure that problems are avoided use the line:
-
- POKEB(peekw($1c)+7),0
-
- immediately before each call to FINDFIELD.
-
- The first argument to FINDFIELD is the string to look for,
- as for FIND. The second is the number of the field to start
- looking in (1 for the first field), and the third is the number of
- fields to search in (starting from the field specified by the second
- argument). If you want to search in all fields, use 1 as the second
- argument and for the third argument use the number of fields you used
- in the OPEN/CREATE command.
-
- The fourth argument adds together two values:
-
- *) 0 for a case independent match, where capitals and
- lower-case letters match, or 1 for a case dependent match. This
- value should be multiplied by 16.
-
- *) 0 to search backwards from the current record, 1 to search
- forwards from the current record, 2 to search backwards from the end
- of the file, or 3 to search forwards from the start of the file.
-
- For a case independent search (0) forwards from the current record
- (1*16), use 0+(1*16), ie 16. If you wanted to search only in the second
- and third fields, the full statement might look like this: "FINDFIELD("brown",2,2,16)".
-
- If you understand hexadecimal arithmetic, as described
- under HEX$ in the `Alphabetic listing' chapter, note that you
- can combine the two values more easily using hexadecimal numbers.
- Use a "$" symbol, then the digit for the start/direction (0/1/2/3),
- then the digit for case dependency (0/1). In the previous example
- the digits are 1 and 0, producing the hexadecimal number "$10"
- (=16).
-
- If you find a matching record and then want to search again from this
- record, you must first use NEXT or BACK (according to
- the direction you are searching in), otherwise the same match will
- be "found" in the current record again."
-
-
- ****** Changing/closing the current file
-
- Immediately after a file has been created or opened, it is automatically
- current. This means that the APPEND or UPDATE commands
- save records to this file, and the record-position commands (explained
- below) move around this file. You can still use the fields of other
- open files, for example "A.field1=B.field2"
-
- USE makes current one of the other opened files. For example
- "USE B" selects the file with the logical name B (as specified
- in the OPEN or CREATE command which opened it).
-
- If you attempt to USE a file which has not yet been opened
- or created, an error is reported.
-
- In this procedure, the EOF function checks whether you are
- at the end of the current data file that is, whether you've
- gone past the last record. You can use EOF in the test
- condition of a loop UNTIL EOF or WHILE NOT EOF
- in order to carry out a set of actions on all the records in a file.
-
- *** Example copies selected records from one file to another
-
- PROC copyrec:
- OPEN "example",A,f%,f&,f,f$
- TRAP DELETE "temp"
- REM If file doesn't exist, ignore error
- CREATE "temp",B,f%,f&,f,f$
- PRINT "Copying EXAMPLE to TEMP"
- USE A REM the EXAMPLE file
- DO
- IF a.f%>30 and a.f<3.1415
- b.f%=a.f%
- b.f&=a.f&
- b.f=a.f
- b.f$="Selective copy"
- USE B REM the TEMP file
- APPEND
- USE A
- ENDIF
- NEXT
- UNTIL EOF REM until End Of File
- CLOSE REM closes A; B becomes current
- CLOSE REM closes B
- ENDP
-
- This example uses the DELETE command to delete any "temp"
- file whch may exist, before making it afresh. Normally, if there was
- no "temp" file and you tried to delete it, an error would be generated.
- However, this example uses TRAP with the DELETE command.
- TRAP followed by a command means "if an error occurs in the
- command, carry on regardless".
-
- There are more details of TRAP in the chapter on `Error Handling'.
-
- *** Closing a data file
-
- You should always `close' a data file (with the CLOSE command)
- when you have finished using it. Data files close automatically when
- programs end. You can only have 4 files open at a time if
- you have 4 files open and you want to access another one, close one
- of them. CLOSE closes the current file.
-
- *** Keeping data files compressed
-
- When you change or delete records in a data file, the space taken
- by the old information is not automatically recovered. By default,
- the space is recovered when you close the file, provided it
- is on `Internal drive' or on a RAM SSD (ie it is not on a Flash
- SSD).
-
- Closing a very large file which contains changed or deleted records
- can be slow when compression is enabled, as the whole file beyond
- each old record needs copying down, each time.
-
- You can prevent data file compression if you wish, with these
- two lines:
-
- p%=PEEKW($1c)+$1e
- POKEW p%,PEEKW(p%) or 1
-
- (Use any suitable integer variable for "p%".) Files used by the
- current program will now not compress when they close.
-
- Use these two lines to re-enable auto-compression:
-
- p%=PEEKW($1c)+$1e
- POKEW p%,PEEKW(p%) and $fffe
-
- Warning: be careful to enter these lines exactly as shown. These
- examples work by setting a system configuration flag.
-
- If you have closed a file without compression, you can recover
- the space by using the COMPRESS command to create a new, compressed
- version of the file. "COMPRESS "dat" "new"", for example,
- creates a file called "new" which is a compressed version of "dat",
- with the space which was taken up by old information now recovered.
- (You have to use COMPRESS to compress data files which are
- kept on a Flash SSD.)
-
-
- ****** Data files and the Database
-
- The files you use with the Database (listed under the Data icon in
- the System screen) often called databases or database
- files are also just data files.
-
- Data files created by the Database can be viewed in OPL, and vice
- versa.
-
- In OPL: to open a data file made by the Database, begin its
- name with "\DAT\", and end it with ".DBF". For example,
- to open the file called "data" which the Database normally uses:
-
- OPEN "\dat\data.dbf",A,a$,b$,c$,d$...
-
- Restrictions:
-
- *) You can use up to 32 field variables, all strings. It is
- possible for records to contain more than 32 fields, but these fields
- cannot be accessed by OPL. It's safe to change such a record and use
- UPDATE, though, as the extra fields will remain unchanged.
-
- *) The maximum record length in OPL is 1022 characters. You
- will see a `Record too large' error (-43) if your program tries
- to open a file which contains a record longer than this.
-
- *) The Database breaks up long records (over 255 characters)
- when storing them. They would appear as separate records to OPL.
-
- In the Database: to examine an OPL data file, press the Data
- button, select `Open' from the `File' menu, and type the name with
- "\OPD\" on the front and ".ODB" at the end for example:
-
- \opd\example.odb
-
- Restrictions:
-
- *) All of the fields must be string fields.
-
- *) You can have up to a maximum of 32 fields, as specified
- in the CREATE command. If you view an OPL data file with the
- Database, and add more lines to records than the number of fields
- specified in the original CREATE command, you will get an error
- if you subsequently try to access these additional fields in OPL.
-
- In both cases, you are using a more complete file specification.
- There is more about file specifications in the Advanced Topics chapter.
-
-
-
-
-
-