home *** CD-ROM | disk | FTP | other *** search
-
- This article is reprinted from the January 1991 edition of
- TechNotes/dBASE IV. Due to the limitations of this media, certain
- graphic elements such as screen shots, illustrations and some tables
- have been omitted. Where possible, reference to such items has been
- deleted. As a result, continuity may be compromised.
-
- TechNotes is a monthly publication from the Ashton-Tate Software
- Support Center. For subscription information, call 800-545-9364.
-
- Understanding SCAN,
- SET options, Using Aliases
-
- Nesting SCANs
-
- To help reduce the amount of dBASE code necessary to produce a
- program, the designers of the dBASE language have introduced the
- SCAN.ENDSCAN command structure. This construct is designed to take
- the place of the LOCATE, DO WHILE, SKIP/CONTINUE, ENDDO sequence of
- commands. Traditionally, looping structures prior to dBASE IV would
- look like this.
-
- GO TOP
- DO WHILE .NOT. EOF()
- .
- * Process this record
- .
- SKIP
- ENDDO
-
- OR
-
- LOCATE FOR <cond>
- DO WHILE <cond> .AND. .NOT. EOF()
- .
- * Process this record
- .
- CONTINUE
- ENDDO
-
- SCAN.ENDSCAN can make this a little smaller by coding it like this:
-
- SCAN
- .
- * Process this record
- .
- ENDSCAN
-
- or
-
- SCAN FOR <cond>
- .
- * Process this record
- .
- ENDSCAN
-
- However, do not assume that SCAN will apparently work in the exact
- same way the common DO WHILE loop does. Particularly, nesting
- SCAN.ENDSCAN loops may lead to some unexpected results. To
- illustrate, let's examine a SCAN loop more closely.
-
- The SCAN command itself behaves like a GO TOP followed immediately by
- a DO WHILE .NOT. EOF(). SCAN with a scope, FOR clause, and/or a WHERE
- clause behaves exactly like a LOCATE with the same clause(s)
- immediately followed by a DO WHILE FOUND() command. Then comes the
- body of the loop. Lastly, the ENDSCAN command behaves like SKIP
- followed by ENDDO if the SCAN had no FOR clauses following it.
- Otherwise, ENDSCAN behaves like CONTINUE followed by ENDDO. Still,
- nothing is apparently amiss here.that is, until SCANs are nested. An
- almost invisible phenomenon occurs. As the following listing
- illustrates, two SCANs means two ENDSCANs, therefore the record
- pointer is moved twice between groups of data. Put plainly, you're
- skipping once more than is obvious, and thereby missing a record of
- possibly needed information. What's more, if the end-of-file is
- reached within the inner SCAN loop, an "End of file encountered" error
- message is produced upon encountering the ENDSCAN command of the outer
- SCAN loop. Use SCAN.ENDSCAN thoughtfully!
-
- SCAN
- SCAN FOR <cond>
- .
- * Process this record
- .
- ENDSCAN && A SKIP or CONTINUE is executed
- here...
- .
- ENDSCAN && And here as well!
-
- SET DIRECTORY, SET DEFAULT and RUN CD
-
- The SET DIRECTORY command has made its appearance in dBASE IV version
- 1.1. This new command extends the SET DEFAULT functionality by
- allowing a drive and a directory to be specified. This capability was
- available in version 1.0, but only through the DOS Utilities section
- of the Control Center. When a SET DIRECTORY command is issued, the
- current DEFAULT drive is also changed to reflect the same drive, but
- issuing a SET DEFAULT TO <drive:> command does not have the reverse
- effect. SETting DEFAULT never has an effect on the current DOS drive,
- so disagreement between DOS and dBASE IV could occur. SETting
- DIRECTORY does affect the current DOS drive and directory, however.
- Another, less obvious, difference between the SET DIRECTORY and SET
- DEFAULT commands is that SET DEFAULT does not "talk". That is, if
- TALK is ON, a SET DIRECTORY command will display the current drive and
- directory on the screen; SET DEFAULT will display nothing. Lastly,
- determining the current SET DIRECTORY and SET DEFAULT settings is also
- available now using the SET() function in this way:
-
- homedir = SET("DIRECTORY")
- defadrive = SET("DEFAULT")
-
- Even though this feature affords the dBASE IV programmer greater
- flexibility and control, a word of caution to veteran programmers may
- be in order. Once the current drive and/or directory is changed with
- the SET DIRECTORY command, that new path is saved in dBASE memory.
- Changing the current DOS directory through the use of the RUN/!
- command, a TSR, or a .BIN file, therefore, may not necessarily reflect
- the dBASE SET DIRECTORY setting. The following code sample
- illustrates this.
-
- . ? SET("DIRECTORY")
- C:\DBASE
- . ! CD
- C:\DBASE && dBase and DOS agree here...
-
- . ! CD SAMPLES
-
- . ! CD
- C:\DBASE\SAMPLES
-
- . ? SET("DIRECTORY")
- C:\DBASE && But not here!
-
- So, depending on the order of their issuance, SET("DEFAULT"),
- SET("DIRECTORY") and ! CD may point to completely disparate entities.
- To complicate matters, when accessing dBASE IV related files
- (programs, data files, labels, and so on) the dBASE IV DEFAULT setting
- will be respected implicitly, regardless of the SET DIRECTORY status
- or the current DOS drive.
-
- Getting SET DIRECTORY, SET DEFAULT and DOS to agree may be
- accomplished by using special forms of the SET DIRECTORY command. If
- the current drive has not been changed, issuing
-
- SET DIRECTORY TO . && period character
-
- will change the dBASE SET DIRECTORY setting to reflect the DOS current
- directory and force SET DEFAULT to reflect the current drive.
- Entering SET DIRECTORY TO by itself with no final parameter will
- change back to that directory from which dBASE IV was started. If the
- drive has been changed, however the following sequence of commands may
- be employed.
-
- . SET DEFAULT TO
- . here = SET("DEFAULT") + "."
- . SET DIRECTORY TO &here
-
- This command sequence forces dBASE IV to agree with DOS. One could
- say that with added power, comes added responsibility.
-
- Functions and Aliases
-
- The following sequence of commands is likely to be familiar to dBASE
- programmers.
-
- SELECT B
- at_end = EOF()
- SELECT A
- IF at_end
- ∙
- ∙
-
- When you wanted to determine conditions which are data file related,
- such as EOF(), RECNO(), or LUPDATE(), it was necessary to change work
- areas, invoke the required function and then return to the previous
- work area.
-
- With dBASE IV, the previous command sequence can be comfortably
- reduced to one or, at most, two lines of program code. The following
- line of code illustrates.
-
- IF EOF("B")
- .
- .
- ENDIF
-
- These functions are not the only extension to dBASE IV that allows a
- programmer to specify operational work areas. GO/GOTO, LIST/DISPLAY
- STRUCTURE, RESET, SKIP, UNLOCK and USE now allow the use of an IN
- clause. For example,
-
- GOTO BOTTOM IN B
-
- would instruct dBASE IV to position the record pointer in work area B
- to the last logical record and no need to change work areas is
- required.
-
- Despite the obvious ease and power that you gain through the use of
- this method of alias referencing, there's a bit of confusion over how
- to properly specify an alias, syntactically speaking. The rules are
- simple. If you are using a command, just about anything goes.
- Assuming that Customer.DBF is USEd in work area 3, any of the
- following examples is valid:
-
-
- GOTO TOP IN 3 && numeric literal...
- GOTO TOP IN (12/4) && numeric expression...
- GOTO TOP IN C && predefined alias specifier
- GOTO TOP IN CHR(67) && character exp./literal
- GOTO TOP IN "C" && indicating a predefined
- && alias specifier
- GOTO TOP IN Customer && An alias name
- && the default in this case
- GOTO TOP IN "Customer" && A character literal
- && indicating an alias
-
- For functions, it's a little more restrictive; only character or
- numeric values are permissible.
-
- mvar = RECNO(3)
- mvar = RECNO(INT(PI()))
- mvar = RECNO("C")
- mvar = RECNO("Customer")
-
-