home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
database
/
db3retxt.zip
/
DB3REF11.TXT
Wrap
Text File
|
1989-03-20
|
29KB
|
959 lines
REFERENCE NOTES FOR dBASE III version 1.1
-----------------------------------------
R E F E R E N C E - dBASE III
-----------------------------
@...GET...RANGE
RANGE is used in conjunction with @...GET to specify an
acceptable continuous set of input values to date or numeric
fields. The RANGE is initialized by specifying lower and upper
bounds (inclusive) which may be literal values, memory variables,
or expressions. For example:
1) Literal values:
@ 10,10 GET var1 RANGE 1,9
@ 11,10 GET mdate RANGE CTOD('12/12/84'),CTOD('12/12/85')
2) Memory variables:
STORE 1 TO low
STORE 9 TO high
@ 10,10 GET var1 RANGE low,high
STORE CTOD('12/12/84') TO low_date
STORE CTOD('12/12/85') TO high_date
@ 10,10 GET mdate RANGE low_date,high_date
3) Expressions:
@ 10,10 GET var1 RANGE low+365,high+(365*10)
@ 11,10 GET mdate RANGE DATE(),high_date+120
Entries outside of the defined range will generate an error
message and input will be prompted until a valid entry is made.
@...GET...PICTURE
Assuming a memvar is initialized with zero (that is, memvar = 0),
when the user types a period at an @...GET memvar PICTURE
"9999.99", dBASE will proceed to the next command line. This
will not occur when the memory variable is initialized to two
decimal places (that is, memvar = 0.00). Only the integer
portion of the number just entered will be stored to memvar if
the period is typed.
@...SAY...PICTURE
To display a dollar-sign character ("$") in front of a numeric
value and not have the possibility of a lot of "$"s filling the
blank areas, do the following:
* ---To display a single "$".
STORE 123.56 TO num
@ 10,10 SAY "$"
@ 10,11 SAY num PICTURE "99,999.99"
This will generate:
$ 123.56
* ---The other option available is:
STORE 123.56 TO num
@ 10,10 SAY num PICTURE "$$,$$$.$$"
This will generate:
$$$123.56
@...SAY using relative addressing
We use the '$' function in dBASE II to control relative screen
addressing with the @...SAY function. For example, we can have a
command file print the contents of a datafile to the screen as
follows:
* ---This is dBASE II syntax.
USE <datafile>
DO WHILE .NOT. EOF
*
@ 5, 5 SAY <Field1>
@ $+1,$ SAY <Field2>
@ $+1,$ SAY <Field3>
@ $+1,$ SAY <Field4>
SKIP
*
ENDDO [while .not. eof]
The dBASE III utility, dCONVERT, is used to convert dBASE II
programs, datafiles, etc. to dBASE III formats. dCONVERT does
not change the '$' function to ROW() and COL(); it leaves it
alone. However, this will not cause any problems when executing
the code in dBASE III. dBASE III will treat the '$' function as
a relative addressing function.
APPEND FROM <filename> [SDF/DELIMITED [WITH <delimiter>]]
The DELIMITED form of the APPEND FROM command should be
documented as having a WITH clause. WITH is not mentioned
in the reference section. Below are a few examples:
Example 1. To read a comma delimited file in which the
character strings are enclosed in double quotes:
APPEND FROM <filename> DELIMITED
or
APPEND FROM <filename> DELIMITED WITH "
Example 2. To read a comma delimited file in which the
character strings are enclosed in single quotes:
APPEND FROM <filename> DELIMITED WITH '
Example 3. To read a comma delimited file in which the
character strings are not enclosed at all:
dBASE III CANNOT READ A FILE OF THIS FORMAT!
Also, the syntax of the APPEND command does not include a WHILE
option as the manual indicates. The correct syntax is
APPEND FROM <file name> [FOR <condition>]
[SDF/DELIMITED [WITH <delimiter>]]
--End--
R E F E R E N C E - dBASE III
-----------------------------
COPY TO <filename> [SDF/DELIMITED [WITH <delimiter>]]
(1) COPY TO <filename> DELIMITED does not enclose logical fields
with the specified delimiters. Numeric and date fields are also
treated this way. Date fields go out in the format YYYYMMDD.
(2) COPY TO <filename> DELIMITED WITH , encloses the character
fields in commas and separates the fields with another comma.
This command behaves differently from dBASE II as shown below:
In dBASE II:
. USE file1
. COPY TO file2 DELIMITED WITH ,
will result in:
SANTA,CLAUS,NORTH POLE,ALASKA
In dBASE III:
. USE file1
. COPY TO file2 DELIMITED WITH ,
will result in:
,SANTA,,,CLAUS,,,NORTH POLE,,,ALASKA,
COPY FILE <source filename> TO <target filename>
The COPY FILE command copies files in 512 byte blocks; whereas,
the COPY TO command will copy a .DBF file until the end-of-file.
Therefore, the COPY FILE command will usually create a slightly
larger file than the COPY TO command. However, the COPY FILE is
faster.
COPY STRUCTURE EXTENDED
CREATE FROM
COPY STRUCTURE EXTENDED and CREATE FROM are fully implemented in
dBASE III although not documented. A brief description is given
below.
1) COPY STRUCTURE EXTENDED creates a file in which the field
names become the contents of one record. The syntax for
this COPY option is:
COPY STRUCTURE EXTENDED TO <new file>
2) CREATE FROM forms a new database (.DBF) file in which the
structure is determined by the contents of a file created
with COPY STRUCTURE EXTENDED. The syntax is:
CREATE <new file> FROM <structure extended file>
Date conversion from dBASE II
The dBASE BRIDGE manual (pages 23-24) lays out an elaborate
scheme for converting dBASE II "dates" to dBASE III date fields.
A much easier way is to simply convert the dBASE II database file
to a dBASE III file and modify the structure from character to
date field. All dates stored in a dBASE II character field as
"MM/DD/YY" will directly convert to a dBASE III date field.
Dates that are blank
CTOD() and DTOC() are intended to be inverse functions. That is,
if DTOC(date) = char, then CTOD(char) = date. This is true in
all circumstances except when the date is blank and the character
string is " / / ". To detect a blank date, you must use the
DTOC() function rather than CTOD(). For example:
reg_date = CTOD("11/09/84")
? reg_date = CTOD("11/09/84")
.T.
? DTOC(reg_date) = "11/09/84"
.T.
* ---With a blank date the following occurs:
blank_date = CTOD(" / / ")
? blank_date = CTOD(" / / ")
.F.
? DTOC(blank_date) = " / / "
.T.
As is evident from the example, the blank date is handled
differently than the non-blank date.
DISPLAY and LIST
The DISPLAY and LIST commands are documented in the manual as not
having a FIELDS clause as part of the syntax, while the ASSIST
and HELP menu options assume the FIELDS clause is required.
dBASE III will accept either syntax for these two commands.
FILE() function
The FILE() function only searches the current directory. SET
PATH TO does not affect this function. If other directories are
to be searched, they must be supplied to the function. For
example,
* ---This will not find Data.dbf, if Data.dbf is in the
* ---subdirectory ACCTS.
SET PATH TO \DBASE\ACCTS
IF FILE( "DATA.DBF" )
DO Process
ENDIF
Workaround:
* ---This method will work.
mpath = "\DBASE\ACCTS\"
SET PATH TO &mpath
IF FILE( mpath + "DATA.DBF" )
DO Process
ENDIF
--End--
R E F E R E N C E - dBASE III
-----------------------------
FIND
SEEK
FIND and SEEK are both used to move the record pointer of an
indexed database to the first instance of the index key that
matches the search argument. FIND searches on a literal
character string while SEEK searches on an expression the value
of which may be character, date, or numeric.
The proper choice of command is related to the context and data
type of the index key. Generally, FIND will only be used to
search for a literal character string and SEEK for all other
searches. The following are some typical cases:
(1) You have an index key that is character and are
working from the dot prompt:
. FIND Lee
{or} . SEEK "Lee"
(2) You have an index key that is numeric or date and
are working from the dot prompt:
. SEEK 1250
. SEEK CTOD('12/12/85')
(3) You are working within a command file and are
initializing a memory variable as a search key:
STORE SPACE(10) TO skey
@ 10,10 SAY 'Enter value to search for' GET skey
READ
SEEK skey
(4) You have a database field that is character, Code, and
the contents are numeric digits and right-justified:
ACCEPT 'Enter code to search for' to skey
SEEK SPACE(LEN(Code) - LEN(skey)) + skey
(5) You are working with several databases and want to
search for a key value in the current work area using a
field variable from a non-active area with an alias
name:
SELECT 1
USE File1 INDEX File1
SELECT 2
USE File2 INDEX File2
SELECT File1
SEEK File2->Field1
Function Keys
F1 toggles the cursor control menu on and off in the following
full screen edit modes.
APPEND EDIT MODIFY LABEL MODIFY STRUCTURE
BROWSE CHANGE MODITY REPORT
INPUT
The INPUT command does not initialize a memory variable of any
type if <RETURN> is pressed at its prompt. The dBASE III manual
says this will produce a syntax error (page 4-58). What really
happens is that a syntax error will result if the non-existent
memvar is later referenced.
MEMO fields
(1) MEMO fields are used to contain up to 5,000 characters of
text information that is to be associated with a database record.
Information may be read into a MEMO field using Ctrl-K-R and
written to text files using Ctrl-K-W. Information from MEMO
fields can be displayed or printed by using LIST, DISPLAY, ?.
The field must be specified with these commands. However, these
commands cause the MEMO field to wrap at 50 columns. The REPORT
FORM may be used to output MEMO fields with line widths of more
or less than 50 characters.
(2) PACKing a database file with memo fields will not decrease
the amount of disk space used by the .DBT file. The command file
below demonstrates how to remove the deleted records and free the
unused disk space.
SET DELETED ON
USE Filea
COPY TO Temp
CLOSE DATABASE
ERASE Filea.dbf
ERASE Filea.dbt
RENAME Temp.dbf TO Filea.dbf
RENAME Temp.dbt TO Filea.dbt
SET DELETED OFF
MODIFY STRUCTURE
In MODIFY STRUCTURE, Ctrl-Home will bring up a menu on line 0 with
the four choices listed below.
Bottom Top Field # Menu
They are selected with cursor control keys and <RETURN>.
Bottom moves the cursor to the last field, Top to the first.
Field # allows selection of a field number, then moves the
cursor to it. Menu toggles the cursor control menu off and
on. This feature is not documented under MODIFY STRUCTURE.
MODIFY STRUCTURE
The "Warning" in the documentation on page 4-73 of dBASE III
version 1.00 and WARNING of page 4-80 of dBASE III version 1.10
should read as follows:
WARNING: Although you may change field names and field
lengths, if you change both at once, the data of the
fields that have been modified will not be appended
into the new structure.
Note that in the ASSIST mode, the following screen message is not
entirely true, "Information in the database file is preserved
where field names remain the same." As noted above, if only
field names are changed or only the length, the data is appended
into the new structure. The correct procedure when both field
name(s) and field length(s) need to be changed, is to modify the
field name(s) first, and then re-enter MODIFY STRUCTURE and
modify the field length(s).
Also, note that deleting a field (with Ctrl-U) has the same
effect as modifying the field length. Therefore, make deletions
at the same time you make field length changes.
--End--
R E F E R E N C E - dBASE III
-----------------------------
Numeric fields with decimal places
Although not documented, dBASE III expects the user to allow for
a leading digit and a decimal point on numeric fields containing
decimal places. For example, a numeric field of two decimal
places should not be defined any smaller than four digits in
length--one position for the leading digit, one position for the
decimal point, and two positions for the two decimal places.
If the structure for a numeric field does not allow for a leading
digit (such as, a width of three and two decimal places), numeric
input to the numeric field will always be stored as zero. Also,
if other numeric fields follow this field, they might
automatically be zeroed out when numeric data is entered to the
first field.
Numeric input of large numbers
If a variable is initialized to zero, dBASE III does not allow
input larger than 10 digits when using the @...GET command, even
if the PICTURE clause is used. For example:
x = 0
@ 5,5 SAY "Enter digits" GET x PICTURE "99999999999"
(There are eleven 9's) ----------^
READ
The display is:
Enter digits 0
If an eleven digit value is entered, the display is:
Enter digits ********** (10 asterisks)
This can be avoided by initializing 'x' to a value greater than
ten digits (such as, 1000000000). This problem does not occur if
a field is used rather than a memory variable.
PARAMETERS, passing Fields
(For a manual update, see the TechNotes "Policies" section.)
In the documentation concerning PARAMETERS when used in
conjunction with the DO <filename> [WITH <parameter list>]
command, page 4-76 of the version 1.0 manual states, "A passed
parameter may be any legitimate expression." Also, in the
Glossary (page 7-3) the definition for Expression is, "Expression
may consist of a field, a memory variable, a function, a
constant, or any combination thereof." However, when a DO is
invoked with a field in the parameter list, dBASE III will give
the message, "Variable not found."
In order to use a field name in the parameter list, you must use
the Alias -> Fieldname form. For example:
USE Filea
DO <Filename> WITH Filea -> Field1
will work, but the following will not.
USE Filea
DO <Filename> WITH Field1
--End--
R E F E R E N C E - dBASE III
-----------------------------
PRIVATE
In dBASE III, all variables are PRIVATE to the routine in which
they are initialized unless otherwise declared. Variables
created at the dot prompt will automatically be PUBLIC no matter
how they are declared.
Declaring a variable PRIVATE in a command file hides any outer-
level definition of a variable with the same name from the
current routine. It also hides any deeper-level routines from
viewing any outer-level definition of a variable with the same
name. In the example below, programs B.PRG and C.PRG do not have
access to variable X in program A.PRG. Program C.PRG, therefore,
will display X with a value of 15 and not 10. Program A.PRG,
however, will display X with the old value of 10 even after
executing program B.PRG.
* A.PRG
x = 10
DO B ----------> * B.PRG
? x PRIVATE x
RETURN x = 15
DO C ----------> * C.PRG
RETURN ? x
RETURN
In programming, you will want to declare a variable PRIVATE in a
subroutine if you do not want this variable to interfere with an
outer-level variable having the same name.
To illustrate the use of PRIVATE, the command files MAIN.PRG and
SUB.PRG are listed below, with the displayed output. Notice that
all the variables are released when MAIN.PRG returns control to
the dot prompt. Also notice that the variables initialized in
MAIN.PRG are PRIVATE in the memory display even though they are
never explicitly declared. Lastly, notice that the value
assigned to height in SUB.PRG is not returned to MAIN.PRG, but
the value assigned to area in SUB.PRG is returned. This is
because height is declared PRIVATE in SUB.PRG and area is not.
LISTINGS:
* MAIN.PRG
* --------
area = 0
height = 304
? "Before call to SUB:"
? "-------------------"
DISPLAY MEMORY
DO Sub ------------------> * SUB.PRG
? "After call to SUB:" * -------
? "------------------" PRIVATE height
DISPLAY MEMORY height = 30
RETURN area = 10 * 20 * height
* EOF: MAIN.PRG ? "Inside SUB:"
? "-----------"
DISPLAY MEMORY
RETURN
* EOF: SUB.PRG
OUTPUT:
Before call to SUB:
-------------------
AREA priv N 0 ( 0.00000000)
HEIGHT priv N 304 ( 304.00000000)
2 variables defined, 18 bytes used
254 variables available, 5982 bytes available
Inside SUB:
-----------
AREA priv N 6000 ( 6000.00000000)
HEIGHT priv (hidden) N 304 ( 304.00000000)
HEIGHT priv N 30 ( 30.00000000)
3 variables defined, 27 bytes used
253 variables available, 5973 bytes available
After call to SUB:
------------------
AREA priv N 6000 ( 6000.00000000)
HEIGHT priv N 304 ( 304.00000000)
2 variables defined, 18 bytes used
254 variables available, 5982 bytes available
When DISPLAY MEMORY is entered from the dot prompt the following
two lines will display:
0 variables defined, 0 bytes used
256 variables available, 6000 bytes available
>>> PROCEDURE
Calling Command Files from Procedures within dBASE III
------------------------------------------------------
To call a command file from a procedure, you must follow a few
rules.
Rule 1:
The command file cannot have the same name as any of the
procedures in the file even if the extension is included as part
of the filename. An attempt to do this will cause the
inappropriate error message, "Unrecognized phrase/keyword in
command." For example:
* Proc_One.PRG
PROCEDURE One
* ---The next command will not work because
* ---Two is a procedure in this file.
DO Two.PRG
RETURN
*
PROCEDURE Two
* ---The next command will work.
DO Three.PRG
RETURN
* EOF: Proc_One.PRG
This can be avoided by renaming either the command file or
procedure. To avoid this problem you might want to begin
procedure names with a prefix that command files will not have.
For instance, in the previous example the procedures could have
been called P_One and P_Two.
Rule 2:
Once the command file is invoked from a procedure file, it must
not DO another procedure in the procedure file. Instead, it
should RETURN to the calling procedure. Otherwise, the called
procedure will usually execute, but an error message will be
displayed for a command line that does not exist.
Rule 3:
Internal procedure calls (that is, a procedure that calls either
itself or another procedure in the same file) must be kept to
eighteen nested calls or less. The nineteenth call attempt will
return execution to the calling command file with no error
message.
PUBLIC
PUBLIC is used to declare memory variables as global and to
prevent their release when control is returned to the dot prompt.
PUBLIC variables must be declared prior to being initialized, and
once declared, these variables will be assigned a logical false
value until initialized. PUBLIC variables can be re-declared as
PUBLIC without losing the values already stored in them.
In programming, declaring all variables as PUBLIC in the main
routine would make dBASE III behave similar to dBASE II.
However, there is one difference in dBASE III, PUBLIC variables
can only be released by the CLEAR MEMORY, CLEAR ALL, and RELEASE
<variable list> commands, but not the RELEASE ALL command.
RELEASE ALL
CLEAR MEMORY
RELEASE ALL and CLEAR MEMORY are not equivalent commands as the
dBASE III manual states. CLEAR MEMORY clears all memory
variables, regardless where they were initialized. RELEASE ALL,
however, will release all memory variables except those declared
PUBLIC or initialized in a nested command file.
REPLACE
REPLACE ALL does not replace all records correctly if an index is
in use and the key field is replaced. Only the first record and
those that logically follow the new value will be replaced. This
occurs because the index is automatically updated (in-place key
updating) when it is edited. The record pointer moves to the
record following the new position, not to the record following
the old position. This can be illustrated in the example given
below (the data file has five records with the field CHARS-C-1,
and is indexed on this field):
. LIST
Record# CHARS
1 a
2 b
3 c
4 i
5 j
. REPLACE ALL Chars WITH 'd'
3 records replaced
. LIST
2 b
3 c
1 d
4 d
5 d
The manual warns against block replacements to the key field.
The correct procedure would be to REPLACE with no indexes in use,
open the indexes with SET INDEX TO, and then REINDEX.
REPORT FORM
MODIFY REPORT
(1) The report generator will right-justify field headings for
numeric fields when the report is run.
(2) If the PLAIN clause is specified with REPORT FORM TO PRINT,
no page ejects occur. The report prints through to the end
without page breaks.
(3) MODIFY REPORT will allow the number of decimal places to be
changed from the default. If this is done and the report is
run, everything is as expected. However, if the report is
modified again, the number of decimal places reverts to the
default when the cursor reaches the "# decimal places" field.
(4) Although not documented in the manual or in the cursor
control menu, Ctrl-N inserts a column in a report being created
or modified. However, its counterpart (Ctrl-U which deletes a
column) is documented and included in the help menu.
--End--
R E F E R E N C E - dBASE III
-----------------------------
Reserved words
Page 1-138 of the tutorial in the first edition f te mnua
uses a sample routine which creates a memory vrible ith he
name 'continue.' Since this is a reserved wod, BAE II wil
give the message, "No database in USE, enter filenam." dBASE
III is assuming you intend to CONTINUE on a LOCATE command.
This will only happen if you use the <variable> = <value> form of
assignment; dBASE III will execute correctly when you use the
STORE <value> TO <variable> form. Other words that will not work
with the first syntax are: AVERAGE, COUNT, and SUM.
ROW()
COL()
After a READ, the ROW() function always returns 24; however, the
COL() function does not change. For example:
SET TALK OFF
var = SPACE(2)
@ 5,40 GET var
? ROW(), COL() <--- This returns 6 and 3.
READ
? ROW(), COL() <--- This returns 24 and 3.
RUN (or !)
The RUN command requires that COMMAND.COM be in the boot drive or
the directory indicated by SET COMSPEC. Otherwise, the incorrect
error message "Insufficient memory" is displayed.
RUN COMMAND
You can get the equivalent to Framework's DOS Access in dBASE III
by issuing RUN COMMAND. This will leave you at the DOS operating
system level, and will allow you to enter any DOS commands. To
get back to the dBASE III dot prompt, type EXIT.
SET ALTERNATE TO
dBASE III will not send a linefeed (that is, CHR(10)) to an
alternate file (Word Perfect looks for this linefeed character in
its mail merge program). The following command file:
SET ALTERNATE TO x
SET ALTERNATE ON
?? "first LF"
?? CHR(10)
?? "second LF"
SET ALTERNATE OFF
CLOSE ALTERNATE
will generate the following test file:
first LFsecond LF
As you can see, there is no linefeed in the file.
SET CONSOLE ON/OFF
The SET CONSOLE ON/OFF command behaves differently in dBASE III
than it does in dBASE II. Specifically, it has no effect when
issued at the dot prompt, and if SET CONSOLE OFF is issued in a
command file that neglects to SET CONSOLE ON, dBASE III will
automatically set the console back on upon the termination of
execution of that file. This includes normal termination as well
as termination by means of pressing the escape key.
SET MENUS ON/OFF
The default for SET MENUS is OFF. However, ASSIST leaves MENUS
SET ON even if they were off prior to entering ASSIST.
SET PROCEDURE TO
PARAMETERS, PROCEDURE
The following program and procedure files illustrate the use of
parameter passing with procedures. FUTVALUE.PRG calculates the
future value of an investment and the future value of an annuity
with the use of the BUSINESS.PRG procedure file. Notice how the
parameters can be passed to BUSINESS.PRG. They can either be
literal numbers, expressions, or variables. Also, notice that
the PARAMETERS command is included after each PROCEDURE that
receives parameters.
LISTINGS:
* FUTVALUE.PRG
* ------------
SET TALK OFF
SET FIXED ON
SET PROCEDURE TO Business
*
* { Calculate future value of an investment }
result = 0.00
DO FV WITH 6000.00, 8.5, 4, 5, result
? result
*
* { Calculate future value of regular deposits (Annuity) }
result = 0.00
DO FVA WITH 150.00, 7.0, 12, 2, result
? result
*
CLOSE PROCEDURE
SET FIXED OFF
SET TALK ON
RETURN
* EOF: FUTVALUE.PRG
* BUSINESS.PRG { Library of business procedures }
* ------------
*
PROCEDURE FV { Calculate future value of an investment }
PARAMETERS amount, rate, periods, years, result
rate = rate / periods / 100
result = amount * (1 + rate) ^ (periods * years)
result = ROUND( result, 2 )
RETURN
*
PROCEDURE FVA { Calculate future value of regular deposits }
PARAMETERS amount, rate, periods, years, result
rate = rate / periods / 100
result = amount * ( (1 + rate) ^ (periods *;
years) - 1 ) / rate
result = ROUND( result, 2 )
RETURN
*
* EOF: BUSINESS.PRG
OUTPUT:
9136.77
3852.15
--End--
INDEX OF TOPICS R E F E R E N C E - dBASE III
Select Topic
------ ---------------------------------------
1. @...GET...RANGE
@...GET...PICTURE
@...SAY...PICTURE
@...SAY using relative addressing
APPEND FROM [SDF/DELIMITED [WITH <delimiter>]]
2. COPY TO <filename> [SDF/DELIMITED [WITH <delimiter>]]
COPY FILE <source filename> TO <target filename>
COPY STRUCTURE EXTENDED
CREATE FROM
Date conversion from dBASE II
Dates that are blank
DISPLAY and LIST
FILE() function
3. FIND
SEEK
Function Keys
INPUT
MEMO fields
MODIFY STRUCTURE
4. Numeric fields with decimal places
Numeric input of large numbers
PARAMETERS, passing fields
5. PRIVATE
PROCEDURE - Calling Command Files from Procedures
PUBLIC
RELEASE ALL
CLEAR MEMORY
REPLACE
REPORT FORM
MODIFY REPORT
6. Reserved words
ROW()
COL()
RUN (or !)
RUN COMMAND.COM
SET ALTERNATE TO
SET CONSOLE ON/OFF
SET MENUS ON/OFF
SET PROCEDURE TO
PARAMETERS, PROCEDURE
7. SET RELATION TO <expression> INTO <alias>
SET UNIQUE ON/OFF
Warning against using a dBASE III file with dBASE II
--End--