0% found this document useful (0 votes)
135 views676 pages

Mastering FoxPro - (For Version 1.01 - Charles Siegel

The document provides a comprehensive guide to using FoxPro for database management, catering to beginners, intermediate, and advanced users. It covers essential operations such as adding, editing, and viewing data, as well as creating reports and customizing applications. The content is structured into three parts: using FoxPro, adding power, and programming with FoxPro, with detailed chapters on various functionalities and techniques.

Uploaded by

Parpalabogdan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
135 views676 pages

Mastering FoxPro - (For Version 1.01 - Charles Siegel

The document provides a comprehensive guide to using FoxPro for database management, catering to beginners, intermediate, and advanced users. It covers essential operations such as adding, editing, and viewing data, as well as creating reports and customizing applications. The content is structured into three parts: using FoxPro, adding power, and programming with FoxPro, with detailed chapters on various functionalities and techniques.

Uploaded by

Parpalabogdan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 676

For Version 1.

01
Beginners: Create, Edit &
Use Your Own Database
Intermediate Users:
Customize Screens &
Applications to Suit You
Advanced Users: Expand
Your Capabilities
Through Programming
Principal Database Management Operations Using FoxPro

Adding, Editing, and Viewing Data


You can add, edit, and view data using either the Change or the Browse dis¬
play. The Change display arranges fields one above another, so you can see all
or most of the fields of a single record. The Browse display arranges the fields of
each record from left to right, so you can see many records, but only a few fields
of each.

The Change
display

EMPLIST ■ : - ’ . ■
The Browse Fname Lname Address
display
Audrey Levy 318 B. 31 St.
JACK LOVE 3642 TANACH WAY
EDNA CHANG 2701 ADDISON WAY
CHARLOTTE SAGORIN 2203 SHADY LANE
WILLIAM JOHNSON 523 EAST 21 ST.
■WILLIAM B. ■JOHNSON- 11701 ALBEMARL E RD.
NANCY NIXON 1124 GRANT AVE.
JAMES SKINNER 1206 FRANCISCO ST.
Laying Out a Report
The report layout window gives you a simple, visual method of creating a
report form. The window begins with three bands, one for the page header, one
for the page footer, and one for the detail line that is repeated for each record
included in the report. You can add bands for a report title and report sum¬
mary; you can also group data and include bands for each grouping.

The report
layout window

(continues on last page)


'
Mastering FoxPro
®

Charles Siegel

San Francisco • Paris • Diisseldorf • Soest


Acquisitions Editor: Dianne King
Editor: Doug Robert
Technical Reviewer: Lin Beacom
Word Processors: Scott Campbell and Chris Mockel
Series Designer: Julie Bilski
Chapter Art: Charlotte Carter
Technical Art: Delia Brown
Typesetter: Elizabeth Newman
Proofreaders: Patsy Owens and Hilda van Genderen
Indexer: Nancy Anderman Guenther
Cover Designer: Thomas Ingalls + Associates
Cover Photographer: Mark Johann
Screen reproductions produced by XenoFont

FoxPro is a trademark of Fox Software, Inc.


XenoFont is a trademark of XenoSoft.
SYBEX is a registered trademark of SYBEX, Inc.

SYBEX has attempted throughout this book to distinguish proprietary trademarks from descriptive terms by
following the capitalization style used by the manufacturer.

SYBEX is not affiliated with any manufacturer.

Every effort has been made to supply complete and accurate information. However, SYBEX assumes no responsi¬
bility for its use, nor for any infringement of the intellectual property rights of third parties which would result
from such use.

Copyright ©1990 SYBEX Inc., 2021 Challenger Drive #100, Alameda, CA 94501. World rights reserved. No
part of this publication may be stored in a retrieval system, transmitted, or reproduced in any way, including but
not limited to photocopy, photograph, magnetic or other record, without the prior agreement and written permis¬
sion of the publisher.

Library of Congress Card Number: 90-70259


ISBN: 0-89588-671-5
Manufactured in the United States of America
10 987654321
To my wife, Jeanne Miller
Digitized by the Internet Archive
in 2017 with funding from
Kahle/Austin Foundation

https://archive.org/details/masteringfoxproOOsieg
A CKNOWLEDGMENTS

I would like to thank everyone at SYBEX who worked long hours


to produce this book: editor Doug Robert, technical reviewer Lin
Beacom, word processors Scott Campbell and Chris Mockel, type¬
setter Elizabeth Newman, artist Charlotte Carter, and proofreaders
Patsy Owens and Hilda van Genderen.
Contents at a Glance

Introduction xix

PARTI USING FOXPRO


Chapter 1 Getting Acquainted with FoxPro 3
Chapter 2 Creating a Database Structure 38
Chapter 3 Adding, Editing, and Viewing Data 75
Chapter 4 Understanding Indexes and Expressions 113
Chapter 5 Using Queries and Advanced Expressions 161
Chapter 6 Generating Reports and Mailing Labels 209

PART II ADDING POWER


Chapter 7 Using the View Window with Relational Databases 257
%

Chapter 8 Getting the Most from the Menu System 293


Chapter 9 Creating Custom Data-Entry Screens and Applications 331

PART III PROGRAMMING WITH FOXPRO


Chapter 10 Expanding Your Capabilities through Programming 375
Chapter 11 Write Your Own Professional Menu Application 419
Chapter 12 Using Advanced Programming Techniques 469

APPENDICES
Appendix A Installing FoxPro 513
Appendix B The FoxPro Filer and Desktop Utilities 521
Appendix C Essential Commands and Functions 553

Index 620
XI

Table of Contents _

Introduction xix

What Is a Database? xix

Simple Databases xix


Relational Databases xxi

dBASE Versus FoxPro xxiii

Is This Book for You? xxvi

PARTI USING FOXPRO

Chapter 1 Getting Acquainted with FoxPro 3

Introducing the FoxPro Menu Structure 6


Making Menu Selections 8

A Quick Tour of the Menu System 10

Introducing FoxPro Dialog Boxes 17

Dialog Box Controls 17


Using Dialog Boxes 20

Working with Windows 22

Special Window Controls for Mouse Users 23

Controlling Windows with the Keyboard 24


How to Use the Editor 25

The Edit Menu 28

Working with the Command Window 29

Other Features 32
Getting Help 34

Quitting 37
Xll

Chapter 2 Creating a Database Structure 38

Creating a Sample Database File 42

How to Create a New File 43

How to Define the Structure of a Database 45

Entering the Field Names and Types 52


Saving the Database File 56

The Database File in the Background 62

Opening and Closing a Database File 62

Copying and Modifying the Structure of a Database File 66

Chapter 3 Adding, Editing, and Viewing Data 73

Appending Data 80

Appending Data with the Change Display 82


Appending Data with the Browse Display 88

Changing (or Editing) Data 90

Browsing through the Data 94

Resizing and Changing the Order of Fields 95


Partitioning the Window 96

Deleting a Record 99

Moving the Pointer 103

Shortcuts Using the Command Window 106

Chapter 4 Understanding Indexes and Expressions 113

Using Some Simple Indexes 116

Understanding Expressions 121


Constants 123

Functions and Operators 124


XXIX

Using Expressions in Indexes 141

Alphabetizing by Name 141


Indexing in Descending Order 149

Maintaining Indexes 150

Reindexing 151

Managing Indexes Using the Setup Dialog Box 153


Sorting 156

Chapter 5 Using Queries and Advanced Expressions 161

Working with Logical Expressions 165


Logical Functions 166

Relational Operators 166

Logical Operators 170

To Index or Not to Index 173


FOR and WHILE Clauses 174

Preparing to Use WHILE 175

Making Queries for Single and Multiple Records 177

Unindexed Queries for a Single Record 177


Indexed Queries for a Single Record 181

Queries for Multiple Records 183

Querying with Other Data Types 189

Dealing with Deleted Records 192

Special Techniques 194

Setting a Filter 194

Building a Query into an Index 196

Restricting the Query 199


Scope 200

Fields 202
XIV

The Easiest Possible Report on a Query:


LIST with Options 204

Chapter 6 Generating Reports and Mailing Labels 209

C reating Reports 212

The Report Layout Window 216

The Report Menu 218

A Sample Report 236

Creating Mailing Labels 243

Laying Out Labels 246


What Next? 251

PARTII ADDING POWER

Chapter 7 Using the View Window with Relational Databases 257

Understanding Relational Databases 261

Setting Up a Relational Database 263


Using a Relational Database 272

Using Environment Settings 283

The On/Off Panel 283

The Files Panel 285


The Misc Panel 287

Chapter 8 Getting the Most from the Menu System 293

Keyboard Macros 297


Creating and Using a New Macro 298

Working with Current and Saved Macros 303


XV

Advanced Editor Techniques 304

Creating a Text or Program File 305


Setting Up the Printer and Printing a File 306

The Edit Menu 308

Advanced Techniques for Manipulating Data 314

Append From 314


Total 316

Calculations Using Memory Variables 318

Replace 325

Setting Colors 327

Chapter 9 Creating Custom Data-Entry Screens and Applications 331


The FoxView/FoxCode System 334

The Basics of Fox View 336


The FoxView Shell 337

The Menu System 345

File View 351

Forms View and Table View 353


Generating a Custom Data-Entry Form 356

Laying Out the Data-Entry Form 357

Validating Data 363

Generating and Testing the Program 364


Generating an Application 367

PART III PROGRAMMING WITH FOXPRO

Chapter 10 Expanding Your Capabilities through Programming 375

Structured Programming 378

Some Preliminary Details 382


XVI

Talking to the User: Input/Output 384

Unformatted Input/Output 385

Formatted Input/Output 394

Control Flow 401


Looping 401

Selection 407

EXIT and LOOP 413

A Note on Procedures 416

Chapter 11 Write Your Own Professional Menu Application 419

Analysis 423

Making a Structure Diagram 425


The Main Menu 429

Stub Testing 434

The Data Submenu * 437

The Screen Format 442


A Stub of LOOKUP PRG for Testing 442

Preliminary Testing 444

The LOOKUP Program 445

Reports and Mailing Labels 450


The Report Menu 451

The Label Menu 459

Exporting for Mail-Merge 464

Chapter 12 Using Advanced Programming Techniques 469

Advanced Techniques of Structured Programming 473

Creating Procedures 473


The Scope of Variables and Passing Parameters 477

User-Defined Functions 480


XUll

Reading User Input into Memory Variables 483

A General-Purpose Password Procedure 495


A Few Extra Tricks 497

APPENDICES

Appendix A Installing FoxPro 513

Appendix B The FoxPro Filer and Desktop Utilities 521

Appendix C Essential Commands and Functions 553

Index 620
'

,
XIX

Introduction

WHAT IS A DATABASE? __

When businesses began to computerize their recordkeeping dur¬


ing the 1960s, computer scientists developed theories about how to
redesign the data that used to be kept in paper files so that it could be
managed more efficiently on computer. In many cases, they simply
used new terms in order to speak more precisely about the same sorts
of things that people had always done when they used paper files. In
other cases, though, they developed entirely new ways of handling
data that had not been possible before computers were used.

SIMPLE DATABASES
A simple database is organized in pretty much the same way that
data has generally been organized on paper.
A typical file in an old-fashioned office was made up of a collection
of identical forms, each with blank spaces where information was
supposed to be filled in. A typical example would be a list of names
kept on a collection of index cards, each of which was printed to show
you where to fill out the name, the address, the city, the state, the zip
code, and the telephone number. Most data was kept on larger forms
that went into file folders, but the basic principle was the same: a
standard form would be prepr inted to indicate the type of data that
was needed, and there were blank spaces where you had to fill in the
actual data needed on each form.
Simple databases are organized in the same way. All you need to
learn are the new terms that are used to describe them once they have
been computerized:

• field: Each line to be filled in is called a field. In the index-


card database mentioned above, there is one field for the
name, one field for the address, and so on.
• record: All the data that would appear on a single form is
called a record. In our example, the name, address, and
phone number of one person makes up one record.

• file: A collection of similar records that are used together is


called a file. In our example, the box of index cards that holds
all the names and addresses that you use together make up a
file. Of course, you could also have another file with similar
records—just as you could have another box of index cards
where you keep another list of names and addresses.

These are the three basic terms that you will hear repeatedly when¬
ever people are talking about databases. They are summarized in
Figure 1.1, which shows how database terminology would be used to
describe the old-fashioned index-card file.

It is often convenient to arrange this sort of data into a table. A


computer, of course, lets you display your data both ways—as forms,
with one form for each person, or as a table, with a column for the
name, a column for the address, and so on, so that the data for each
person can be listed on one line. When the data is arranged as a table,
each column represents a field, each line represents a record, and the
table as a whole represents the file.

RELATIONAL DATABASES
Some of the advantages of computerizing data are obvious. A
computer can instantly look up the record you want: for example, if
you are looking for the telephone number of a certain person. It can
print out the data in different forms, saving you the trouble of copy¬
ing it from the list in the form you need: for example, it can print out
a list of names and phone numbers when you want to call people, and
can print out labels when you want to do a mailing. It can instantly
select only certain records from the file: for example, it can list the
names and phone numbers of only the people who live in New York,
or it can print out mailing labels for only the people who live in New
Jersey. It lets you use the data in different orders: for example, you
can effortlessly print out your mailing labels in zip code order and
print out your list of names and phone numbers in alphabetical
order.
In addition to these obvious advantages of computerizing data,
early computer scientists found a more subtle advantage of com¬
puterization. They found that computers made it possible to avoid
repetition.
In the days of the paper office, for example, a typical large business
had dozens of different forms that included the name and address of
each employee. The payroll department used a form with the name,
address, and wages of each employee; the benefits department used a
form with the name, address, and eligibility for benefits of each
employee; the human resources development department used a
form with the name and address and the training courses taken by
each employee; and so on.
This repetition was obviously inefficient. The same name and
address—and, of course, other basic information such as Social Secu¬
rity number and telephone number—had to be filled out over and
over again. If an employee moved, a dozen different people in a
dozen different departments would have to change the address on
a dozen different forms.
Repetition could not be avoided in a paper office, but computer
scientists quickly devised ways to let a business enter the names and
addresses only once and to let each department use those names
and addresses in combination with the specific data that it needed
about wages, benefits, training courses, or whatever.
Early methods that were used for tying all this data together were
very complex and unwieldy. There were hierarchically organized
databases and databases organized as networks that were held
together using pointers, both of which were so complicated that they
could only be understood and used by programmers with training in
database theory. Companies had to have teams of programmers just
to retrieve information or to produce reports.
In 1970, E. F. Codd invented a new way of tying together this sort
of data, which was called the relational database. His idea was to break
down the data into separate files, which could be related using a com¬
mon key field.
In the example we have been looking at, the business would proba¬
bly use an employee number as a key field. Then it could have one
file with each employee’s employee number, name, address, and
other basic data, another file with each employee’s employee number
and wages, another file with each employee’s employee number and
eligibility for benefits, and so on. Basic information such as the name
and address would only have to appear once. Each department
would have a program that used the employee number to relate the
data it needed on wages or benefits to the basic data that everyone
needed.
With relational databases, most of the work of relating the data
was built into the database management program. You did not need
programmers to create pointers to relate one record to another. You
just had to enter the right employee number and wage in one file, and
the database management system would do the work of relating that
record to the record in another file that had the name and address for
that employee number.
Codd analyzed the relational database using mathematical set the¬
ory and discovered ways to break down the data that minimized
repetition. Because they were both powerful and simple to visualize
and to use, relational databases quickly became the preferred method
of handling complex data.
XXlll

In simple databases—for example, the simple list of names and


addresses that could be kept on index cards—there is no distinction
between the database and the file: a simple database consists of only
one file. Relational databases, though, consist of more than one file.
We have to add one more term to those we already defined: in addi¬
tion to field, record, and file, we now understand the term database
itself. A database is made up of all the data used together in an appli¬
cation, whether it is kept in one file or in many.

DBASE VERSUS FOXPRO -


When the IBM-PC and compatibles became popular during the
1980s, the program dBASE II, developed by Ashton-Tate, quickly
emerged as the leading database management program. A couple of
simpler programs had some brief popularity because they were so
easy to use, but none of them let you manage more than a simple
database, such as the basic list of names and addresses that you could
keep on index cards. dBASE II was the most popular of the programs
that let you work with either a simple or a relational database.
dBASE’s interactive commands let business users create, edit, and
print reports on databases. dBASE also included a programming
language which was relatively easy to learn and to use, and program¬
mers used it to create menu-driven custom applications for their
clients. Business users who did not want to bother learning about
dBASE could have programmers set their applications up for them,
so they could just make choices from menus and edit data or print out
exactly the reports they needed; it was quicker and easier to do this
programming in dBASE than in other computer languages because
dBASE was specifically designed for this sort of task.
Because of its power, dBASE was by far the most popular database
management system for microcomputers. At the high point of its
popularity, it was estimated that 80 to 85 percent of all database
applications on IBM-PC compatible microcomputers used dBASE.
dBASE became an industry standard. Even unrelated database pro¬
grams were designed so that they could use dBASE data files.
dBASE II was followed by dBASE III and dBASE III +, both of
which added to its power, but there were complaints about limitations.
Many users considered the various dBASE versions too difficult.
Early versions of dBASE just presented the user with a dot prompt,
and the user had to memorize all the commands that had to be
entered at the prompt in order to manipulate the database. You had
to enter exactly the right command to edit the data or to produce a
report. Even if you were working with the simplest sort of database,
you had to learn dozens of commands; if you spelled a command
incorrectly or got its syntax slightly wrong, dBASE would display an
error message and refuse to work.
Critics said that dBASE told the user less than any other program
that existed: even DOS, which was notorious for being cryptic, at
least displayed a prompt that told you what drive you were on, but
dBASE just displayed a dot, the smallest, least informative prompt
imaginable. Later versions of dBASE added an “Assistant” mode,
which let you do some of the basics by using menus, but its capacity
was limited.
Programmers had different complaints from users. There was
grumbling about certain limitations of the dBASE language, such as
its inability to create arrays, but the most common complaint by far
was that dBASE did not include a compiler.
Most programming languages are compiled: the application pro¬
gram is written in an English-like language, and then the compiler
translates it permanently into the sort of machine language that the
computer uses. When programmers distribute the application, they
can simply give the users the compiled program, which runs directly
on their computers.
On the other hand, some more primitive programming languages
(such as the early versions of BASIC) are interpreted. The program
remains in the English-like language that it was written in. Each time
it is run, the interpreter reads it one line at a time, interpreting each
line into machine code. An interpreted program has two major dis¬
advantages over a compiled program. First, it runs much more
slowly: each line has to be interpreted before it is run, and that takes
time. Second, the language program itself must be distributed along
with the application: it cannot run by itself.
dBASE programmers complained about both of these problems.
Everyone agreed that programs working on large data files ran too
slowly. Some thought it was even worse that you had to own dBASE
to run a program written in dBASE. If clients who did not already
XXV

own dBASE hired a programmer to write a database management


system for their business, they did not like the idea that they had to
pay as much for a copy of dBASE to run the program as they had
paid the programmer to write the program. Further, some program¬
mers were beginning to use dBASE to write complete commercial
applications, such as small business accounting programs, but they
could not really distribute these programs commercially as long as
users needed to own dBASE itself in order to run them.
In response to these complaints, a couple of companies that were
not related to Ashton-Tate (which owns dBASE) came up with com¬
pilers and pseudo-compilers for the dBASE III and dBASE III +
languages—usually with enhancements and sometimes with slight
incompatibilities compared with the original.
One of these was Fox Software, which developed FoxBase and then
FoxBase 4 , dBASE-compatible development systems that include a
-

pseudo-compiler. A pseudo-compiler does not translate programs into


machine code that the computer can run direcdy. Instead, it does a sort
of partial translation and creates something that is closer to machine
code than the original English-like program and that runs much more
quickly than an interpreted program would, but which still cannot run
by itself; it must be distributed along with a run-time module that does
some interpretation each time it runs.
FoxBase was widely considered one of the best of the dBASE com¬
pilers because its programs ran quickly and because it had a high-
level of compatibility with dBASE itself. You could take programs
written using dBASE and compile them using FoxBase, while other
compilers usually required you to rewrite the program a bit before
they could compile it.
You can see that different dialects of dBASE were emerging. Com¬
pilers not only enhanced the original dBASE language but some¬
times also differed from it in minor ways. As more enhancements
appeared, the dBASE standard became diffuse: Ashton-Tate could
no longer define what the dBASE standard was.
Today, people no longer know which version of the standard to
choose Ashton-Tate’s dBASE IV has failed completely to reestablish
itself as the standard. Not too long ago, I struck up a conversation
with a programmer who was browsing in the computer section of a
major bookstore: he was planning to take up database programming
and was wondering whether to learn FoxBase + or Clipper. He was
not even considering learning dBASE IV: it was out of the picture.
FoxPro is a major advance over FoxBase +, and it could easily
emerge as the new dBASE standard.
As you will see, FoxPro is designed around a very powerful combi¬
nation of a Macintosh-like user interface based on windows and pop¬
up menus (which can be used easily either from the keyboard or with
a mouse) and a special Command window, where you can enter the
type of procedural commands used at the dBASE dot prompt. As its
most striking feature, this interface automatically generates com¬
mands in the Command window when you make the equivalent
choices from the menu system, making it easy for users to get started
with the program and to learn more and more about it as they go
along.
For programmers, the FoxPro language includes a set of com¬
mands that make it easy to create pop-up menus and windows. It also
includes a major extension of the dBASE language for advanced
users: low-level file handling functions, similar to the file handling
functions in the C language, which could make it a very popular
general-purpose language as well as the industry standard database
programming language.

IS THIS BOOK FOR YOU? _

This book is designed to suit people who want to approach FoxPro


in a variety of different ways.
This book is for you if you want a fast introduction to the funda¬
mentals of FoxPro. Part I of the book—-the first six chapters—are
meant to be tutorials on the features of FoxPro that are essential for
ordinary business users.
Unnecessary features of the program are put in later sections or in
the appendices, so that they do not get in the way of your learning to
use the program as quickly as possible. For example, the features of
the menu system that are not essential are put off until Part II, so that
they will not get in the way of your getting started with FoxPro
quickly.
You can use Part I of this book and then get right down to work
with FoxPro. You will have learned what you need to know to handle
XXUll

any simple database application—almost every application that you


will come across in practice.
This book is also for you if you want to become a power user of
FoxPro. Part II teaches you all the features of the menu system. It
will teach you, for example, to create keyboard macros that assign
values to any of the function keys or to almost any combination of
Ctrl, Alt, Shift and another key. It will teach you to create custom
data-entry screens that validate data, so you can set up FoxPro to
minimize the training that data-entry people need—and to minimize
the number of errors they make. It will take you as far as using the
application generator to create an entire menu-driven application,
which would let you set up the work that you need to do with FoxPro
so it can be done by someone who has absolutely no experience with
the program.
Finally, this book is for you if you want to become a FoxPro pro¬
grammer. Part III begins with a general discussion of the principles
of computer programming, such as control flow and passing param¬
eters, using FoxPro as an example. In the final chapters, you will
write a complete, professional-quality mailing list program using
advanced techniques of structured programming. FoxPro is powerful
enough that you will be able to write programs of this quality by the
time you finish this book, whether or not you have ever done any pro¬
gramming before.
If you are impatient to move on to programming, you may skip
Part II of this book and go directly to Part III after you finish Part I.
You will be able to follow all of the programs with Part I as a back¬
ground. After you have learned programming, you can go back to
Part II to learn additional FoxPro commands that will add more
power to your programs.
The FoxPro language is so large that it is hard for anyone to learn it
all. It includes all of the dBASE language plus much more. Even
experienced programmers can browse through the reference manual
and suddenly be surprised to learn new commands or functions that
give them easier ways of doing things they have done for years. The
FoxPro interface and the basic FoxPro commands that you need, on
the other hand, are very simple to use: one can never finish learning
FoxPro, but you should find it easy to begin.
. : ■

Using FoxPro
Getting
Aquainted with FoxPro
Fast Track '***
To make a selection from the menu using a mouse, 8
point at the menu pad that you want and press the mouse but¬
ton to make the menu popup appear. Continue to hold down
the mouse button while dragging to highlight the menu option
you want. Release the mouse button to select that option.

To make a selection from the menu using the keyboard, 9


press Alt or FI0 to move the cursor to the menu bar, and the left
and right arrow keys to move it to the menu pad you want.
Then press Enter to make the menu popup appear. Use the up
and down arrow keys to highlight the menu option you want,
and press Enter or the space bar to select it.

To use dialog box controls with a mouse, 20


simply click a text button, a check box, or a radio button. To
use a popup control, treat it exactly as you would a menu pad.
To use a scrollable list, click the arrow at the top or bottom of
the scroll bar to move up or down the list, then click on the
desired item. To use a text box, simply position the cursor in
the box and type in the text.

To use dialog box controls with the keyboard, 20


first use Tab (or Shift-Tab) to highlight the control you want to
use. Once they are active, most controls can be used simply by
pressing the space bar. To make a selection from a scrollable list,
use the up or down arrow keys or PgUp or PgDn to move the cur¬
sor to the desired item in the list, then press the space bar. To use a
popup control, press the space bar to pop the menu up, use the up
and down arrow keys to highlight the desired menu option, and
press the space bar. To use a text box, simply tab until the text box
is active, then start typing.
To change the appearance or the position of a window using a 23
mouse,
use the special window controls that are common to many win¬
dows applications.

To change the appearance or the position of a window using the 24


keyboard,
use the Window menu popup. To change the location of a win¬
dow, select Move; when its border flashes, use the arrow keys
to move it, then press Enter. To change the size of a window,
select Size; when its border flashes, use the arrow keys to adjust
its bottom and right borders, then press Enter. To “zoom” or
“unzoom” a window, simply select Zoom.

To edit text, data, and commands, 25


use the conventional editing keys. In addition, you can use Ctrl to
magnify the ordinary uses of the key: for example, Ctrl-Backspace
deletes an entire word, and Ctrl-End moves to the end of a docu¬
ment. Shift marks text as you move the cursor; you can also mark
text using the mouse. The Edit menu lets you use more advanced
Editor features.

To use the Command window, 29


simply type commands into it and press Enter. All commands
that you enter are saved; you can reuse previous ones and even
edit them. When you press Enter, the command is executed.

To quit FoxPro, 37
select Quit from the File menu popup, or enter QUIT in the
Command window. Always quit FoxView when you are done
with it to avoid loss of data.
6 MASTERING FOXPRO

CH. 1

EVERYTHING YOU WILL DO WITH FOXPRO CENTERS


around its interface of pop-up menus and windows. Beginners use
this interface to perform simple menu-driven operations on their
data. Advanced programmers use the same interface to write and
compile their program files.
This chapter teaches you how to use the FoxPro interface and tries
to make you comfortable with its basics before you go on to the rest of
the book.
As you will see, FoxPro works well using either the keyboard or a
mouse. With the keyboard, it often gives you several ways of doing the
same thing. This lets you choose the method you find most convenient.
Because there are many ways of performing most operations, it
will not be possible to list them all every time they are discussed.
When later chapters give you step-by-step instructions on using Fox¬
Pro, they will simply tell you to make certain selections from the
menu and from the dialog boxes. They will not detail all the ways that
you can make these selections, because it would simply take too much
time and would make the book difficult to read.
For this reason, it is very important for you to make good use of
this first chapter. This chapter will detail all the ways of performing
the basic FoxPro operations, the ones you will perform over and over
again as you work with this book. Experiment with the different ways
of doing things as you read. The rest of the book will be easier for you
to use if you begin to become comfortable with one way of making
selections from menus, one way of using dialog boxes, and one way
of working with windows by the time you finish this chapter.

INTRODUCING THE
FOXPRO MENU STRUCTURE _

FoxPro combines an easy-to-use interface, based on choosing


items from pop-up menus, with a Command window, where you can
enter the sort of procedural commands that were used in early ver¬
sions of dBASE. FoxPro’s combination is unique in that when you
make choices from the menu, the program displays the written com¬
mand equivalent, which appears in the Command window.
In this section, you will learn to make selections from the FoxPro
menu system and then will take a quick tour of the FoxPro menu
GETTING ACQUAINTED WITH FOXPRO 7

structure. First, of course, you must start the program. If you have
not yet installed FoxPro, see Appendix A for installation instructions
before going on.

1. Make sure you are in the FOXPRO directory that was cre¬
ated when you installed the program.

2. At the DOS prompt, type FOXPRO and press Enter. You


will see the initial FoxPro screen illustrated in Figure 1.1.

System File Edit Database Record Program Window

Figure 1.1: The initial FoxPro screen, with the menu and Command window.

The main menu is at the top of the screen. Most of the screen is
taken up by the FoxPro logo with the copyright notice under it, and
the Command window is near the bottom of the screen. Notice
that the cursor is in the Command window, ready for you to enter a
procedural command. (Unfortunately, the cursor does not appear in
the screen images used in the figures. When it is important to know
where to find the cursor, the text will instruct you where to look.)
The highlighted menu across the top of the screen is called the menu
bar. Each of the words written in the menu bar is called a menu pad, as
in keypad. Think of each pad as a button. As you will see, when you
select one of the menu pads, a menu popup will appear, containing a
group or groups of choices called menu options.
8 MASTERING FOXPRO

CH. 1

When you perform certain operations with FoxPro, you will find
that some of the menu pads that are no longer relevant to what you
are doing will disappear from the menu bar. Sometimes, you will also
find extra pads added to the right of the pads already on the menu
bar. For example, when you are creating mailing labels, a Label pad
will appear, permitting you to access additional options relevant to
working with labels.
When you look through the menu popups, you will see that a

H Do not bother learn¬


ing Control-key
single popup may be subdivided by lines to group related options.
You will also see that some menu options are dimmed, indicating
shortcuts when you are
that they cannot be chosen in the current situation. Some menu
first starting with FoxPro. options have Control-key shortcuts next to them, a combination of the
Because they appear next Ctrl key (indicated by the symbol *) and some other key. You can use
to the menu options, over
a Control-key combination to choose an option instantly without
time you will automati¬
cally learn the shortcuts going through the menu system.
for the options that you A menu option followed by an ellipsis (...) indicates that a dialog box
use frequently.
will appear when you choose that option. Dialog boxes present more
information and more choices relating to the option you have selected.

MAKING MENU SELECTIONS


If you are using a mouse, selecting options from the FoxPro menu
system is simple and intuitive. If you are using the keyboard, select¬
ing options from the menu is not as intuitive, but is still very easy to
do once you are used to it.

USING A MOUSE

To make a selection from the menu using a mouse, simply point at


the menu pad you want and then hold the mouse button down. This
will make that pad’s menu popup appear. Continue to hold down the
mouse button and drag it downward until the menu option that you
want is highlighted. Releasing the mouse button at that point selects
that option. The menu popup will disappear, and FoxPro will do
whatever your selection tells it to do.
Practice this technique by making each menu popup appear as you
read the “Quick Tour of the Menu System” in the section following
this presentation of techniques.
GETTING ACQUAINTED WITH FOXPRO 9

USING THE KEYBOARD


You can use the keyboard in several ways to make a selection from
the menu. Choose the one that you like best.
First, you must make the right menu popup appear. You may
either

• press the Alt key in combination with the highlighted letter of


one of the menu pads to make that popup appear immedi¬
ately, or

• press the Alt key by itself or the F10 key by itself to move the
cursor to the menu bar. The cursor will land on the System
menu pad initially, but the System menu popup will not
appear. To select the menu pad that you want, use the left
and right arrow keys to move the cursor to that menu pad;
then make the menu popup appear by pressing any of the fol¬
lowing: Enter, the space bar, the up or down arrow key, or
any character key.

After you have made one menu popup appear, you can make others
appear by moving the highlight left or right from one menu pad to
another; however, only one menu popup can appear at a time. It is
sometimes convenient to browse through the menu popups in this way.
Once the menu popup that you want has appeared, you can

a The highlighting of
the letter to press in
choose the menu option from within it in a couple of ways. Either

• press the highlighted letter of that menu option (usually the


order to select a menu
option does not appear on first letter), or
some displays. Where this
• use the up and down arrow keys to move the cursor to high¬
is the case, you may select
options by using the up light the menu option you want. (You will notice that when
and down arrow keys and the cursor is on the first option, the up arrow key moves the
then pressing Enter or the cursor to the last option as if you had reached the top and
space bar.
were starting over from the bottom.) Once you have high¬
lighted the option you want, select it by pressing Enter or the
space bar.

After you select a menu option, the menu popup will disappear, and
FoxPro will do whatever your selection has told it to do.
10 MASTERING FOXPRO

CH. 1

Try to become comfortable now with one or two of these methods


of selecting menu options. Experiment with them by calling up the
menu popups in different ways as you read the next sections that
describe the popups. If you also practice selecting menu options in a
few different ways, it will take you into the uncharted territory of win¬
dows and dialog boxes, but try it anyway. You can return to the
menu system simply by pressing the Esc key repeatedly to “back up’ ’
until you reach the menu display.

A QUICK TOUR OF THE MENU SYSTEM


Some people find the organization of the FoxPro menu system a
bit confusing at first, so when you begin with FoxPro, it is a good idea
to look at each of the original menu popups in order to get an overall
idea of how the menu is organized. Once you have a sense of its gen¬
eral structure, you will find it easy to work with the menu system.

THE SYSTEM POPUP


Use one of the techniques that you just learned to look at the Sys¬
tem popup, illustrated in Figure 1.2. (The FoxPro logo and the Com¬
mand window have been eliminated from the following illustrations
to make them clearer.)
The utilities below the line—such as the Filer, the Calculator, the
Calendar/Diary, and so on—are DOS and desktop utilities which
can be handy, but they are not related to FoxPro’s main functions.
They are discussed in Appendix B of this book.
The utilities above the line are a bit more closely related to Fox¬
Pro’s main functions. Macros will be discussed in Part II of this book,
and Help will be discussed later in this chapter.

THE FILE POPUP


The File popup, shown in Figure 1.3, includes some of the most
important options of the menu system.
The options above the first line let you create and use files—not
only database files but also text files, program files, and the files that
FoxPro uses for its indexes, reports, and mailing labels. New lets you
GETTING ACQUAINTED WITH FOXPRO 11

System File Edit Database Record Program Window

Bller
alculator
Calendar/[giary
Special Characters
Ascgi Chart
Capture
Pugzle

Figure 1.2: The System popup.

System File Database Record Program Window

iipen.
Close

Save
Save as.
Revert

Printer Setup.
Print...

Quit

Figure 1.3: The File popup.


create a new one of any of these; Open lets you open and use an exist¬
ing one, and Close lets you close the one you are currently using. The
next group of options is also for working on these files. Save lets you
save the changes you have made, Save As lets you save them under
12 MASTERING FOXPRO

CH. 1

another name, and Revert lets you cancel the changes that you made
to a file since it was last saved.
As you work with FoxPro—creating database files, indexes, reports,
and mailing labels—you will use these first two groups of menu options
constantly.
The options in the third group let you print, and, finally, the Quit
option lets you leave FoxPro and return to DOS.

THE EDIT POPUP


The Edit popup, shown in Figure 1.4, is useful mostly for advanced
users who use the FoxPro editor to write and debug lengthy programs or
text files.

System File HjjEUj Database Record Program Window

Undo ~U
Redo ~R

Cut
Copy ~C
Paste "'V
Clear

Select All ~A

Goto Line...
Find... ~F
Find Again '"G
Replace And Find Again ~E
Replace All

Preferences...

Figure 1.4: The Edit popup.

The same editor is used throughout FoxPro for editing data in


your databases and editing commands in the Command window as
well as for editing programs and text. The editing that you will do in
this book generally involves only the basic features of the editor, and
not the advanced features that you access through the menu.
Notice that almost all of the advanced word-processing features on
the Edit menu have Control-key shortcuts listed to their right. Once
GETTING A CQUAINTED WITH FOXPRO 13

you become an advanced user of the editor, these shortcuts can make
it a very powerful and fast word processor.
The basics of the editor and a couple of the most useful menu fea¬
tures, such as Copy and Paste, are discussed later in this chapter.
Advanced features of the Edit menu are discussed in Chapter 8.

THE DA TABASE POPUP


The Database popup, shown in Figure 1.5, is used to perform
operations on the entire database. You will find it fundamental to the
work you do with FoxPro.

System File Edit I Database 1 Record Program Window


f— .. 1 ~ .. i
Setup...
ibsseem
Append From. .
Copy To...
Sort...
T otal. . .

Average..
Count...
Sum...

SCalculate
eport...
abel...

Pack
Reindex

Figure 1.5: The Database popup.

The two options in the first group let you do basic operations on
the entire file. Setup lets you determine how the data in the file will be
displayed. Browse lets you look at and edit data from the entire file.
The next grpup of options lets you perform operations that involve
two separate files: appending the data in one file to another, copying
from one file to another, sorting the records from one file into an¬
other, and totaling the numeric fields from one file into another.
The next group of options lets you work with one file, performing
numeric operations or producing reports or labels.
14 MASTERING FOXPRO

CH. 1

The final group includes two utilities which let you finalize dele¬
tions and repair indexes.

THE RECORD POPUP


The Record popup, which lets you work with individual records of
a database file, is not activated unless you have already opened a
database file. On some screens, you can see that the Record pad is
dimmer than the other pads. Since at this point you will not be able to
bring forth the popup, you should look at the illustration of it in Fig¬
ure 1.6 to follow the discussion of its options.

System me Edit Database 1 Record 1 Program Window

Figure 1.6: The Record popup.

Like the Database popup, the Record popup is fundamental to the


work you will do with FoxPro. The first two options, Append and
Change, let you add a new record or edit an existing record. These
options let you see only one record at a time, but they let you do
much the same things that the Browse option on the Database popup
lets you do.
The options in the next group let you move around the database to
get to a record that you want to use. The options in the final group let
GETTING ACQUAINTED WITH FOXPRO 15

you replace the values of records, delete records, or recall deleted


records.

THE PROGRAM POPUP


The Program popup, as you may have guessed, includes options that
are useful for writing FoxPro programs. It is illustrated in Figure 1.7.

System 'File Edit Database Record ■JWiiffTTM Window

Figure 1. 7: The Program popup.

The first option, Do, lets you run a program. The pair of options
below Do let you stop running a program or resume running a pro¬
gram. The options in the following group are useful for debugging.
The options in the final group are utilities. Compile, predictably,
lets you compile a program. Fox View is the application generator
that you will learn about in Chapter 9. FoxDoc is the documentation
generator. FoxGraph lets you access a program to generate graphs of
FoxPro data; this graphics program is not included with the FoxPro
package and must be purchased separately.

THE WINDOW POPUP


The Window popup, illustrated in Figure 1.8, helps you use the
window interface itself.
16 MASTERING FOXPRO

CH. 1

System F i 1c I d; t Database Record F'rogram Window

Hide
Clear

Move "F7
Size ~F8
Zoom ■'F10
gycle HU
Cofjor. ..

I
Command U£j
ebug
race
lew

Figure 1.8: The Window popup.

The first option, Hide, lets you hide a window and temporarily
suspend use of it. The second option, Clear, clears the contents of a
window. Both of these options will be discussed further later in this
chapter, along with most of the options in the second group, which let
you change the appearance of a window.
The options in the third group let you use special windows: the
Command window (which you have already seen), the Debug and
Trace windows (which are used in programming), and the powerful
View window, discussed in Chapter 7.

SUMMARY OF THE MENU SYSTEM

Once you have this general overview of it, the FoxPro menu system is
not difficult to understand. It offers so many options it can be confusing,
but once you realize that only some of the options on a few of the popups
are essential to using FoxPro, it becomes easy to understand.
Three of the popups are fundamental. The File popup is essential
for creating and using the files that hold databases, indexes, reports,
mailing labels, and so on. The Database popup is essential for work¬
ing with whole database files, and the Record popup is essential for
working with records and groups of records within files.
GETTING ACQUAINTED WITH FOXPRO 17

In addition to these, the Window popup, though it is not used for


database management, is essential to working with the FoxPro inter¬
face itself.
The other three popups let you use utilities or advanced features,
and you will not have to deal with them for some time.
With the general overview of it that you now have, you should not
have any trouble finding your way around the menu system.

INTRODUCING
FOXPRO DIALOG BOXES
S
_

Dialog boxes are As you have seen, many of FoxPro’s menu options are followed by
often called “dia¬ ellipses. If you choose one of these options, you will be presented with
logs” in other books
about FoxPro. For clar¬
a dialog box asking you for more information. Within a dialog box,
ity, however, this book there are a number of different types of controls, which are used for
uses the more precise different purposes. Some of these controls can also contain ellipses:
term “dialogbox.”
choosing one of these controls will take you to another dialog box ask¬
ing you to enter more information.
In this section, you will begin by looking at the different types of
controls within dialog boxes, and then you will learn to use each
of these controls with either a mouse or the keyboard.

DIALOG BOX CONTROLS


Figure 1.9 shows the dialog box that appears if you select Sort from
the Database menu popup while you are working with a database file.
This is a complex dialog box. In fact, it is used as an illustration
because it is one of the only dialog boxes that is complex enough to
use every type of control. You should not try, at this point, to under¬
stand fully how this dialog box works, though the discussion will
sometimes mention sorting purely to clarify the functions of the
different controls in this specific dialog box.
There are six different types of controls. The use of these controls
with the mouse and keyboard will be discussed in the next section.
Their general functions are described here.
18 MASTERING FOXPRO

CH. 1

scrollable list radio buttons

System Database Program Window

Database Fields: Sort Order:

FNAME C 15 0 < Move •» >


LNAME C 20 0
J08TITLE C 30 0 < Remove >
DEPTCODE C 3 0
SALARY N 10 2 1r i ield Options —
STARTDATE D 8 0 1 < 1 Qscendlng
ADDRESS C 30 0 I < ) descending
CITY
STATE
C
C
20
2
0
1u
0 i /
] ugnore Case

Database: r Input - r Output -


Scope. . -i < Safle As... > [ ] Fieflds... <{|ancel >
DEMO Bor... /
0hile..1 « OK

popup control text buttons

check boxes text box

Figure 1.9: A dialog box.

• scrollable list: A scrollable list is a boxed list with what is


called a scroll bar on its right. A scroll bar is a vertical bar with
an arrow at the top, an arrow at the bottom, and a diamond
somewhere between to show you where in the list the cursor
is. When it is activated, one of the items in the list is high¬
lighted, and you move the highlight to make your selection.
In this dialog box, the scrollable list lets you select database
fields; in other dialog boxes, a scrollable list might let you
select files or directories.
• popup control: A rectangle with double lines on its right and
bottom edges is a popup control. If you select this control, a
popup that is similar to a menu popup appears. In the example
in the illustration, the popup control would display a list of avail¬
able databases, enabling you to choose the database file to be
GETTING ACQUAINTED WITH FOXPRO 19

sorted. After you choose one option from the popup, the popup
disappears so it does not get in your way, and the name you
chose appears within the control, as DEMO does now.

• radio buttons: Radio buttons are options with parentheses to


their left. A dot in one of the parentheses shows which button
is selected. These are used when you must choose one and
only one option from a group of options: choosing one of the
options automatically unselects whichever button was al¬
ready selected. In this example, the set of radio buttons offers
only two options—sorting in either ascending or descending
order. Usually radio buttons offer more than two options.

• check boxes: A pair of square brackets is a check box, represent¬


ing an option that may be set on or off. An X appears in the
check box when the option is on. Often several check boxes that
perform associated functions appear as a list; unlike radio but¬
tons, more than one check box may be chosen.

• text buttons: A word or two of text surrounded by angle


brackets is a text button. Some text buttons present you with
yet more choices; others actually make something happen:
after you have used the other controls to select all the options
you want, you use a text button to initiate or cancel the oper¬
ations) as specified. Double angle brackets indicate the
default text button, the action which is most commonly per¬
formed. The example contains five text buttons, two of
which are included in most dialog boxes: < Cancel > lets you
leave the dialog box without initiating the operation, and
<<OK>>, which is the default, initiates it as specified.

a In some FoxPro
dialog boxes, only
• text box: The Output rectangle in this dialog box is a text
box. You can type text into it, or you can have FoxPro dis¬
the position of the cursor play text resulting from your menu choices. In this example,
lets you know that you you can either type the name of the hie where you want the
can type text at that
sorted output saved or select the Save As text button within
point.
the text box to choose a hie name, which will then appear
next to (or often below) the text button.
20 MASTERING FOXPRO

CH. 1

USING DIALOG BOXES


You can exit from As with many other features of FoxPro, using dialog boxes with a
the dialog box and mouse is very easy and intuitive, and using them with the keyboard is
cancel what you have
done within it by choos¬
easy after you have gotten used to it. Though it is not hard to learn to
ing the Cancel text button work with the keyboard, you may want to refer back to this section a
or simply by pressing few times when you first use dialog boxes in later chapters. After
Esc. You can execute the
a short time, dialog box techniques will become second nature
default choice by choos¬
ing the default text button to you.
or by pressing Ctrl-Enter.
These keyboard shortcuts
(Esc and Ctrl-Enter) are USING A MOUSE
\
useful regardless of
whether you are using a
Most controls in a dialog box can be selected by simply clicking
mouse or a keyboard. them with the mouse. Click a text button to perform that action.
Click a check box to select it and an X will appear between the square
brackets. (If an X is already there, clicking it will unselect the option
and make the X disappear.) Click one of the buttons in a set of radio
buttons and it will be selected, automatically unselecting any previ¬
ously selected button in the set.
To use a popup control, point at it and hold down the mouse but¬
ton to make a popup with additional options appear. Without releas¬
ing the mouse button, drag to highlight the option you want. Then
release the mouse button to select that option, just as you do when
you are selecting from a menu popup.
When you use a scrollable list, you may click the arrow at the top
or bottom of the scroll bar to move the list up and down, then click on
the desired item to select it. (You can also drag the diamond at the
center of the scroll bar to move quickly through the list.)
To use a text box, simply position the cursor in the box and type in
the text, or select the text button if there is one within or next to the
box. The latter method will display another dialog box from which
you can make choices that will automatically fill in the text box.
You can also reposition dialog boxes on the screen if they are in the
way of something you want to see: just use your mouse to point to
the dialog box’s top border and drag to move it.

USING THE KEYBOARD


To use dialog boxes from the keyboard, you must first use the Tab
key to activate the control that you want to use. Pressing Tab or
GETTING ACQUAINTED WITH FOXPRO 21

Ctrl-Tab moves you from one control to another: generally, Tab moves
the highlight “forward” through the controls, and Ctrl-
Tab moves “backward.” Once you have highlighted the control you
want, you can use the arrow keys to move within it. For example,
you would use the arrow keys to move to the different items in a scrol¬

D M any controls can


also be selected by
lable list.
Once they are active (highlighted), most controls can be used sim¬
pressing Enter—but not
ply by pressing the space bar. Press the space bar to use the text but¬
all of them. If you get in ton that is active. Press the space bar to place an X in a check box, or
the habit of using Enter to remove the X from it if one is already there. Press the space bar to
to select controls and then
select the radio button that is currently active (and to automatically
find that it does not work,
remember you can press unselect any previously selected button in that group).
the space bar instead. Sometimes one of the letters in a text button is underlined or high¬
lighted. When this is the case, you can use it by simply typing that let¬
ter, referred to as a hot key, without having to use the Tab key to select
the control first.
To make a selection from a scrollable list, you must move the cur¬
sor to the item you want within the list: once you have used the Tab
key to make the list active, use the up or down arrow key to move the
highlight. If the list is a long one, use the PgUp and PgDn keys to
move the cursor more quickly. Once you have highlighted the item
you want, press the space bar to select it.
To use a popup control, you must first use the Tab key to make it
active, then press the space bar to pop up the menu. Use the up and
down arrow keys to highlight the option you want within the menu,
then press the space bar to select that option.
To use a text box, simply tab until the text box is active, then type
text into it or select the text button if there is one within or next to it.
This latter method calls up another dialog box allowing you to make
choices that will automatically fill in the text box.
When you are using the keyboard, it is particularly helpful to use
shortcuts for the text buttons. Pressing Esc will cancel the dialog box.
Pressing Ctrl-Enter will execute the default text button, whether or
not it is highlighted.
You can also reposition a dialog box if it is in the way of something
you want to see. Press Ctrl-F7 and the border of the dialog box will
begin to flash. Use the arrow keys to move it across the screen.
22 MASTERING FOXPRO

CH. 1

(Pressing PgUp or PgDn will move it immediately to the top or bot¬


tom of the screen, and Home or End will move it immediately to the
left or right edge of the screen.) Once the dialog box is where you
want it, press Enter, and the border will stop flashing.

WORKING WITH WINDOWS


Most of your work with FoxPro will be done in windows. When
you choose to browse, to add records, to use the Help facility, to write
a program, to edit a text file, or to do most of the other things that the
FoxPro menus and dialog boxes give you access to, FoxPro will open
a window on the screen to let you do it.
You can open many windows at the same time. For example, if
you want to look at two databases, write a program that uses them,
and take notes on what you are doing, you can have all the windows
that you are using visible on your screen at the same time.
A newly opened window will generally be in front of any windows
that are already open. If a number of windows are visible, you can
work on the frontmost window only. You can recognize the front-
most window because only it has the mouse controls along its bor¬
ders. (These controls will be presented in the following section.) The
mouse controls appear regardless of whether you are using a mouse.
Of course, you can also recognize the frontmost windows because
actions you perform occur within it.
Hidden windows If a window is in your way, you can hide it temporarily, without
listed on the popup
are numbered, beginning
closing it, by selecting Hide from the Window menu. When you hide
with zero. These num¬ a window, its name is added to the bottom of the window popup; you
bers translate into hot can make it visible again simply by selecting its name from the
keys that are particularly
popup.
convenient for people
using the keyboard. For You can also get windows out of your way by bringing the window
example, to make the first you want to work in to the front. If you are using a mouse, just click
hidden window on the list
anywhere on a window to make it frontmost. If you are using the key¬
reappear, just press
Alt-W to pop up the board, select Cycle from the Window menu. This brings successive
Window menu, then windows to the front: keep selecting Cycle until the window that you
press 0 to unhide the want to work in is frontmost.
window.
There is also a shortcut that lets you hide or show all of your win¬
dows at once. Hold down Shift when you select the Window menu
pad—either by pressing Shift-Alt-W or by pressing Shift when you

CfC LF ' PMV ffilM


towts evt
GETTING ACQUAINTED WITH FOXPRO 23

make the selection with the mouse—and the Window menu popup
will display the Hide All and Show All options instead of its Hide
option. (Similarly, if you hold down Shift when you select the File
menu pad, the popup will include a Close All option.)

SPECIAL WINDOW
CONTROLS FOR MOUSE USERS
The descriptions of windows that you have read so far apply to
both mouse and keyboard users. If you are a mouse user, FoxPro
windows are particularly easy to manipulate, because of the special
controls on their borders.
Figure 1.10 shows the Command window (looking a bit larger
than usual) with the names of all the features that you find in window
borders. The figure also shows the menu popup, for your conven¬
ience when you read the more general discussion of using windows.

Systorn Database^ Record Program Window

close box

Figure 1.10: Features for using windows.


24 MASTERING FOXPRO

CH. 1

Mouse users can control windows using the following features.

• title: You can move a window by putting the pointer on the


tide, holding the mouse button down, and dragging. When the
window is where you want it, release the button.
• close box: Click the close box in the upper left corner to close a
window. (You can also close a window by pressing Esc,
which is sometimes easier than clicking the close box.)

• zoom control: Click the zoom control in the upper right cor¬
ner to “zoom” a window—that is, to make it fill the entire
screen. Click the zoom control again to return it to its pre¬
vious size.

• size control: To change the size of a window, put the pointer


on the size control in the lower right corner, hold down the
mouse button, and drag. When the window is the size you
want, release the mouse button.

• scroll bar: If the display is too long or too wide to fit in the
window, a scroll bar made up of two arrows and a diamond
appears. To move up or down through a file, click the up or
down arrow on the right border of the window. The position
of the diamond, called the thumb, indicates where in the file
the cursor is. The closer the thumb is to the up or down
arrow, the closer the cursor is to the beginning or end of the
file. To move quickly through a file, use the mouse to drag
the thumb. If the display is too wide for the window, a scroll
bar also appears on the bottom border, and is used in the
same way.

CONTROLLING
WINDOWS WITH THE KEYBOARD
If you are using a keyboard, you can control windows by using the
Window menu options, or the hot keys that appear next to some of
the menu options. If you do something frequently enough, you will
learn the hot keys without any effort, and then you will be able to
work just about as quickly as someone with a mouse.
GETTING A CQUAINTED WITH FOXPRO 25

• Move: To change the location of a window on the screen, select


Move from the Window menu. The window border flashes to
show that it is ready to be moved. You can use the arrow keys
to move it gradually across the screen, or use PgUp, PgDn,
Home, or End to move it directly to the top, bottom, left, or
right edge of the screen. When the window is where you want
it, press Enter and the border will stop flashing.

B Since only the bot¬


tom and right bor¬
• Size: To change the size of a window, select Size from the
Window menu. The window border flashes to show that it is
ders of a window move ready to be resized. You can use the arrow keys to adjust the
when you are resizing it, bottom and right borders of the window and make it larger or
the window is not always
exactly where you want it
smaller. When it is the size you want, press Enter and the
after you resize it. It is border will stop flashing.
best to resize the window
first and then move it if • Zoom: If you select Zoom from the Window menu, the win¬
vou want to do both. dow will expand to fill the entire screen. If a window has
already been “zoomed” to fill the whole screen, selecting
Zoom will return it to its previous size.

• Scroll: As long as the window’s border is not flashing (from


choosing an option from the Window menu), the arrow keys
and the PgUp and PgDn keys will allow you to scroll through
the contents of a window.

• Close: To close the currently active window, simply press Esc.

HOW TO USE THE EDITOR __

The FoxPro editor is very elegantly designed, and its basic opera¬
tions are very easy to learn.
Most keys are used in the ordinary way—the character keys to
enter text (of course), the Del key to delete the character the cursor is
on, the Backspace key to delete the character to the left of the cursor,
and so on.
The Ins key is used in the conventional way, to toggle back and
forth from insert mode to type-over mode. When you begin typing,
you are in insert mode: anything you type will be inserted to the left
of the character that the cursor is on, and everything after that char¬
acter will be pushed to the right to make room for it. If you press Ins
26 MASTERING FOXPRO

CH. 1

to toggle into type-over mode, anything you type will write over and
replace existing text, character by character. When you are in type-
over mode, the cursor becomes large, a warning that existing text can
be lost.
The cursor movement keys are also used conventionally. The
arrow keys move one character to the left or right or one line up or
down. The Home key moves the cursor to the beginning of the line it
is on, and the End key moves it to the end of the line. PgUp and
PgDn scroll up and down through text a window at a time. Of
course, you might prefer to use the mouse to move through the text.
Remember that the text will always be in a window, so you can use
the scrolling techniques mentioned in the previous section.
All these ways of using the editor are very common. The uncom¬
mon thing about the FoxPro editor is the way it uses the cursor move¬
ment keys in combination with Ctrl and Shift. These key movements
are summarized in Table 1.1. In general, Ctrl magnifies movements,
and Shift marks text as you move.
a Ctrl is not used with
the up and down
Looking at the table, you can see that holding down Ctrl when you
move the cursor makes it go further. For example, the right and left
arrow keys, as PgUp and
PgDn serve the same
arrow keys by themselves move the cursor one character to the right
purpose. or left; Ctrl plus those keys makes it move a whole word to the right or
left. Home and End by themselves move the cursor to the beginning
or end of a line; Ctrl-Home and Ctrl-End move it to the beginning or
end of the document.
In addition, since Backspace by itself deletes a character, Ctrl-
Backspace deletes a word. However, Ctrl has no special effect with Del.
If you decide after
Holding down Shift when you move the cursor marks text, mak¬
releasing the Shift
key to continue to mark
ing it appear in reverse video; this is sometimes called selecting text.
text, you can simply hold You can use Shift in combination with the arrow keys, Home, End,
down the Shift key again PgUp, or PgDn to mark text. You can also use Shift in combination
and move the cursor
further. Be sure you hold
with the extended cursor movements (those using the Ctrl key). For
down Shift first, though, example, since Ctrl-End moves the cursor to the end of the docu¬
or else moving the cursor ment, Shift-Ctrl-End moves it to the end of the document and marks
will unmark all the text
all the text along the way.
you have already marked.
You can also mark text using a mouse. Position the pointer where
you want the marking to begin, hold down the mouse button, and
drag to mark the text; when you have marked all the text you want,
release the mouse button. To unmark text, place the pointer any¬
where outside the marked area but inside the window, and click.
GETTING ACQUAINTED WITH FOXPRO 27

Table 1.1: Cursor Movement Using the FoxPro Editor

Key Effect

Home moves to the beginning of the line

End moves to the end of the line

Left Arrow moves one character left

Right Arrow moves one character right

Up Arrow moves one line up

Down Arrow moves one line down

PgUp moves one window up

PgDn moves one window down

Ctrl-Home moves to the beginning of the text

Ctrl-End moves to the end of the text

Ctrl-Left Arrow moves one word left

Ctrl-Right Arrow moves one word right

Any of these keys or key combinations can be used with Shift to mark
text as you move the cursor.

Apart from these simple mouse operations, there are other shortcuts
for marking text with the mouse, shown in Table 1.2.
Pressing the space After you have marked it, you can perform operations on the
bar or any character entire block of marked text. One of the notable consequences of this is
might also delete all
that if you press Del or Backspace, the editor will delete all the
marked text. If you mark
text by mistake, be sure marked text. The easy way to delete all the text from the cursor to
to unmark it by pressing the end of the line, then, is to press Shift-End to mark the text to the
a cursor movement key
end of the line and then press Backspace to delete it. The easy way to
or by using the mouse
before you resume typ¬ delete all the text from the cursor to the end of the document, simi¬
ing. Fortunately, if you larly, is to press Shift-Ctrl-End to mark the text and then press Back¬
do delete text by mistake,
space to delete it.
you can recover it by
selecting Undo, discussed
To unmark text, press any cursor movement key (Home, End,
below. PgUp, PgDn, or one of the arrow keys) without holding down the
Table 1.2: Shortcuts for Marking Text with the Mouse

Purpose Method

to mark a word place the pointer on the word and


double-click

to mark a line place the pointer on the line and


triple-click

to mark text word by word double-click and drag

to mark text line by line triple-click and drag

to mark a segment of text Shift-click the cursor then Shift-click


at another location to select all the
text between

to unmark a segment of text Shift-click within the marked text


at the point where you want the
marking to end

Shift key. The cursor will move and the marking of the text will
disappear.

THE EDIT MENU


FoxPro enables you to perform more complicated editing opera¬
tions by means of the Edit menu. Two of these operations, “cut and
paste” and “copy and paste,” take advantage of the marking tech¬
niques you just learned.
Cut and paste lets you take a block of text that you have marked,
cut it out of the place where it is, and then put it wherever you want
it. Copy and paste lets you leave the marked text where it is and also
put a copy of it somewhere else.
To use these features of the editor, all you have to do is to select the
Edit menu pad (using the mouse or the keyboard) when text is
marked, and select either Cut or Copy from the Edit popup. Then
you move the cursor to the place where you want the text to be
placed, select the Edit menu pad again, and select Paste from the Edit
GETTING ACQUAINTED WITH FOXPRO 29

popup. That’s all there is to it. (As you get used to using FoxPro, you
will naturally begin using the Ctrl shortcut keys to do these things,
speeding up the operation even more.)
One other pair of features of the Edit popup that you will find very
handy in circumstances that are not always possible to avoid are the
Undo and Redo features. If you make an error, such as deleting a
large block of text by mistake, select Undo from the Edit menu
popup. This will undo the last editing action you made, restoring the
text to the state it was in before you made the error.
You can continue to choose Undo to undo all the past editing
actions that you made during the current work session, one at a time,
starting from the most recent and working back to the first.
If you use Undo by mistake, then you can select Redo from the
Edit menu popup to recover the editing action that you undid most
recendy.
You have now learned enough about the FoxPro editor to use it for
most practical purposes. You will be using this editor throughout
FoxPro for entering data, entering commands, writing programs,
writing text files, and so on.

WORKING WITH
THE COMMAND WINDOW
a Remember that the
Command window
_

As you have seen, the Command window lets you enter the sort of
procedural commands used in earlier dBASE compatible programs
behaves a bit differently
from most FoxPro win¬
rather than having you work through the menu system. You also
dows. You cannot close it know that the procedural commands are generated in the Command
by pressing Esc. In addi¬ window when you do use the menu system.
tion, it is not added to the
This sort of procedural command was the only thing available in
list of active windows at
the bottom of the Win¬ the days of the dot prompt, but there are still reasons to use it in this
dow menu popup when it era of the pop-up menu and mouse.
is hidden. To unhide it,
It is sometimes easier to enter commands than to make selections
you simply reselect it
from where it is always
from the menu system—particularly when you are performing a
listed: in the Window repetitive task—since you can edit and reenter commands that you
menu’s third group of already used. A list of all the commands you have entered or gener¬
options.
ated by using menus remains available in the Command window
throughout your work session. You can use the up arrow key (or the
mouse) to move the cursor to earlier commands, even to those that
30 MASTERING FOXPRO

CH. 1

have scrolled beyond the top of the window. Once you have found
the command that you want, just press Enter to reuse it as is. At that
point the command will be executed and the cursor will return to the
bottom of the list, where a copy of that command will be added. If
you want to use a variation on the command, you can edit it first,
using any of the editing techniques you just learned, and then press
Enter to execute it and add it to the list in its revised form.
Of course, if you ever want to do any programming, you must also
learn these commands, since a program is, in large part, a list of these
commands.
For these reasons, this book will begin by using the menu system to
enter commands but will also mention the procedural commands
that are generated in the Command window, so that you can learn
both. For now, you should try entering a couple of procedural com¬
mands in the Command window, just to get an idea of how it works.
You may find the FoxPro command RUN very helpful in your
work: this is a utility that lets you use any DOS command directly
from within FoxPro. In the example, you will use the command

RUN DIR

to get a DOS directory from within FoxPro. Of course, you can also
use RUN with other DOS commands—for example,

RUN FORMAT A:

to format the disk in the A drive. You will also use the FoxPro com¬
mand CLEAR, which, like Clear from the Window menu, clears the
screen or the contents of the current output window. You will notice,
when you enter these commands, that they do not apply to the Com¬
mand window itself.

1. You should already have started FoxPro, and the cursor


should be in its initial position in the Command window. If it
is not, press Esc until you have gotten out of the menu system
and returned to the Command window. If, for some reason,
the Command window is no longer on the screen, select
Command from the Window menu to make it reappear.
GETTING ACQUAINTED WITH FOXPRO 31

While it runs, Fox¬ 2. Type RUN DIR and press Enter. FoxPro will display a DOS
Pro sometimes
directory similar to the one illustrated in Figure 1.11. (Of
creates and uses tempo¬
rary files whose names course, your directory will not be exactly like the illustration.)
are made up of random
3. Type CLEAR and press Enter to clear the screen.
numbers and letters and
which have no extension;
you can see one in the
illustration of the direc¬
| System File Edit 1Database Record 1 Window
tory listing. Do not delete PROWORDS FXD 5440 11:10a
10-20-89
these files while you are in FX2W0RDS FXD 1039 3-01-87 9 : 06p
FXDPRT FXD 1860 9-29-89 11:57a
FoxPro. Most will be FOXVIEW 000 57856 9-07-89 2 : 47p
FOXVIEW 001 46336 9-07-89 2 : 48p
deleted automatically FOXVIEW 002 57088 9-07-89 2 : 49p
FOXVIEW 003 41984 9-07-89 2 : 48p
when you quit FoxPro; if
0104-3844 2362 12-04-90 1 : 08a
any are left, you may FOXVIEW COM 38877 12-04-90 2:13a
FOXVIEW MSG 22528 9-07-89 1 :57p
delete them while FoxPro DEMO DBF 1171 5-27-88 10:12a
FOXVINST PRG 2745 9-21-89 6 : 44a
is not running. FVBRAND COM 11568 5-27-88 1:38p
FVDEMO BAT 973 6-17-88 4: 30p
FOXVIEW BAK 1458 12-04-90 2 : 12a
FOXVIEW CFG 1454 12-04-90 2:13a
TEMPLCOD <DIR> 12-04-90 2:15a
FOXHELP FPT 851127 11-09-89 1 : 22p
FOXHELP DBF 18589 11-09-89 1 : 22p
FOXGEN COM 64968 5-27-88 9:33a
FOXBIND EXE 39840 3-09-89 2 : 23p
FOXBIND RSC 23993 8-30-88 3 : 56p
54 File(s) 1588544 bytes f ree

Figure 1.11: Using FoxPro to get a DOS directory.

4. Now, try getting a directory of just program files with the


extension .EXE by using the DOS command

DIR *.EXE
Rather than typing the entire command

RUN DIR *.EXE


edit the earlier RUN DIR command, using the editing tech¬
niques you just learned: press the up arrow key twice to move
up to the line where the earlier directory command is; press
End to move to the end of the line; then type a space and
*.EXE and press Enter.

Notice that the command, in its edited form, is added to the end of
the list of commands in the window and that the new DOS directory
appears, as in Figure 1.12.
System File Edit Database Record Program Window
Volume in drive C has no label
Directory of C:\FOXPRO

FOXUNPAK EXE 26870 10-25-89 2 : 57p


FOXPRO EXE 325560 11-16-89 5 : 00p
FOXDOC EXE 82848 11-06-89 12:07 p
FOXBIND EXE 39840 3-09-89 2 : 23p
4 File(s) 1380352 bytes free

Figure 1.12: Editing the earlier directory command.

You can imagine how valuable the ability to edit and reuse com¬
mands can be if, for example, you are copying a large number of files
with slighdy different names. There are many cases where it is easier
to use and reuse commands than to repeat the same series of menu
choices over and over again.

OTHER FEATURES _

That takes care of all the major features of the FoxPro interface,
but there are a few smaller ones that you should know about.

• Esc: Pressing the Esc key interrupts any FoxPro command or


program (except for commands that could destroy data if
they were interrupted). After you press Esc, FoxPro will give
you the choices Cancel, Suspend, and Ignore. Choosing
Cancel, which is the default option, stops execution of the
command or program completely. Choosing Suspend stops
execution of the command or program temporarily, but lets
you start it again by selecting Resume from the Program
menu or by entering RESUME in the Command window;
GETTING ACQUAINTED WITH FOXPRO 33

this choice is only useful when you are debugging programs.


Choosing Ignore makes FoxPro ignore the fact the Esc was
pressed; thus FoxPro continues executing the command or
program.

• “talk”: When you make certain menu choices or use certain


commands, what is called “talk” appears on the left side of
the screen. For example, if you use certain commands to
move around the database, the talk will serve as a status
reporter telling you the number of the record you are cur¬
rently on. However, if there is a window covering the area at
the left of the screen where the talk appears, you will not be
able to see it until you close the window.

a With Version 1.01


of FoxPro, you can
Ordinarily, talk appears at the lower left of the screen,
where it is not likely to be hidden by a window. If you enter
CLEAR, though, talk will appear at the upper left, where it is
start the program without
displaying the FoxPro more likely to be hidden. In general, though, talk is not as
logo, using the command important now as it was in the days of the dot prompt, when
FOXPRO -T. If you do
it was often the only way of knowing what was happening;
this, there is no need to
enter CLEAR initially. now there is rarely any need to see it, but it can be helpful.
As a result, talk is less
• alerts: An alert may appear on the screen if you tell FoxPro to
likely to be hidden.
do something that is impossible or that will destroy data. The
alert is in a large box that is impossible to ignore, and its mes¬
sage is generally self-explanatory. Heed its advice if you con¬
sider it to be relevant. To make the alert disappear, click the
mouse button or press any key except for a function key,
Shift, Ctrl, or Alt. Then continue what you were doing.

• system messages: Like an alert, a system message is a box that


gives you information about an action you have performed.
Unlike an alert, it is not a warning or error message. For
example, in Chapter 4, you will learn to check if an expres¬
sion that you are using is valid. The box that tells you it is
valid is a system message rather than an alert. Alerts actually
interrupt what you are doing, since it could be destructive,
and you must remove them explicitly, by clicking the mouse
or pressing a key, as you just saw. A system message does not
interrupt you. If you go on with what you were doing, it will
disappear. »
34 MASTERING FOXPRO

CH. 1

The preceding informadon on the Esc key and on “talk” tells you
what FoxPro does by default. As you will see in Chapter 7, it is pos¬
sible to disable either of these features by using the View window or
by entering the command

SET ESCAPE OFF

or

SET TALK OFF

and it is possible to enable them again by using the View window or


the commands

SET ESCAPE ON

or

SET TALK ON

In general, though, you should not disable these features unless you
are a programmer setting up foolproof systems for end users. When
you are using FoxPro yourself, it is always best to have escape on and
talk on, as they are by default.

a Help will not be


available to the
GETTING HELP
The Help window explains all the elements of the FoxPro lan¬
guage. Though you will not have many occasions to use the Help
extent described here if
when installing the pro¬
window at first, you will find it very useful to browse through it once
gram you elected to save you become a more advanced user. It is worthwhile taking a moment
disk space by not install¬ to see how it works.
ing the Help file.
Selecting Help from the System menu lets you use the Help win¬
dow. The Help window displays a list of topics, including commands
and functions, which are listed in ASCII order (excepting the intro¬
ductory READ ME file, which gives you information for using the
Help window). The beginning of the list can be seen in Figure T13.
You can scroll through the list of topics and use the default text but¬
ton to get complete information on any topic you like.
GETTING A CQUAINTED WITH FOXPRO 35

Figure 1.13: The beginning of the list of topics in the Help window.

Once the list of topics is displayed, you can also type the first letter
or the first few letters of a command, and FoxPro will immediately
move the cursor to the first topic beginning with those letters. You
will be doing this in the next exercise.
One remarkable feature of FoxPro is that you can use the editor to
copy commands out of the Help window and then paste them into the
Command window. This feature is particularly useful when you are
working with a complex command whose exact syntax is difficult to
remember. You should try a simple example now to see how it
works. In the following exercise, you will copy the CLEAR command
out of the Help window and use it to clear the screen again.

1. Select the System menu pad and select Help from the menu
popup. A list of topics—commands, functions, and operators—
will appear. Notice that the command HELP was generated in
the Command window when you made the menu selection. Of
course, you could have bypassed the menu by typing HELP
direcdy into the Command window.

2. Zoom the window (by clicking the zoom control or selecting


the Zoom option from the Window menu popup) so you can
see more of the topic list.
36 MASTERING FOXPRO

CH. 1

3. Type C to move the highlight to the first topic beginning with


C. Then press the down arrow to move the highlight to the
command CLEAR. To get help with that command, select
the default text button (Help) either by clicking it with the
mouse or by pressing Ctrl-Enter. You will see a list of
the different forms of the command and the beginning of the
explanatory text (shown in Figure 1.14), which you can scroll
through using the usual editing keys if you want to read it. You
will also see three text buttons at the bottom of the window:
selecting Topics takes you back to the list of topics, and selecting
Next or Previous takes you directly to the next or previous top¬
ic’s Help screen.

System File Edit Database Record Program Window


1 HELP =
CLEAR N . - ' ]

Formats:

CLEAR
CLEAR ALL
CLEAR FIELDS
PI PAD
LLtAK PPTQ
bt1O
s
CLEAR MEMORY
CLEAR MENUS
CLEAR POPUPS
CLEAR PROGRAM
CLEAR PROMPT
CLEAR TYPEAHEAD
CLEAR WINDOWS

CLEAR

The CLEAR command without arguments erases the screen or the current output

« lopics » < Next > < Previous >

Figure 1.14: The Help window for the command CLEAR.

4. For now, you just want to use the editor to copy the simplest
form of this command. Move the cursor to the word CLEAR
in the Formats list. Then hold down Shift and press End to
mark the word. Select Copy from the Edit menu to copy the
marked text. Then Press Esc to close the Help window (or
click the close control with the mouse).
GETTING A CQUAINTED WITH FOXPRO 37

5. When the Help window disappears, the cursor should be on


a blank line in the Command window, under the command
HELP. Select Paste from the Edit menu, and the word
CLEAR, which you just copied, will appear there.
6. Press Enter to execute this command. It will clear the screen
of the directory listing that was there.

QUITTING

B Always quit FoxPro


when you are done
with a session. It you
To quit FoxPro and return to DOS, simply select Quit from the
File menu. Notice that the command QUIT appears in the Com¬
simply turn off the com¬
mand window before FoxPro terminates. Of course, you can also
puter without quitting type QUIT directly into the Command window to leave FoxPro.
first, you can lose data.
Creating a
Database Structure
MHHWBHM

To create a database file using the menu system, 43


select New from the File menu popup. The Database radio but¬
ton should be selected by default; if not, select it. Then select
the OK text button to use the Structure dialog box, which lets
you define the database file’s structure.

To create a database file using the Command window, 44


enter CREATE Kfile name>. The Command window lets you
name the file when you begin to create it, unlike the menu sys¬
tem, which gives it the name UNTITLED until you save it.

To name a field, 46
use up to ten characters, including letters, whole numbers, and
the underscore character. The name must begin with a letter,
and FoxPro does not distinguish between capital and small let¬
ters in held names.

To select the data type of a field, 47


use the Type popup control to place the data type in the Type
column of the current held, or simply enter the hrst letter of the
data type in that column. The rest will be filled in automatically.

To change the field width, 52


edit the number that appears by default in the Width column
when you select the data type. Numeric and boat helds let you
edit the number of decimal places as well: you must allow for
the decimal point itself when you determine their width. You
cannot change the widths of logical helds (width 1), date helds
(width 8), and memo helds (limitless, though they display a
width of 10).
To save the database file, 56
select the OK text button from the Structure dialog box, and
a dialog box appears that lets you name the new file. Select
the directory you want from the scrollable list of existing files
and directories. Then enter the name for the new file in the text
box of this dialog box, or select the name of an existing file from
the scrollable list to overwrite the existing file.

To move among DOS subdirectories, 57


select [.. ] from the scrollable list of file names to move to the
parent directory of the current directory. This scrollable list also
contains the names of all the subdirectories that are under the
current directory, and you can select one of those to move to it.
Since DOS has a hierarchical directory structure, you can ulti¬
mately move to any directory by selecting the parent or child
directory of the current directory in this way.

To open a database file, 62


select Open from the File menu and select a database file from
the dialog box that appears; or enter USE Kfile name"> in the
Command window. As long as it is open, the file persists—even
if you cannot see any indication of it on the screen.

To close an open file, 63


enter the command USE without any file name following it.

To modify the structure of a database file, 68


select Setup from the Database menu, then select the Modify
text button from the Setup dialog box. The Structure dialog
box appears, just as it did when you were first defining the
structure. Modify the structure displayed here by editing it.
BEFORE YOU CAN WORK WITH A DATABASE FILE, YOU
must define its structure. You have to decide exactly what fields you
want to include in the file.
Defining the structure of a database is a bit like designing the pre¬
printed form that you would use if you were working with paper files.
You would have to decide, for example, that your index cards would
have blank spaces for name, address, phone number, and so on.
When you are working with a computerized database, you do not
have to decide on only one arrangement for your data. For example,
in Chapter 3, you will look at the same data arranged in two different
ways: first with one field above another, and then as a table, with the
fields arranged from left to right. (You will also learn in Chapter 9 to
create custom data screens, so that you will be able to arrange the
fields of a database in any way you want.)
On the other hand, you do have to define, or specify, in advance
exactly what fields will be in your database file, and here you must be
even more precise than you are when you work with paper files.
Since you cannot write with small letters to squeeze in a long name
when you are working on a computer, you have to define the maxi¬
mum number of characters for each field. You must also define what
sort of data can be entered in each field, since some fields (as you will
see) can hold only numbers, logical values, or dates.
In this chapter, you will define the structure of a database file that
will be used as an example throughout this book and which will illus¬
trate the different data types that are available in FoxPro.

CREA TING A
SAMPLE DATABASE FILE _

The sample database that you will work with in this book is a list of
employees. This database will be a bit like the database file that any
small business might use, but it will be simplified to save you data entry;
for example, it will not include Social Security numbers. The fields that
are in the database will be chosen to illustrate FoxPro’s capabilities,
rather than as an example of an actual business application.
CREATING A DATABASE STRUCTURE 43

HOW TO CREATE A NEW FILE


Before you create the database file itself, you should create a DOS
subdirectory for the work that you do in this book. Later in this chap¬
ter, you will use FoxPro to navigate your way through the subdirec¬
tory system and choose the directory where you want to save your
database file. It is best to create the subdirectory in advance, so at this
point there will be a brief discussion of how DOS subdirectories are
organized. If you do not know how to use DOS subdirectories, sim¬

a The FoxPro Filer


(which is on the
ply copy the following commands to create the subdirectory.
We will work from the Command window to manipulate files,
using the RUN utility plus DOS commands. Many people pre¬
System menu popup)
provides a menu-driven fer using these ordinary DOS commands, but if you do not know
utility that lets you per¬ DOS, or if you prefer a menu-driven operation, just follow these
form operations needed
instructions without trying to learn the DOS commands. You can
to manipulate DOS files
study the section on the Filer (in Appendix B) later.

1. If necessary, start FoxPro: first make sure you are in the Fox¬
Pro directory (if you are not, enter CD\FOXPRO), then
enter FOXPRO (or FOXPRO-T with Version 1.01) to start
the program.

2. The cursor should be in the Command window; if it is not,


press Esc until you get back into the Command window. If
necessary, enter CLEAR to clear the screen.

3. To create a new subdirectory for the exercises in this book,


enter
RUN MD \LEARNFOX
(Do not forget to include the space and the backslash before
the directory name.) The FoxPro RUN utility lets you use the
usual DOS command for creating a new directory. The
screen will become blank for a moment while the new direc¬
tory is being created and then will reappear.

4. To create your new database file, select New from the File
menu. FoxPro will display a dialog box with radio buttons to
let you choose what type of file to create, as shown in Fig¬
ure 2.1. The dot in the parentheses next to the word Data¬
base shows that it is the default file type.
44 MASTERING FOXPRO

CH. 2

Figure 2.1: Creating a new database file.

5. Select the default text button, OK, to create a database file.


Remember that you can select the default text button either
by clicking it with the mouse or by pressing Ctrl-Enter. (In
later chapters, you will use this same dialog box to create
reports, mailing labels, and other types of files simply by
choosing the different radio buttons.)

The Structure dialog box appears, as illustrated in Figure 2.2, to


let you define a new database.
Notice that this dialog box has the heading ‘'Structure: Untitled”

a Discussions of Fox¬
Pro commands
in its upper left corner. Though the Command window is partly cov¬
ered now, you will notice later that the command CREATE Untitled
has been generated.
usually use angle brackets If you were working from the Command window, you could have
to indicate words that must created a new database file simply by entering CREATE plus the
be filled in. CREATE
Kfile name>, for example, name you want the database to have. When you work from the menu
indicates that you would system, however, the file initially has the name Untitled, and you
enter the word CREATE give it an actual name only when you save it. The command
followed by whatever name
you use for the file. Do
CREATE <file name> is used only to create database files. When you
not type the brackets enter a new file name in this manner, the program automatically
themselves. adds the extension .DBF to the name you give the hie.
CREATING A DATABASE STRUCTURE 45

System File Edit Structure

Figure 2.2: Defining a new database structure.

You should also notice that the menu bar has changed. Only the
menu pads for System, File, and Edit are left from the original menu
bar, and a new menu pad for Structure is added to their right.

HO W TO DEFINE THE
STRUCTURE OF A DATABASE
As you can see, the Structure dialog box has columns headed
Name, Type, Width, and Dec (for number of decimal places). To
define the database structure, you simply fill them in for each of the
fields in your database file. The first line describes the first field in
each record, the second line describes the second field, and so on.
Normally, you simply fill out the field definitions in sequence, from
the first in each record to the last, but it is possible to move among the
fields—for instance, to make changes in a definition before saving it. To
do this from the keyboard, use Tab to move one column to the right (or,
if you are in the last column, to the first column of the next line), or
Shift-Tab to move one column to the left. Use the up and down arrow
keys to move up and down the list. Of course, you can also use the
mouse to move the cursor.
46 MASTERING FOXPRO

CH. 2

You can use the Insert text button in the dialog box to insert a new
field or the Delete text button to eliminate a field you already typed.
You can also insert or delete fields via the Structure menu popup. In
fact, if you select the Structure menu pad, you will see that the only
two options on the Structure popup are Insert Field and Delete Field,
as shown in Figure 2.3. (These options offer the hot keys Ctrl-I and
Ctrl-D; for keyboard users, this is faster than using the text buttons.)
You will use the Structure menu popup later in this chapter when
you are modifying the structure of a database.

Figure 2.3: The Structure menu with the Structure dialog box.

B A field name cannot


include any spaces.
A field name may have up to ten characters: these characters may
include the letters from A to Z, whole numbers, and the underscore
For this reason, if you
have a field name made
character (_), but the field must begin with a letter. Field names do
up of more than one not distinguish between upper and lowercase letters, so FoxPro auto¬
word, it is a good idea to matically capitalizes the name when you enter it. Of course, you can¬
use the underscore char¬
acter (_) to separate
not use two fields with the same name in the same file. Table 2.1
words, which makes them gives examples of a few valid and invalid field names, to illustrate
easier to read. these rules. You should note that a field name’s validity is not of itself
sufficient to ensure its usefulness. A useful field name will also tell you
about the contents of that field.
CREATING A DATABASE STR UCTURE 47

Table 2.1: Valid and Invalid Field Names

Field Name(S) Valid or Invalid?

Z valid

2 invalid because it begins with a number

UP_DOWN valid

_NAME invalid because it begins with an underscore

CITY_STATE_ZIP invalid: more than ten characters

ADDRESS_1 both valid and may be used in same file


ADDRESS_2

NOTES may not be used in same file, as both have


notes the same name (case differences—i.e.,
lowercase, uppercase—are ignored)

When you begin to enter a field name, Character and 10 are auto¬
matically filled in under Type and Width respectively. You can
change the type by using a popup; the width changes automatically
depending on the type you select. The data types and their default
widths are summarized in Table 2.2.

Table 2.2: Data Types and Their Defaults

Default
Data Default Decimal Change
Type Width Places Defaults?

Character 10 n/a yes

Numeric 8 0 yes

Float 8 0 yes

Date 8 n/a no

Logical 1 n/a no

Memo 10 in .DBF file n/a no


48 MASTERING FOXPRO

CH. 2

DATA TYPES
The Type column must contain one of FoxPro’s six data types.
The data type you choose determines what you can enter into the
field.

• Character: may contain any of the characters on the keyboard,


including letters, numbers, and special characters (such as &
or *). DOS also includes an extended set of special characters,
including box-drawing characters and foreign characters with
accent marks; character fields can hold any of these. FoxPro
character data may include any eight-bit value, including the
null character (ASCII character 0); thus advanced users can
use character fields to store virtually any data, including
binary data. The maximum width of a character field is 254
characters.

FoxPro uses only 16 • Numeric: may contain numbers and a decimal point, and
significant digits may also begin with a + or - sign. The maximum width of
internally and rounds
numeric data wider than
a numeric field is 20 characters. The decimal point and + or
this. Though these are - sign each take up one place, so you must take them into
more than enough signi¬ account when you define the field width. If you want a field
ficant digits for most
to hold amounts of money less than one thousand dollars, for
business uses, there are
many scientific or statisti¬ example, it must be six places wide: three for the dollar
cal calculations where amounts, one for the decimal point, and two for the cents.
rounding might create
Add an extra place if you want to indicate + or - amounts.
errors. When in doubt
about potential rounding Note that a field that has a decimal point and a leading + or
errors, use the Float type. - sign can hold a maximum of 18 numeric digits (20 maxi¬
mum minus 2).

• Float: like numeric, may contain numbers, a decimal point,


and a leading + or - sign, and can hold up to 20 characters.
The float data type is designed for scientific calculations,
since it stores more significant digits internally. It is not com¬
monly used.

• Logical: may contain only the values T or F, to indicate true


or false. However, when you are entering data you may enter
Y (for yes) or N (for no) as well as T or F, and the entry will
be read as a logical true or false. Furthermore, any of these
CREATING A DATABASE STRUCTURE 49

characters may be entered as upper or lowercase letters. This


type, then, makes it easy to enter true and false or yes and no
responses.

• Date: includes date numbers and the slash character to sepa¬


rate them—for example, 10/02/91. The date field itself is
always eight characters wide, though it can be displayed with a
four-character year—for example, as 10/02/1991. Dates can
also be displayed and managed in European format (with the
day first) or in ASCII format (with the year first). In Chap¬
ter 4, you will learn about special functions that let you print
the contents of date fields in character form—for example, to
print out the name of the month.

• Memo: may contain any amount and type of data. The only
limit to the length of a memo field is the amount of disk space
you have. Like a character field, a memo field may include
the null character and binary data; thus advanced users can
use FoxPro memo fields to hold types of data that could never
before be manipulated with database management pro¬
grams, such as scanned images or digitized sound. In ordi¬
nary uses, memo fields act as variable-length character fields,
and they can be manipulated using any of the functions that
are used to manipulate character fields.

For every field you define, there is space taken up on the disk for the
entire width you specify, even if there is little or no data in the field.
Certain fields have unalterable widths: the logical type will always be
one character wide, and the date type will always be eight characters
wide. Memo fields, though they can hold any amount of data, are
automatically defined as ten characters wide. The ten spaces reserved
for it in the database file are just used to point to the location in a sepa¬
rate, variable-length file where the actual data for that field is kept.
When you are entering data, the memo field at first appears to be only
ten spaces long, but if you press Ctrl-PgDn when the cursor is on that
field, you open a special memo window, as illustrated in Figure 2.4, to
allow you to enter any amount of text (or other data); closing the
memo window returns you to ordinary data entry.
50 MASTERING FOXPRO

CH. 2

Figure 2.4: A memo window.

Because a memo Database files automatically get the extension .DBF (which stands for
field is not kept in
database hie). For example, when you name your sample employee list
the same file as the rest
of the database, there is a
file EMPLIST, it will be stored with the name EMPLIST.DBF. Fox¬
danger of losing your Pro memo files are given the extension .FPT (for FoxPro text). When
memo data when you are you create your EMPLIST database later in this chapter, then, it will
copying a database file—
for example, to transfer it
actually be stored in two files: EMPLIST.FPT as well as
to another computer. You EMPLIST.DBF. In earlier dBASE compatible programs, memo files
must be sure to copy the were given the extension .DBT (which stands for database text). These
memo file as well as the
.DBT files could hold only character data.
database file, and the
easiest way to do this is by Since FoxPro memo files can hold any data type-character or
using the DOS wild-card binary—FoxPro can use databases with these older forms of memo
character. For instance, to
field without any difficulty.
copy a database file named
SAMPLE, use the DOS When you are entering the definition of your sample database file,
command COPY SAM¬ you will see that the cursor does not even move to the Width column
PLE. *, which will copy for date, logical, and memo fields, since their widths are preset and
SAMPLE.DBF and
cannot be changed.
also SAMPLE. FPT or
SAMPLE.DBT. No doubt, you have noticed that an actual piece of data can some¬
times go into several different types of field. For example, numbers
can go into character, numeric, or float fields, and dates can go into
date or character fields. The real difference between field types lies in
CREATING A DATABASE STRUCTURE 51

how the data can be used. You can perform numeric calculations, for
example, only on numeric or float fields—not on numbers that are
stored in character fields. In the earliest versions of dBASE, dates
were stored as characters, and there was no date type. As a result, it
was hard to arrange records in order of date. Now that there is a spe¬
cial date type, though, you can not only sort records in order of date,
you can also perform calculations with dates—to find the number of
days between two dates, for example.
When you are defining the structure of a database, it is best to use
the numeric type only for fields that will actually have calculations
performed on them. Beginners are often tempted to define the zip
code field as numeric just because it has numbers in it. Actually,
though, some zip codes—those from foreign countries—contain let¬
ters as well as numbers, and extended zip codes include a dash after
the first five digits. Neither of these could be entered in a numeric
field. Furthermore, because data in a character field can be sorted
alphabetically and by number, it is possible to sort any zip code in
order when Zip is a character field. There is no advantage, then, to
using a numeric field except for the ability to perform calculations.

BREAKING DOWN THE DA TA


The time to think about how much you need to break down the data
for the uses that you are going to make of it is before you create the
structure of your database. When even a very small business comput¬
erizes, entering names and addresses in its mailing list usually takes at
least a week of full-time work for a data entry person (or for an over¬
worked owner). There have been cases where, after the data entry was
done, users decided to print out the names on their mailing list in
alphabetical order—and only then realized that you cannot alphabet¬
ize by last name if the first and last name are in a single field. Some¬
times these people have managed to get by without the alphabetical
listings that they wanted; in other cases they have gone back, redefined

D You usually do not


need a separate field
the database, and spent an extra week redoing all their data entry.
Our sample application in this book will be a simple list of employ¬
ees. As with most lists of names and addresses, it is best to break
for a middle initial, which
you can fit into the same down the name into fields for first and last name, so you can alpha¬
field as the first name. betize records, and also to have separate fields for city, state, and zip,
rather than a single field for all three. In this sort of application, you
52 MASTERING FOXPRO

CH. 2

may well want to list just the people who live in a certain city or a cer¬
tain state, and you usually want to print mailing labels in order of zip
code; you can do these things if you have a separate field for each.
There are costs to creating fields for which you rarely have data—
fields that, in many records, will be empty. For one thing, it takes
data entry time to skip that field and leave it empty. In addition, a
field takes up space on your disk whether there is any data in it or not.
To save disk space, it is best not to create unnecessary fields and not
to make fields wider than necessary.
Balance the advantages and disadvantages of breaking down your
data. When in doubt, it is generally safest to break the data down
more, rather than less.

ENTERING THE FIELD NAMES AND TYPES


Now you are ready to create a new database file by using the Struc¬
ture dialog box that you called up earlier in this chapter, filling it out
with the name, data type, and width of the fields you want. (If you
have quit FoxPro and started it again since reading the beginning of
this chapter, go back to the section entitled “How to Create a New
File” and follow the numbered steps there to call up the Structure
Other keys can
sometimes be used dialog box again before going on with the next set of numbered
to move from one col¬ instructions.)
umn to the other, such as
As you will see, as soon as you begin to fill out each field, FoxPro
Enter to move right and
the left arrow key to move automatically defines the type to be Character and the width to be 10.
left—but they do not Obviously, you will sometimes want to change these default assign¬
work consistently in every ments. You can move from column to column using Tab (or Shift-
column, so it is best to
just get in the habit of
Tab, to move back a column). If you have a mouse, you can click the
using Tab and Shift-Tab word you want to move to, but it is usually quicker to use Tab or
to move among columns, Shift-Tab.
and saving the left and
Once you have gotten to the column you want (the word or num¬
right arrows for editing
purposes. It is good to get ber in it will be highlighted), you can change its contents in one of
used to these keys now, two ways:
since you will find in the
next chapter that FoxPro
• Simply begin to type the contents you want. Any current
works in a similar way
when you are editing the contents will immediately disappear, and the new contents
data in a database file. that you are typing will replace them.
CREATING A DATABASE STRUCTURE 53

• Use the right arrow key to move the cursor. The whole word
will no longer be highlighted; instead, a cursor will appear on
one letter of the word. This allows you to use the ordinary
editing keys to make changes one character at a time.

When you use the first method above to change the data type, all
you have to do is type the first letter of a data type, and FoxPro will
automatically fill in its entire name. If you do not remember all the
data types, you can press the space bar, and a popup will appear to let
you choose among the different FoxPro data types.
The default width will change depending on the data types. If you
choose the numeric or float data type, a default value of zero will
appear for the number of decimal places, but you will be able to edit
it. On the other hand, to accept a default value, just move the cursor
to the next item.

1. Type FNAME in the Name column. As soon as you begin


typing, ‘ 'Character’ ’ appears in the Type column, and “10”
appears in the Width column. These are the default assign¬
ments for these items. A double-headed arrow also appears,
to the left of the name, as shown in Figure 2.5.

System File Edit Structure

Structure: Untitled
Name Type Width Dec
Field
t F Character 10
<Insert>

<Delete)

« OK »

<Cancel)

Fields: 1 Length: 11 Available: 3989

Figure 2.5: The default data type and width appear as soon as you start typing.
54 MASTERING FOXPRO

CH. 2

2. You need to change the width from 10 to 15. When you have
finished typing the field name, press Tab twice to move to the
Width column. Press the right arrow key to change from a
highlight to a cursor, which will be on the first digit. Press the
right arrow key again to move to the second digit, press Del
to delete the zero that is there, and type 5 to replace it. The
number will now be 15.

3. Press Tab to move to the Name column of the next line.


Type LNAME. Press Tab twice to move to the Width field.
This time, instead of using the arrow and editing keys to
change one character in the Width field, simply type 20
to replace the entire number. When you start typing, the 10
will disappear.

4. Press Tab to move to the next line. Type ADDRESS. Press


Tab twice. As the width, type 25. Press Tab to move to the
next line.

5. Type APT_NO. Press Tab twice. As the width, type 5. Press


Tab to move to the next line.
*

6. Type CITY. Press Tab twice. As the width, type 20. Press
Tab to move to the next line.

7. Type STATE. Press Tab twice. Type 2 as the width, and


then press Tab to move to the next line.

8. Type ZIP. Press Tab twice. Type 5 as the width and press
Tab to move to the next line.
B If you have a
mouse, you can use 9. Type DATE_HIRED. The first time through, you should try
it to move to the Type
using the popup to change the data type, to get used to it and
column, use the popup,
and make your selection to give you an idea of another place to find the type names
from it—in the same way listed. Press Tab to move to the Type column, and then press
as you do when you are the space bar to use the Type popup, illustrated in Fig¬
using a menu popup.
ure 2.6. Press the down arrow three times, and then press the
Most people, though,
once they leam the names space bar to select the Date type. Notice that the width auto¬
of the data types, find it matically becomes 8 and the cursor moves to the next line:
easier to use the keyboard
because there is no choice of width for date fields, the cursor
when they are doing this
sort of steady typing. moves down to the next field.
CREATING A DATABASE STRUCTURE 55

System File 'Edit Structure

Structure: Untitled
Name Type Width Dec
Field
FNAME Character 15
LNAME Character 20 <Insert>
ADDRESS Character 25
APT_NO Character 5 <Delete>
CITY Character 20
STATE Character 2
ZIP 5
DATE HIRED ♦Character 0 « OK »
Numeric
Float <Cancel>
Date
Fields: 8 Logical Available: 3897 OX
Memo d
Picture

Figure 2.6: The popup to choose data type.

a In the Width
column of a
10. Type WAGE. Press Tab to move to the Type column. Type
N for numeric type. (The whole word—NUMERIC—is
numeric field you must
count spaces for the
automatically displayed.) Notice that the default width is 8.
decimal point and deci¬ Since we will assume that everyone’s hourly wage is under
mal places if there are to 100 dollars, we need a width of 5: two for the dollar figures,
be any. Thus, the deci¬
one for the decimal point, and two for the cents. Type 5 and
mal places you count for
the Dec column are not press Tab to move to the Dec column. Type 2 and press Tab
additional to the number to move to the next line.
in the Width column.
11. Type PROBATION. This is a logical held to see whether or
not the employee is on probation. Press Tab to move to the
Type column and type L make it a logical held. Notice that
the width is automatically 1. Because you cannot change the
width of a logical held, the cursor automatically moves to
the next line.

12. Type NOTES. Press Tab to move to the Type column and
type M to choose the Memo type. The width of a memo held
is listed as 10, even when it is holding much more than that,
as you will see. There is no need to change it.
56 MASTERING FOXPRO

CH. 2

13. When you choose the Memo type, the cursor moves to the
next line and the list scrolls up to make room for the descrip¬
tion of another field, but we have all the fields we need for this
sample database. The Structure dialog box should look like
Figure 2.7.

14. Scroll up to the top of the list of fields you entered in order to
see if they are all correct. If you made any typographical
errors, correct them in the same way that you changed the
default values—either by typing the new value when the field
is highlighted, or by pressing the right arrow key and then
editing the existing value.

15. When you have confirmed that the definition is right, select
the default text button, OK, either by clicking it with the
mouse or by pressing Ctrl-Enter.

SA VING THE DA TABASE FILE


When you select OK, the dialog box that lets you name the data¬
base appears—including a scrollable list with names of files and

System File Edit Structure

Structure: Untitled
Name Type Width Dec
Field
X ADDRESS Character 25
X APT NO Character 5 <Insert>
X CITY Character 20
X STATE Character 2 <Delete>
X ZIP Character 5
X DATE HIRED Date 8
X WAGE Numeric 5 2
X PROBATION Logical 1 « OK »
X NOTES Memo 10
<Cancel> d

Fields: 11 Length: 117 Available: 3883 OX


d

Figure 2. 7: The structure dialog box with fields filled in. (Not all field names
are visible.)
CREATING A DATABASE STRUCTURE 57

directories, as shown in Figure 2.8. (Of course, your list may look a
bit different from this illustration, depending on what is in your
directory.) The list on the left side of the dialog box lets you navigate
through the DOS directory structure, so you can save your file in any
subdirectory. The place where your cursor is located in this dialog
box is a text box without the box around it, the place for you to type
in the file name. For readers who are not familiar with DOS sub¬
directories, the next section contains a brief discussion of how they
are organized; if you are familiar with DOS subdirectories, skip to
the following section, “How to Save the File.”

System FiLe Ldit. Structure

Name the new database:

►[..] Drive
[TEMPLCOD]
DEMO.DBF
FOXHELP.DBF
FOXUSER.DBF Directory
MONITOR.DBF
M0NIT0R2.DBF
PROINST.DBF «

[ ] All Files

Figure 2.8: The dialog box for naming the new database file.

WORKING WITH THE DOS DIRECTORY STRUCTURE


DOS has a hierarchical subdirectory structure. This means that its
subdirectories are arranged like the organization chart of a typical
corporation, which has the president at the top, a number of vice-
presidents directly under the president, a number of managers under
each vice-president, and so on. This sort of hierarchical structure
lets each directory on your disk have a number of directories below it
but only one directory directly above it; there is one directory at
the top.
58 MASTERING FOXPRO

CH. 2

A directory is sometimes called a child of the directory above it and

a To be even more
complete, you can
a parent of the directories below it. The directory at the top is called the
root directory.
The root directory is represented by the backslash \ symbol. Other
include the disk letter
followed by a colon before directories are referred to by listing all the directories above them,
the directory name. For
beginning with the root directory; each of these directories is sepa¬
example, C:\ is the root
directory of the C disk and rated by backslashes. For example, your root directory has a FOX¬
A:\MISC is the MISC PRO directory under it, which has a TEMPLCOD (Template
subdirectory directly under Code) directory under it. The TEMPLCOD directory is referred to
the root directory of the A
disk. If use several disks—
precisely as \FOXPRO\TEMPLCOD. If TEMPLCOD had a
for example, if you have directory under it named MISC, then the full name of that directory
more than one hard disk— would be \FOXPRO\TEMPLCOD\MISC. Figure 2.9 illustrates
it is good to get in the habit
a directory structure with these directories plus a few others.
of including the disk letter
in the directory name, as it By default, DOS commands apply only to the current directory
will let you access the For example, the command
directory you want no
matter what disk you are
DEL FiLE.TXT
in. Here, we assume that
you work in one disk and
do not need to include the would delete the file named FILE.TXT only if it were in the current
disk letter. directory. You can enter the full directory name, though, to use

Figure 2.9: A directory structure.


CREATING A DATABASE STRUCTURE 59

commands on files in any directory, using the same backslash delim¬


iter to separate the file name from the directory name. For example,

DEL \FOXPRO\TEMPLCOD\MISC\FILE.TXT

would work no matter what directory you are in when you enter it.
Note that a space must follow any command word, but no spaces
should occur within a file name or path.
A useful shortcut is to use two dots to refer to the parent of the cur¬
rent directory. The two dots (periods) stand for the entire name of the

B If you prefer us¬


ing a menu-driven
parent directory of the current directory.
Once you understand how to refer to directories, there are only
method of working with
three basic commands you need to work with them.
files, you can use the
Filer, discussed in Appen¬ • MD stands for Make Directory. MD <directory nameycreates
dix B, instead of these a directory with a given name.
three basic commands for
working with subdirecto¬ • CD stands for Current Directory or for Change Directory.
ries. In either case,
CD <directory name> moves you into the directory you
though, you do have to
understand the hierarchi¬ named.
cal organization of direc¬
• RD stands for Remove Directory. RD <directory name>
tories discussed above, in
order to use FoxPro removes the directory with that name, but it only works if
dialog boxes to navigate that directory has no files in it or subdirectories under it.
through the directory
system.
These commands can use the full directory name or the same abbre¬
viations of directory names as other commands. For example,

RD \FOXPRO\TEMPLCOD\MISC

would remove that directory no matter which directory you were cur¬
rently in. If you were already in the \FOXPRO\TEMPLCOD
directory, though, you could remove it by just entering RD MISC.
That is really all you will ever need to know about DOS directories.
You used MD \LEARNFOX earlier in this chapter to create a directory
to use with this book. You can use RD \LEARNFOX to remove that
directory when you are done with this book and have deleted your
practice files. And you should understand the directory structure well
enough that you will have no trouble moving through it.
60 MASTERING FOXPRO

CH. 2

HOW TO SA VE THE FILE


In the scrollable lists in FoxPro dialog boxes, the names of sub¬
directories that are under the current directory are in square brack¬
ets. A square bracket with two dots in it represents the parent
directory of the current directory. You can move up and down
the directory structure by selecting either the parent or one of the
children directories of the current directory, and you can ultimately
get to any directory on your disk in this way.
The popup control boxes to the right tell you the name of the cur¬
rent disk drive and current directory. The Drive popup control lets
you select the disk you want to save to: for example, you can use it to
select A if you want to save the hie on a floppy disk in drive A. The
Directory popup control will display all the parent directories up to
the root, to let you move up quickly through a complex subdirectory
structure. In the Directory control, FoxPro refers to the root direc¬
tory simply by using the drive letter plus a colon, without the back¬
slash used in DOS.
To move through most directory structures, you just need the
scrollable list, and you can use it to save the new database file in
the \LEARNFOX directory that you created at the beginning of this
chapter.

1. The cursor should be at the lower left of the dialog box called
up by selecting OK from the Structure dialog box. Type
EMPLIST as the name of the database.
2. Move to the list of directories. Select the first item in the list,
[..]. You have now moved from the FOXPRO directory up
to the root directory.
3. This list is alphabetical. Select [LEARNFOX] from it, and a
new scrollable list representing the contents of this directory
appears. Of course, there are no files or subdirectories in this
new directory, just [.. ] to let you move up to the parent direc¬
tory, as in Figure 2.10.

4. Now that you have the proper file name (EMPLIST) and
subdirectory (LEARNFOX), just select the default text but¬
ton, Save, to save the new database file.
CREATING A DATABASE STRUCTURE 61

5. FoxPro will save the file and ask if you want to enter records
now, as in Figure 2.11. Select the No text button. (You can
do this simply by pressing the letter N.)

System File Fdit. Structure

Figure 2.10: Moving around the directory system.

System File Edit. Database Record Program Window

Figure 2.11: FoxPro lets you add records immediately.


In practice, you will find that you often create a database file under
the pressure of necessity, and you will want to enter records as soon as
you are done. For now, though, you should take a few moments to
investigate how the program keeps track of what you are doing.

THE DA TABASE FILE


IN THE BACKGROUND _
You have learned all that you really need to know to create data¬
base files, but it is also useful to look a little deeper. In this section,
you will work from the Command window and do a few things
that you cannot do by using the menu system.
This section is not meant to teach you new techniques. It simply
uses these new techniques to give you a deeper understanding of
what happens more or less ‘ ‘behind the scenes” when you work with
the menus. Therefore, you do not have to try to memorize the com¬
mands in this section. The menu system will be enough for almost all
of your practical work.
You should take a moment to absorb the very important idea that
when a given database file is in use it does not necessarily appear any¬
where on your screen—that it can be hovering in the background and
still be the database file that any operations which you choose from
the menu will be performed on. For exaanple, though it does not
appear on the screen, the database file that you just created is in use.
If you select Edit from the Database menu, for example, this is the
database file that will appear in the Edit window.

OPENING AND CLOSING A DA TABASE FILE


Normally, you use a database file by selecting Open from the File
menu. The database file that you select from the dialog box does not
appear on the screen, but it becomes available and can be manipu¬
lated with the Database or Record popup.
When you select Open, the command USE Kfile namey is gener¬
ated in the Command window. This command is used to open a file
from the command line or from within a program.
CREATING A DATABASE STRUCTURE 63

If a file is already in use, its name will be dimmed in the scrollable


list of files when you select Open, and you will not be able to ‘ ‘re¬
select ’ ’ the file. Another handy way of telling whether a file is in use is
by entering the command DISPLAY STRUCTURE in the Com¬
mand window. This will display the name of the current file and the

a You will see in


Chapter 7 that you
names, types, and widths of its fields.
Normally, only one database file can be in use at a time. If you
open another database file, the current file will no longer be in use: it
can use the View window
to have multiple files in automatically closes and will be replaced by the one you opened.
use at once, a feature that Thus, you rarely need to close a database file when you are working
is used primarily with
through the menu system—you simply use another file.
relational databases. To
do this, though, you must If it happens that you want to close a database file without opening
create a separate work another one, you cannot do so by selecting Close from the File menu.
area for each file. There
That menu option merely closes the current window and does not affect
is always just one file in
use in the current work the database file in the background. If you did it now, it would close the
area. You can also use Command window—but the EMPLIST database would still be open.
the View window to close There is a simple command to close a database file, though. The
database files through the
menu system.
command USE Kfile name>, which has the side effect of closing the
current file as it opens the one you specify, will still have the side effect
of closing the current file if you don’t specify a file to be used. Thus,
the command USE without a file name serves to close the current file.

A BIT OF EXPERIMENTING

Try some experimenting to see what kinds of things can occur in


the background:

1. Select Open from the File menu and note that EMPLIST-
.DBF, the file you just created, is dimmed in the scrollable list in
the Open dialog box. Try to select it, and you will see that it
is impossible: the file is already open. Press Esc to close the
dialog box.
2. Enter DISP STRU in the Command window, and FoxPro
will display the structure of the EMPLIST file, as shown in
Figure 2.12—another indication that this is the current file.

3. Enter USE in the Command window to close the current file


without opening a new one.
64 MASTERING FOXPRO

CH. 2

System trio tdil Database Record Program 'Window

Structure for database: C:\LEARNFOX\EMPLIST.DBF


Number of data records: 0
Date 'of last update : 11/05/90
Field Field Name Type Width Dec
1 FNAME Character 15
2 LNAME Character 20
3 ADDRESS Character 25
4- APT NO Character 5
5 CITY Character 20
6 STATE Character 2 1 Command =1
7 ZIP Character 5 ■ CLEAR I
8 DATE HIRED Date 8 I RUN MD \LEARNFOX
9 WAGE Numeric 5 2 R CREATE Untitled
10 PROBATION Logical 1 . .1B DISP STRU
11 NOTES Memo 10 1 _ 1
** Total ** 117 «♦_^_M

Figure 2.12: Displaying the structure of a database file.

4. To see if the last command worked, enter CLEAR to clear the


screen, and then enter DISP STRXJ again. Since no file is in
use, FoxPro will display a dialog box to let you select a data¬
base whose structure you want displayed, as in Figure 2.13.

Rather than selecting a database, press Esc to close this dia¬


log box. FoxPro will display an error message telling you that
it cannot execute the DISPLAY STRUCTURE command
because no database is in use, as shown in Figure 2.14. This
is an example of an alert: Press any key and it will disappear.
For one more look behind the scenes, enter

RUN DIR \LEARNFOX


You will see the files in the LEARNFOX directory, as shown
in Figure 2.15. Notice that it includes EMPLIST.DBF, the
database file, and EMPLIST.FPT, the memo file.

This bit of experimenting should help you realize that a database


file is sometimes in use without there being any obvious indication of
it on the screen.
CREATING A DATABASE STRUCTURE 65

System File Edit Database Record Program Window

Select database:

Drive C

Directory LEARNFOX

« Open »

I
< Cancel Hand
[ ] All Files

CLEAR
DISP STRU

Figure 2.13: The Select Database dialog box.

System File ; Edit Database Record Program Window

Figure 2.14: A FoxPro alert.


System File Edit Database Record Program Window
Volume in drive C has no label
Directory of C:\LEARNFOX

<DIR> 11-06-90 1:27a


<DIR> 11-06-90 1:27a
EMPLIST DBF 385 11-05-90 12:48a
EMPLIST FPT 512 11-05-90 12:48a
4 File(s) 1245184 bytes free

Figure 2.15: The EMPLIST database and memo files.

COPYING AND MODIFYING THE


STR UCTURE OF A DA TABASE FILE _

Normally, you would use the menu system to define the structure
of a new database file, but there are cases where it is easier to work
from the command line. For instance, if you are creating a new data¬
base file that is similar to an existing one, you can work from the com¬
mand line to copy the structure of an existing file to a new file. The
FoxPro menu system does not offer an option to enable you to copy a
file structure directly. As you will see in Chapter 5, it is possible to use
the menu system to trick FoxPro into copying the structure, but it is
simpler just to use the command COPY STRUCTURE from the
Command window, as you will do in the following exercise. After
you copy the structure of an existing file to a new file, you will use the
menu system to modify the copy somewhat, a procedure that will
address a common need in practice.

1. If you want, enter CLEAR in the Command window to clear


the screen. Select Open from the File menu popup and select
CREATING A DATABASE STRUCTURE 67

EMPLIST.DBF from the Open dialog box, shown in Fig¬


ure 2.16. The dialog box used to open a file is very similar to
the one that you used to name the file, so you should be com¬
fortable with it. The command
USE C:\LEARNFOX\EMPLIST.DBF
is generated in the Command window (though some of the let¬
ters are probably lost beyond the right edge of the window).

Figure 2.16: Opening a database file.

H Remember that you


can use just the first
2. To copy its structure to a new file (which we will call TEMP
since is it being used only temporarily, for illustration), enter
four letters of each word
in any FoxPro command. COPY STRUCTURE TO \LEARNFOX\TEMP
Here, you can abbreviate
the command as COPY in the Command window.
STRU. (You can abbre¬
viate only FoxPro key
3. To make TEMP the current file, select Open from the File
words, not file names.) menu again and the new file from the dialog box. Note that
EMPLIST.DBF is dimmed: you cannot select it (open it)
because it is already in use. Note also that the new file,
TEMP.DBF, has automatically been given a .DBF extension.
68 MASTERING FOXPRO

CH. 2

Now that you have copied the structure of an existing database file
to a new one, you will practice modifying it slightly using the Setup
dialog box (shown in Figure 2.17) from the Database menu popup.
This dialog box gives you control over the way in which a database
file is displayed. It is very powerful and versatile. It will be further

System File f d1 t Database Record Program Window

Database: TEMP
Structure: <Modlf|> Indexes: Index

►FNAME C 15 0 < Qdd... >


LNAME C 20 0 <Modify. . . >
ADDRESS C 25 0 < Remove >
APT NO C 5 0 <Set Order>

Fields: 11 Length: 117 Index expr:


Index filter:
[ ] Set FlelBjs. ..
' ‘ OB <•>
r, (1°III (•: ogf
[ ] Filter...
[ j Forfat...

Figure 2.17: The Setup dialog box.

discussed in Chapter 4, which deals with indexes, as well as in later


chapters. For now, you will just use it in a simple way to modify the
structure of the new database.
There are two Mod¬
ify text buttons in
1. From the Setup dialog box, select the Modify text button that
the Setup dialog box
discussed in Step 1. Do follows the word Structure in the upper left corner.
not select the one under
2. The Structure dialog box appears, the same dialog box you
the word Index in the
upper right corner of the used when you were creating the structure of a new database
dialog box. If you do, from scratch, except that it is already filled out with a struc¬
press Esc to return to the
ture for the TEMP database, as shown in Figure 2.18. This
Setup dialog box.
structure is identical to the structure of EMPLIST.
CREATING A DATABASE STRUCTURE 69

System Structure

Name Type Width Dec


Field
t FNAME Character 15
t LNAME Character 20 <In8ert>
t ADDRESS Character 25
t APT NO Character 5 <Delete>
t CITY Character 20
t STATE Character 2
t ZIP Character 5
t DATE HIRED Date 8
t WAGE Numeric 5 2
t PROBATION Logical 1 <Cancel>

Fields: 11 Length: 117 Available: 3883


LEARNFOX\T I

L
USE C:\LEARNFOX\TEMP.
MP.DBF I

Figure 2.18: The initial structure of TEMP, copied from EMPLIST.

3. Try moving the FNAME field below the LNAME field so


that the last name comes before the first name in this data¬
base. If you are using a mouse, simply move the pointer to
the arrow to the left of FNAME, hold down the button,
drag the field below the LNAME field, and release the but¬
ton. If you are using the keyboard, press Tab twice to high¬
light the double arrow to the left of FNAME, press the space
bar to highlight the field, press the down arrow key once to
move it, then press Enter to complete the operation.

H Notice the hot keys


on the Structure
4. Try inserting a middle-initial field. Place the cursor in the
ADDRESS field. Then, if you are using a mouse, it is easiest
menu: Ctrl-I to insert a
field and Ctrl-D to delete
just to click the Insert text button. Using the keyboard, use
a field. The hot keys are the Structure menu popup to select Insert Field. In either
really the only convenient case, a field called NEWFIELD with character data type and
way to insert and delete
the default width of 10 is inserted above the ADDRESS field,
fields using the keyboard.
where the cursor was. Edit this field: Type MI (for Middle
Initial) to change its name, and 1 to change its width.

5. Finally, delete the PROBATION field. Move the highlight to


this field using the mouse or the down arrow key. Then select
70 MASTERING FOXPRO

CH. 2

the Delete text button, or select Delete Field from the Structure
menu as you did when you were inserting a field. The PRO¬
BATION field disappears. The Structure dialog box should
now look like Figure 2.19. (Note that the LNAME field in our
screen has scrolled up beyond the top of the list box.)

System File Edit. Structure

Structure: C:\LEARNFOX\TEMP.DBF
Name Type Width Dec
Field
FNAME Character 15 >
MI Character 1 <Insert> >
ADDRESS Character 25 >
APT_NO Character 5 <Delete> >
CITY Character 20
STATE Character 2
ZIP Character 5
DATE HIRED Date 8 « OK »
WAGE Numeric 5
NOTES 10 <Cancel>
Li Fields: 11 Length: 117 Available: 3883
jl ==JI PLIST.
ILEARNFOX\T

L
USE C:\LEARNFOX\TEMP.DBF

Figure 2.19: The new structure of TEMP.DBF.

6. Assuming that those are the changes you want, select the
default text button, OK. FoxPro will ask for confirmation
that you want to make the structure changes permanent:
select Yes. FoxPro will display the Setup window again: a
system message in the upper right says “ Database Structure
Modified. ” Remember that there is no need to remove a sys¬
tem message; unlike an alert, it will just go away. Select OK
to confirm what you have done and to remove the Setup dia¬
log box.

Of course, you can also modify the structure of a file you have been
using—for example, if you have been entering five-digit zip codes
and want to convert to extended zip codes. For now, though, you
should be aware that you can lose data when you modify a files
CREATING A DATABASE STRUCTURE 71

structure—for example, if you mistakenly shorten a field so that it is


no longer large enough to hold some of the data in it or if you mistak¬
enly delete a field with data in it. For this reason, FoxPro automati¬
cally backs up a database file when you modify its structure, as you
will see in a moment.

Remember that after you create a file it is in use. Enter DISP


STRU and you will see that TEMP has the structure you
defined.

8. To see exactly what you have created, enter


RUN DIR \LEARNFOX
Notice that the directory, shown in Figure 2.20, contains a
.DBF and an .FPT file for both EMPLIST and TEMP;
these are the database and memo files respectively. There are
also backup hies for TEMP, with the extensions .BAK and
.TBK, since you modified its structure.

If you ever lose data and want to use the backup hies as your data¬
base, you can do so in several ways. One easy one is by using the
DOS command COPY Kfile name>.BAK Kfile name>.DBF, and

1 System File Edit Database Record Program Window


Volume in drive C has no label
Directory of C:: \LEARNFOX

<DIR> 11-06-90 1 :27a


<DIR> 11-06-90 1 :27a
EMPLIST DBF 385 11-05-90 12:48a
EMPLIST FPT 512 11-05-90 12:48a
TEMP BAK 385 11-05-90 12 : 57a
TEMP TBK 512 11-05-90 12 : 57a
TEMP DBF 385 11-05-90 1 : 02a
TEMP FPT 512 11-05-90 1 : 02a
8 File(s) 1187840 bytes free

Command
USE C:\LEARNFOX\EMPLIST.
COPY STRU TO \LEARNFOX\T
USE C:\LEARNFOX\TEMP.DBF
RUN DIR \LEARNF0X

Figure 2.20: Database, memo, and backup files.


72 MASTERING FOXPRO

CH. 2

COPY Kfile namey.TBK <file namey.FPT if there is a memo field


as well.
Since this was just an exercise, you can simply delete the new file
and backup files. FoxPro has its own commands to delete files, and
the Filer utility covered in Appendix B lets you delete files using a
menu-driven system; but it is usually easier to use the DOS DEL
command. You can use the DOS wild-card character * (which stands
for any word) to delete them all at once. Thus, to delete all the tempo¬
rary files, enter

RUN DEL \LEARNFOX \TEMR*

in the Command window.


If you want to take a break, select Quit from the File menu—or, if
you are becoming accustomed to the Command window, just enter
QUIT.
Adding, Editing,
and Viewing Data
To view your database one record at a time, 79
select Change from the Record menu popup, or enter either
CHANGE or EDIT in the Command window. You can edit as
well as view records displayed in this way.

To view more than one record at a time, 79


select Browse from the Database menu or enter BROWSE in
the Command window. This display allows you to see more
than one record, but in most cases you cannot see all the fields
in each record at one time. However, you can still edit records
displayed in this way.

To add new data, 80


Select Append from the Record menu or enter the command
APPEND. This command automatically adds blank records at
the end of the file. You can also add a single blank record after
you have selected Change or Browse, by selecting Append
Record from the Browse menu popup.

To save changes you have made to a file, 81


click the close box or press Ctrl-End to close the Browse/
Change window.

To discard changes you have made to a file, 81


press Ctrl-Qto close the Browse/Change window.

To modify a memo field, 81


double-click the memo held or put the cursor on it and press
Ctrl-PgDn to open the memo window. You can then enter data
or use the usual editing keys to edit the existing material. When
you are done, click the close box or press Ctrl-W to save the
changes you made; or simply press Esc to discard the changes.
To change the order of fields using a mouse, 95
move the pointer to the field name, then drag to move that
field’s column or row to where you want it.

To change the order of fields using the keyboard, 96


select Move Field from the Browse menu. Press the left or right
arrow key to move the field. When it is where you want it, press
Enter.

To delete a record, 99
select Toggle Delete from the Browse menu, or Delete from the
Record menu, or enter the command DELETE. Any of these
actions just marks the current record for deletion.

To recall a deleted record, 100


select Toggle Delete from the Browse menu popup, or select
Recall from the Record menu popup, or enter the command
RECALL. Any of these actions unmarks the current record if it
is marked for deletion.

To move the pointer, 103


select Goto from the Record menu or enter the command GO
TOP, GO BOTTOM, GO <number>, or SKIP. These actions
let you move the pointer through the hie without physically
scrolling through the Browse/Change window: you can use
them whether the window is open or not.
78 MASTERING FOXPRO

CH. 3

FOXPRO OFFERS TWO FUNDAMENTALLY DIFFERENT


ways in which you can look at the database when you add, edit, or
view data: the Change (or Edit) mode and the Browse mode.
The Change mode is designed to let you work on the database one
record at a time. The fields of the record are thus arranged so that
you can see the entire record, limited only by the size of the screen.
Of course, some records have such wide fields or such a number of
fields that you cannot see all the data in one record at one time using
the Change window. Still, Change is essentially record-oriented, and
its vertical field arrangement comes as close as possible to letting you
see an entire record. Figure 3.1 shows a complete record and, be¬
cause there is still room in the window, the beginning of the next
record in the database.

System File Edit Database Record Program Window Browse


i mpi isi =
Fname WILLIAM B
Lname JOHNSON
Address 1701 ALBEMARLE RD
Apt_no
City
State
Zip
Date_hired
Wage
Probation
Notes

Fname NANCY
Lname NIXON
Address 1124 GRANT AVE.
Apt no ▼ Command

USE EMPLIST.DBF
APPEND
CHANGE

Figure 3.1: Change mode.

The Browse mode is designed to let you look quickly through the
entire database file, rather than looking at one record at a time. It dis¬
plays the database in table form so that each record takes just one line, as
shown in Figure 3.2. In the Browse mode, you can see many records at
a time, but you usually cannot see all the fields of each record.
ADDING, EDITING, AND VIEWING DATA 79

SyStom Database Record Program Window Drowse


iMI’IISI
Fname Lname Address

Audrey Levy 318 B. 31 St.


JACK LOVE 3642 TANACH WAY
EDNA CHANG 2701 ADDISON WAY
CHARLOTTE SAGORIN 2203 SHADY LANE
WILLIAM JOHNSON 523 EAST 21 ST.
IWII i 1 AM D. ioi in:.on 1701 ALBEMARL f RD.
NANCY NIXON 1124 GRANT AVE.
JAMES SKINNER 1206 FRANCISCO ST.

BO
I ▼ Command

USE EMPLIST.DBF
APPEND
CHANGE

Figure 3.2: Browse mode.

The command Because Change is record-oriented, Change is on the Record


EDIT is more com¬ menu popup; and because Browse is database-oriented, Browse is on
mon than CHANGE in
older dBASE compatible
the Database menu popup. Working from the Command window,
programs. CHANGE is you can simply enter CHANGE (or EDIT) to use the Change window
more common in FoxPro. or enter BROWSE to use the Browse window.
The Change and Browse windows are related. Whenever you choose
either of these options, a Browse menu pad is added at the right of the
menu bar. The first option on the new menu popup lets you switch from
one mode to the other: if you are in Change mode, the first option is
Browse, and if you are in Browse mode, the first option is Change.
These options simply alter the way the database is displayed, without
closing the window and interrupting your work. We will refer to the
window created by either of them as the Browse/Change window, since
you can toggle between the two modes.
Browse and Change are meant to let you work on existing
records—to edit them or simply to look at them. If you want to create
new records, there is an option on the Browse menu popup that lets
you add a new record after you have selected Browse or Change,
but you must choose it each time you want to add a new record,
which is inconvenient when you are doing data entry.
To add several new records, you should select Append from the
Record menu or enter the command APPEND in the Command
window. This command continually maintains a blank record at the
end of the database file as you fill in additional records. The screen in
the Append mode starts out arranged as in the Change mode, with
one field above another. When you are in the Append mode, you can
scroll in the usual manner to reach other records in the file that you
are appending to. Thus, in the Append mode you can edit previous
records as well as add or change new ones; however, you would
always have to scroll up from the bottom of a database file to edit pre¬
vious records. For purposes of editing database records, Change is
the better option.
Append also makes the Browse menu pad appear, which enables
you to toggle the window from a Change-mode display to a Browse¬
mode display and vice-versa. You can add records with the window
arranged in either way. No matter how the window is arranged, as
long as Append is selected there will always be one blank record at the
end of the file for you to fill in.
Of course, a database must be in use before you can utilize
Browse, Change, or Append, which is to say that you must first select
Open from the File menu or enter the command USE Kfile name'> in
the Command window. If no database is in use, Change and Append
are not even available from the menu system, because you cannot
access the Record popup that they belong to. You can select
Browse—-from the Database menu—when no database is in use,
however, and FoxPro will display a dialog box to ask you which data¬
base you want, as shown in Figure 3.3. The same dialog box will
appear if you enter the command CHANGE, EDIT, BROWSE, or
APPEND in the Command window when no database is in use.

APPENDING DATA __
If you try to change or browse a database before any records are in
it—for example, the database from Chapter 2 which only has its
fields defined—the Change/Browse window will simply be blank. It
won’t even display the names of the fields to indicate the structure of
the database. You should append a few sample records first, so that
you have something there to change and browse a bit later.
ADDING, EDITING, AND VIEWING DATA 81

Figure 3,3: If no database is in use, FoxPro asks which database you want.

Most of the sample entries in the exercises of this chapter will be


made in Append mode. You will move around the file in the conven¬
tional ways, using the mouse or the right and left arrow keys to move
within a field, the up and down arrow keys to move among fields,
Tab or Enter to move to the next field, and so on.
If you press Ctrl-Q When you are finished editing database records you may either
to close the
Browse/Change window
save or discard the changes you made. Ctrl-End, Ctrl-W, clicking
while appending, editing, the close box, and selecting Close from the File menu are four ways to
or browsing records, close the window and save the changes you made. Ctrl-Q closes the
remember that FoxPro
window and discards the changes you made.
does not give you any
notice before closing the Memo fields of the database will show the word memo. If there is
window and discarding any text in the memo, this word will begin with a capital M; if not, it
any changes you have
will begin with a small m. To work with the contents of the memo
made. Furthermore,
pressing Esc might or field, press Ctrl-PgDn or double-click the memo field with the
might not save changes in mouse, and a memo window will open. Enter or change the memo
different versions of contents using the conventional editing keys. To close the memo win¬
FoxPro—you should test
yours to see whether it
dow and save the changes you made, press Ctrl-W or select Close
saves or whether it from the File menu. (Ctrl-End does not close a memo window—it
discards. moves the cursor to the end of the document.) Pressing Esc lets you
discard the changes, but when you are in a memo field FoxPro gives
you a warning before discarding.
82 MASTERING FOXPRO

CH. 3

All these features will be very obvious when you use them in the
following exercises. First you will append some data in the ordinary
way, with the fields one above another, as they are in the Change
mode. Then you will append more data with the fields next to each
other, as they are in the Browse mode. Throughout this book we will
refer to the vertical arrangement of fields as the Change mode or dis¬
play and the horizontal arrangement of fields as the Browse mode or
display, in keeping with the “Browse/Change window” terminol¬
ogy. As you will see later, this window can be split to display informa¬
tion in both modes if you wish.

APPENDING DA TA
WITH THE CHANGE DISPLA Y
In the last chapter, you used the FoxPro dialog boxes to move
among subdirectories. Now that you have become familiar with these
operations, you might as well make your work easier by getting into
the LEARNFOX subdirectory to begin with, which will let you
select the database file with less trouble.

1. Before starting FoxPro, use DOS to change directories. At


the DOS prompt, enter CD \LEARNFOX. Then enter FOX¬
PRO to start the program. (If you are already running Fox¬
Pro, just enter RUN CD \LEARNFOX in the Command
window.) If you want, enter CLEAR in the Command win¬
dow to clear the screen and make it easier to see.

Remember that, if 2. To use your sample database, select Open from the File
you are working
menu and select EMPLIST.DBF from the Open dialog box.
from the Command
window, you do not need
(Notice that the command generated in the Command win¬
to include the .DBF dow is USE EMPLIST.DBF. The full name of the database
extension. You can just file \LEARNFOX\EMPLIST.DBF is not needed, as the file is
enter USE EMPLIST,
in the current directory.)
since the USE command
applies only to database 3. To add data to the file, select Append from the Record menu.
files anyway.
The command APPEND is generated in the Command win¬
dow, a Browse menu pad is added to the menu bar, and the
Browse/Change window appears in the special form that it
has when you are in the Append mode, shown in Figure 3.4.
ADDING, EDITING, AND VIEWING DATA 83

Figure 3.4: The ‘ ‘Append window” with a blank record.

Notice that the name of the database file is at the top of this window
and that the record is arranged in what we are calling the Change dis¬
play, with one field above another. The fields are highlighted in
reverse video, so that you can see the maximum length of each
held—the amount of space you have to fill in. The cursor also
appears in the Fname held; it is the ordinary blinking cursor except
that it is in reverse video.
If you hll the entire length of a held, FoxPro beeps and goes on to
the next held. As you will see, this saves a bit of time when you are
It is common when entering helds of a hxed length, such as date helds. FoxPro will not
using dBASE com¬
patible database fields to
accept invalid data in any held. If you try to enter a letter in the Wage
enter blank records. If held or Date_hired held, for example, it will beep and not accept it.
you create a blank record, One important point to note—and one which is unique to the
in FoxPro, the > > will
Append mode—is that, when you begin, all the helds of the record
disappear and the record
will be saved. The > > have the double right arrowhead > > to their left. This indicates that
sign thus makes it easy there is no data entered in the record: if you close the window at this
for you to tell whether
point, that record will not be saved. On the other hand, as soon as
you truly have a blank
record or simply an you enter any data in the hrst held of the record, the >> will disap¬
unused one. pear from all the helds of the current record, and a new record with
84 MASTERING FOXPRO

CH. 3

> > before each field will be added after the current record, as in Fig¬
ure 3.5. This change indicates that the current record is no longer
empty, and that it will be saved when you close the window. This is a
major difference between selecting Append and selecting Change or
Browse, which only let you add a new record by making an explicit
choice from the Browse menu popup for each record to be added.

USE EMPLIST.DBF
APPEND

Figure 3.5: As soon as you enter data, a new blank record is appended.

FoxPro (like other dBASE compatible programs) is sensitive to


case differences in data. For example, if you tell it to search for
SMITF1 (all uppercase) it will not find the record if the name was
entered as Smith (upper and lowercase). For this reason, it is a com¬
mon practice to enter names in all capital letters, to avoid difficulties
in sorting and searching. However, when you have a long file, it is
also common to have some names that were inadvertently entered in
the ordinary format, with both capital and small letters. For the pur¬
poses of this exercise, you will enter the first record in the upper-and-
lowercase format as begun in Figure 3.5, and the rest of the records in
all capitals—so that you can see in later chapters what sort of difficul¬
ties this causes and how to get around them.
ADDING, EDITING, AND VIEWING DATA 85

The samples in this exercise will also have other inconsistencies


that often arise in data entry: for example, “Christmas” and “fund
raising’ ’ will be spelled in more than one way. There will also be two
people with the same name, as there often are in a large database.
Though this is a small sample, it should give you an idea of some of

H The instructions tell


you to press Tab to
the difficulties you usually come across in real life.

1. Type Audrey in the Fname field and press Tab. Notice that,
move to the next field,
but you can actually press as soon as you press Tab, the > > signs to the left of all the
Tab, Enter, or the down fields in this record disappear, because this is no longer a
arrow key. As usual, you blank record. At the same time, a new blank record with
should find the one that is
most comfortable for you.
a > > sign before each field is added after it.

2. Type Levy in the Lname field and press Tab.


3. Type 318 B. 31 St. in the Address field and press Tab.

4. Press Tab to skip the Apt_no field.

5. Type Far Rockaway in the City field and press Tab.


6. Type NY in the State field. Because the data fills the entire
field, FoxPro beeps and the cursor automatically moves to
the next field.

7. Type 11600 in the Zip field. Again, FoxPro beeps and moves
to the next field.

8. Type 07/16/81 in the Date_hired field, and FoxPro beeps


and moves to the next field.

9. You want to enter 8.00 in the Wage field. Press the space
bar, then type 8, and then press Tab to keep the two zeroes
there and move to the next field.

10. Type n for no in the Probation field. The letter n appears for
an instant and is then replaced by an F, as FoxPro translates
yes and no answers into True or False logic statements. Fox¬
Pro then beeps to tell you the field is full, and the cursor
moves to the next field. (If you enter anything besides a capi¬
tal or small T, F, Y, or N in a logical field, FoxPro beeps to
show that you have made an invalid entry, and the cursor
stays in the field.)
86 MASTERING FOXPRO

CH. 3

11. Since the Notes field is a memo field, press Ctrl-PgDn or


If you did not want
to enter anything in double-click to use the memo window. You can see it is titled
this memo field, you
EMPLIST- >NOTES
would just press Tab,
Enter, or the down arrow to show that it is the Notes field of the EMPLIST database file.
key to move on to the
You can enter any text in the memo window, using the usual
next field.
editing keys that you learned in Chapter 1. Try entering a note
that is longer than one line: Vacation time now totals more than
three weeks per year. Works on annual Christmas fund-raising
drive. Notice the editor’s word-wrap feature: when you get to
the right edge of the window, the text automatically continues
on the next line, as shown in Figure 3.6.

System File Edit Database Record Program Window


EFIPL1 ST-> NOTES =

Figure 3.6: The memo window with text.

12. Try zooming the window, to get a better feel for word wrap.
Click the zoom control, or select Zoom from the Window
menu. The memo window now takes up the entire screen,
and the text is automatically rewrapped to fit into the new
size of the window, as shown in Figure 3.7. Zoom the win¬
dow again to return it to its original size.
ADDING, EDITING, AND VIEWING DATA 87

Figure 3. 7: Text in the memo window is automatically rewrapped when the


size of the window changes.

13. When you have finished typing, press Ctri-W or click the
close box to close the memo window and return to
the Browse/Change window. Then press Tab to move to the
next field, the Fname field of the second record.

Try entering the following additional names to get used to the way
the Append mode works and to give yourself some sample data to
work with in the rest of the book. Be sure to press the Caps Lock key
first so that you enter the following records as they are written, in all
capital letters (except for the memo fields, some of which are entered
with ordinary capitalization). Where the field indicates “(none),”
leave that field blank.

• Fname: JACK Lname: LOVE Address: 3642 TANACH WAY


Apt_no: 18 City: ELIZABETH State: NJ Zip: 07200 Date
_hired: 06/04/89 Wage: 16.20 Probation: T Notes: Cannot work
on Christmas fund raising drive.
• Fname: EDNA Lname: CHANG Address: 2701 ADDISON WAY
Aptjno: 2B City: BERKELEY State: CA Zip: 94706 Datejnred:
09/07/88 Wage: 9.75 Probation: T Notes: (none)
88 MASTERING FOXPRO

CH. 3

• Fname: CHARLOTTE Lname: SAGORIN Address: 2203


SHADY CIRCLE Apt_no: (none) City: EAST ORANGE State:
NJ Zip: 07000 Date_hired: 06/06/82 Wage: 22.75 Probation: F
Notes: ON XMAS FUNDRAISING COMMITTEE.

• Fname: WILLIAM Lname: JOHNSON Address: 523 EAST 21


ST. Apt_no: F-23 City: NEW YORK State: NY Zip: 10022
Datejiired: 4/23/76 Wage: 6.25 Probation: F Notes: LONG
TERM AND LOYAL EMPLOYEE.
• Fname: WILLIAM B. Lname: JOHN SON Address: 1701 ALBE¬
MARLE RD. Apt_no: D-14 City: BROOKLYN State: NY Zip:
11226 Datejiired: 12/15/89 Wage: 19.70 Probation: T Notes:
(none)

You should be accustomed, by now, to the way FoxPro works


when you append data with the ordinary, Change-mode display.

APPENDING DA TA
WITH THE BROWSE DISPLA Y
You will continue creating your sample database by appending
another record with the Browse display. In this exercise, you will use
the menu system to toggle the screen to this display, and then you will
go on adding records in much the same way you did before.

1. If it isn’t already there, move the cursor to the first field of the
blank record. Then select the Browse menu pad. Since
the Browse/Change window is now arranged in the Change
display mode, the first option on the menu popup is Browse.
Select that option to toggle the window to the Browse display.

2. The Browse/Change window is now large enough to show


only a few fields of each record, and the cursor is right where
it was before you toggled to the Browse display, as shown in
Figure 3.8.

3. To enter the next record, type NANCY in the Fname field


and press Tab. Notice that the > > symbol disappears from
the left of the current record, and moves one line down, just
ADDING, EDITING, AND VIEWING DATA 89

System f i le' [ cJ.it’ Database Record Program Window Ilrovtse j


P ■ _. IMP! ISI - E
Fname Lname Address

WILLIAM JOHNSON 523 EAST 21 ST.


WILLIAM B, JOHNSON 1701 ALBEMARLE RD. 1
»MM1

c Command

Figure 3.8: Appending with the Browse display.

as it moved one record down when you were working with


the Change display.
4. Type NIXON in the Lname field and press Tab.

5. Type 1124 GRANT AVE in the Address Field and press Tab.
Then press Tab again to skip the Apt_no field.

6. Type PALO ALTO in the City field and press Tab.

7. Type CA in the State field. Notice that although the State


field now looks wider than is needed to hold the two letters of
a state’s name, it still accepts no more than the two characters
that are its defined width. It then beeps and goes on automat¬
ically to the next field.

8. Type 94300 in the Zip field.

9. Type 02/01/84 in the Datejhired field.

10. Type 18.25 in the Wage field.

11. Type N in the Probation field.

12. There is no entry in the Notes field. Leave the cursor in that
field.
90 MASTERING FOXPRO

CH. 3

As you can see, it is equally easy to append records with either the
Browse or the Change display. Now, in order to leave the file in
the way you will next use it, you will toggle back to the Change dis¬
play and then end your data-entry session.

1. Select the Browse menu pad. Notice that the first option on
the menu popup now is Append, which toggles the screen
back to the Change display that is standard in Append mode.
Select the Append option.
2. Close the window to save your changes: press Ctrl-End, click
the close box, or—if you insist on doing things the hard
way—select Close from the File menu.

Remember that the EMPLIST database is still in use. Even if you


selected Close from the File menu, you only closed the current win¬
dow and not the database file itself.

CHANGING (OR EDITING) DATA ._


At this point, you should find it very easy to learn how to edit data.
When you select Change from the Record menu, the database
appears in a form very much like the Change display that you are
familiar with from appending data. The only major difference, as
you will see, is that since you are not in the Append mode, new
records are not added at the end of the database automatically—you
must use the menu system to add a blank record each time you want
to add a record to the database.
When you are To edit the data, you will use the conventional editing keys, and
editing, pressing
Ctrl-Q closes the window
press Ctrl-End or Ctrl-W, or click the close box, to close the
and discards the changes Browse/Change window and save the changes you made, just as you
that you have made did with Append. You may edit memo fields, also, just as you did
without giving you any
with Append. When you are editing, you are more likely than when
warning, as it does when
you are appending. you are appending to want to scroll among records, so you will be
Although this is useful if using the scroll bar or the PgUp and PgDn keys. You are also more
you made changes by
likely to want to use the Undo feature of the editor, which you learned
mistake, it must be han¬
dled with caution; other¬ about in Chapter 1.
wise you might discard When you begin, you will see that not only is the EMPLIST file
changes you shouldn’t.
already open, as mentioned above, but that the record you worked
ADDING, EDITING, AND VIEWING DATA 91

on last is still the current record—the record with the cursor in it, dis¬
played in the Browse/Change window as shown in Figure 3.9. Fox¬
Pro thus kept track of where the cursor was even after the window
was closed. FoxPro has what is called a pointer, which remains on the
current record until you either move it or close the database. The
idea of the pointer is important, and you will look at it more thor¬
oughly later in this chapter.
The command
CHANGE is exactly
equivalent to the com¬
mand EDIT.

Figure 3.9: The Change window, with the last record you entered still current.

1. Select Change from the Record menu. This will display the
Browse/Change window with the last record that you
entered. Notice that the command CHANGE is generated in
the Command window.
2. Try moving up and down through the file. After moving up,
use the scroll bar or press PgDn repeatedly to try to move
beyond the last record: you will see that you cannot. Try
again, by using the down arrow key to move to the final field
of the last record. When you try to go further, you will see
that you cannot go beyond the last record and add a new
record, as you could when you were in Append mode.
92 MASTERING FOXPRO

CH. 3

3. Let’s say that you find that SHADY CIRCLE is supposed to


be SHADY LANE. To correct it, use the keyboard or the
mouse to move the cursor through the record to the first letter
of CIRCLE. Press Ins to toggle into the typeover mode.
Type LANE. Press Ins again to toggle out of the typeover
mode. Press Del twice to delete the L and E of CIRCLE.
You have corrected the error.

If you delete the That’s all there is to editing the content of fields; you can close the
entire contents of a window and save the changes by pressing Ctrl-End or discard them
memo field, the word
memo in the database will
by pressing Ctrl-Q. To edit a memo field, just move the cursor to the
begin with a small m field, press Ctrl-PgDn to access the memo window, and edit the field
again, to show that the just as you did when you were first entering it, using the conventional
field is empty.
editing keys. Save the changes you made by closing the memo win¬
dow, or discard the changes you made by pressing Esc.
A Browse menu pad was added to the menu bar when you selected
Change, just as it was when you selected Append. Most of the
options on this menu popup (shown in Figure 3.10) are far more use¬
ful when you are in Browse mode, and you will look at this popup in
detail in the next section.

System f i lo Edit
Dat..abase Record F’rogram Window Browse
1 E1V1PL 1ST
1 Fname ■CHARLOTTE DDMMHHBHf Browse
I Lname ■sAGORIN grid Off
1 Address ■J20i SHADY LANE Unlink Partitions
Apt_no Change Partition ~H
City
State Size Field
Zip Eove Field
Date_hired Sesize Partitions
Wage
Probation G0to...
Notes Seek . . .

Fname
Lname
WILLIAM
JOHNSON
J|oggle Delete
Append Record |
Address 523 EAST 21 ST.
Apt no F-23 ▼ Command

Figure 3.10: The Browse menu popup when you are in Change mode.
ADDING, EDITING, AND VIEWING DATA 93

You will find that, in general, the only time you will want to use
the menu when you are in Change mode is when you want to add a
single extra record. Try it now:

1. Select Append Record from the Browse menu. Notice that a


blank record has been added to the end of the file, and that
your cursor immediately moves to this new record, ready to
enter data in it. Unlike the record that is added to the end of
the database when you select Append from the Record
menu, this new record does not exhibit the > > symbol, as
shown in Figure 3.11. This means that a record created in
this way will be saved as a blank record if you close the window
immediately.

System File Edit Database Record Program Window Brows.e


EMPLIST
Fname
Lname
Address
Apt_no
City
State
Zip
Date_hired
Wage
Probation
Notes

▼ Command

USE EMPLIST.DBF
APPEND
CHANGE

Figure 3.11: Adding a blank record to the file.

2. Make a sample entry in the record. For Fname, enter


JAMES. For Lname, type SKINNER. For address, type 1206
FRANCISCO ST. Skip the Apt_no field. For City, type
MENLO PARK. For State, type CA. For Zip, type 94025.
For Date_hired, type 12/01/88. For Wage, type 8.2. For
Probation, type Y. Type nothing in the memo field.
94 MASTERING FOXPRO

CH. 3

What happened when you selected Append Record is identical to


what happens when you use the command APPEND BLANK from
the Command window: the program adds a new blank record and
makes it the current record. There actually is no advantage to using
APPEND BLANK in the interactive mode, because to make an entry
in the new record you would have to enter the command CHANGE
(or EDIT). APPEND BLANK is very important in programming,
though, since it lets you have complete control over users’ access to
the database—unlike APPEND, which lets users scroll through the
entire database.

BROWSING THROUGH THE DA TA _


You probably noticed that when you are in the Change mode the
first option on the Browse menu popup lets you toggle to Browse
mode—just as you toggled from Change to Browse display when you
were appending records. If you choose Browse from this popup, the
Browse/Change window will be arranged like the Browse display you
used in Append mode, except that now that you aren’t in the Append
mode you will not be able to append without explicitly making the
menu choice to add a single blank record.
Since it is so similar to what you have already learned, you do not
need extensive exercises with the Browse window. You can just play
with it yourself to get the feel of it.
If you are using Because it lets you see many records at a time but does not let you see
Browse just to look
all the fields in each record, you often want to select which fields you can
through the database, the
best way to close the see in the Browse window. Imagine, for example, that you have a list of
Browse window is to names, addresses, and telephone numbers, and you need to use this list
press Ctrl-Qwhen you
in order to make telephone calls. The addresses would probably be of lit¬
are done. If you made
any changes inadver¬ tle help for this purpose, and the address fields would take up so much
tently, they will be space that you would not normally be able to see the telephone number
discarded.
in the Browse window. As you will see, though, you can move the fields
of the Browse window so that the telephone number is displayed imme¬
diately after the first and last name—making it much easier for you to do
your telephoning.
There are a number of ways of altering the display of the Browse
window, which are listed in this section. As you have seen, the
ADDING, EDITING, AND VIEWING DATA 95

options for altering the display of the window that are on the Browse
menu popup are also available when you select Change, but they
obviously are more useful when you are browsing through a file and
cannot see the entire record. You should experiment with these
options as you read their descriptions below. Experiment also to see
how they work when you toggle back and forth between Change and
Browse.
When you experiment, the first thing you should notice is that
whenever you select Browse (from the Database menu), the com¬
mand generated in the Command window is BROWSE LAST. This
command can be used to open the Browse window as it was when
you last used it. This command is very useful in practice. For
example, if you often telephone people, and you change the order of
fields in the Browse window so that the telephone number is next to
the name, FoxPro will save the setting even after you turn off your
computer, and will display the fields in that order whenever you
browse that file using BROWSE LAST.

RESIZING AND
CHANGING THE ORDER OF FIELDS
The most common alteration you will want to make in the Browse
window is to change the order and the size of the fields, so you can see
the data you want. If you move the fields that you need to the left,
and you make some of the fields smaller, you can generally see all of
the data that you need within the Browse window. (Sometimes,
of course, you will want to Zoom the window also).
Changing the size or order of fields in this way only affects how
they are displayed in the Browse window, and does not affect the way
that they are actually stored in the database, so there is no danger of
loss of data.

USING A MOUSE
It is extremely easy to change field size or order using a mouse.
You simply use the mouse to manipulate the list of field names above
the records. First, though, check to see if you can see the grid lines
96 MASTERING FOXPRO

CH. 3

to the right of each field name. If you cannot, select the Grid On
option from the Browse menu.

• size: To change the size of a field, move the pointer to the grid
line to the right of the field’s name. Drag left or right to make
the field smaller or larger.

• order: To change the order of a field, move the pointer to the


field’s name, then drag left or right to reposition the column
where you want it.

USING THE KEYBOARD


If you are using the keyboard, you must use the Browse menu to
change the size or order of fields.

• size: Select Size Field, then select the field whose size will be
changed. The name of the current field is highlighted in
reverse video. If it is not the field you want, use Tab or Shift-
Tab to move to the field you want. Then press the left arrow
key to shorten the field or the right arrow key to lengthen the
field. When it is the size you want, press Enter.

• order: Select Move Field, then select a field to be moved. The


name of the current field is underlined. If it is not the field you
want, use Tab or Shift-Tab to move to the field you want. Then
press the left arrow key or the right arrow key to move the field.
When it is in the location you want, press Enter.

PARTITIONING THE WINDOW


You can divide the window into two partitions—which is a bit like
having two separate windows that let you look at two parts of the
database file at once.
Normally, the two partitions are linked: when you scroll through
the records in one partition, records will automatically scroll
through the other partition, so the same record is visible in both.
However, you can use the menu to unlink partitions in order to view
records independendy. This menu option toggles from Unlink to
ADDING, EDITING, AND VIEWING DATA 97

Link; after you have unlinked partitions, you would choose Link
to tie them together again. Figure 3.12 shows the difference between
linked and unlinked partitions.
After you have partitioned the window, only one partition is active
and available for editing. You can move around a partition in the same
way that you move around any Browse/Change window, by using the
scroll bar or by using the Tab, arrow, PgUp, and PgDn keys.
As you can see from the illustrations, the partitioned window is very
versatile. Experiment with it when you read the following sections. The
first section is for mouse users, the second is for keyboard users, and the
third describes menu selections that are the same for both.

USING A MOUSE
Again, it is very simple to work with partitions using the mouse.

create, resize, or remove: Move the pointer to the window


splitter. This is an arrow with two heads pointing left and
right that is in the lower left corner of the Browse window
when no partitions have been created or on the bar separat¬
ing the two partitions when partitions have been created.
Dragging the splitter to the right divides the window into two
partitions. As you drag the splitter, the partition on the left
fitfROW:
becomes larger and the one on the right becomes smaller. To
(i dij) )
. ,
fjbj ly
-4 A
f ly resize the partitions, drag the partition splitter in the same
' MCVtS- way until the partitions are the size you want. To remove the
partitions, drag the splitter until one is closed.

to change: To move the cursor from one partition to another,


just click the partition that you want to be active.

USING THE KEYBOARD


Again, to work with partitions using the keyboard, you must make
selections from the Browse menu.

• create, resize, or remove: Select Resize Partitions from the


Browse menu. The window splitter (the arrow with two
heads that is in the lower left corner of the Browse window
when there are no partitions or at the bottom of the bar
between the partitions when they have already been created)
98 MASTERING FOXPRO

CH. 3

Figure 3.12: The Browse/Change window with linked partitions (top) and
unlinked partitions (bottom).
begins to blink, indicating that you can move the partition.
Press the right arrow key, and the window splitter will move
right, dividing the window into two partitions. As you press
the right arrow key, the partition on the left becomes larger
and the one on the right becomes smaller. Keep pressing the
right and left arrow keys until the partitions are the size you
want. Resize existing partitions in the same way. To
Remove the partitions, press the arrow keys until one is
closed.
ADDING, EDITING, AND VIEWING DATA 99

• to change: Select Change Partition from the Browse menu,


which will move you to the partition that you are not cur¬
rently in.

LINKING AND UNLINKING PARTITIONS


Regardless of whether you are using a mouse or the keyboard, you
must use the Browse menu to link and unlink partitions.
Normally, the two partitions are linked: if you scroll through one
partition, you will automatically scroll through the other at the same
time. Select Unlink Partitions from the Browse menu to separate the
two, so that you can scroll through one without affecting the other.
When you have unlinked partitions, the Unlink Partitions option
on the Browse menu popup is replaced by a Link Partitions option.
Select this to tie the partitions together again.

DELETING A RECORD _
There are a few additional features of the Browse menu popup.
Selecting Grid Off removes the vertical lines separating fields in
the Browse window. If you select it while in the Change display, the
lines will be removed when you toggle to the Browse display. After
the lines are removed, this option changes to Grid On, which lets you
replace the lines.
Goto and Seek from the Browse menu popup let you move
through the database file by specifying the records you want and by
using indexes. These options are identical to options available on the
Record menu popup. Goto will be discussed later in this chapter;
Seek will be discussed in Chapter 5.
The most important remaining option on the Browse menu is
Toggle Delete, which lets you delete a record. To be more precise,
selecting this option lets you mark a record for deletion—it does not
actually remove the record from the database file. When a record is
marked for deletion, a bullet appears to its left, as shown in Fig¬
ure 3.13. The menu option is equivalent to the command DELETE.
If a record is already marked for deletion, selecting the same
option will unmark it; that is why it is called Toggle Delete. In this sit¬
uation, it is equivalent to the command RECALL.
100 MASTERING FOXPRO

CH. 3

System Kile L cli t Database. Record Program Window Browse


IMPL1ST
Fname Lname Address

• Audrey Levy 318 B. 31 St.


JACK LOVE 3642 TANACH WAY
•EDNA CHANG 2701 ADDISON WAY
CHARLOTTE SAGORIN 2203 SHADY LANE
WILLIAM JOHNSON 523 EAST 21 ST.
WILLIAM B. JOHNSON 1701 ALBEMARLE RD.
NANCY NIXON 1124 GRANT AVE.
■JAMES SKINNER |1206 FRANCISCO ST.

D▼ Command

Figure 3.13: Bullets show that the first and third records are marked for
deletion.

Using this option from the Browse menu popup is very handy
when you are editing or browsing a file, to delete or recall the record
you are currently working on. In other situations, you may want the
extra power that you get by selecting Delete from the Record menu
and using the Delete dialog box, shown in Figure 3.14.
I The For and While
Selecting the default text button Delete from this dialog box simply
■■I check boxes are the
most useful, as they let you
marks the current record for deletion, just as selecting Toggle Delete
delete or undelete records from the Browse popup does. As you can see, though, this dialog also
that meet certain criteria. includes Scope, For, and While check boxes, which let you mark
For example, you can
more than one record at a time. These three check boxes are found in
delete all the records with
less than a certain wage or many different dialog boxes, and you will learn how to use them
recall the records that are in Chapter 5. To give one example now, though, to give you an idea
not from California. This
of what they can do, select Scope and then choose All from the Scope
is essentially a matter of
building a query into the dialog box to mark all the records for deletion (or just enter the com¬
DELETE command, and mand DELETE ALL in the Command window).
you should bear it in mind
Remember that these records are simply marked for deletion: you
when you read the discus¬
sion of FOR and WHILE
can select Recall from the Record menu to unmark them. The Recall
clauses in Chapter 5. dialog box, shown in Figure 3.15, has the same check boxes as the
Delete dialog box. Selecting its default Recall text button will
ADDING, EDITING, AND VIEWING DATA 101

System. File Edit Database Record Program Window Browse


EMPLIST
Fname Lname Address

[Audrey 318 B. 31 St.


JACK LOVE 3642 TANACH WAY
EDNA CHANG 2701 ADDISON WAY
CHARLOTTE SAGORIN 2203 SHADY LANE
WILLIAM JOij==
WILLIAM B. JO
NANCY NI [ ] Scope..
JAMES SK « Delete »
C ] |or...
< Cancel >
[ ] Ehile.

Figure 3.14: The Delete dialog box.

System FTle Edit Database Record Program Window Browse


EMPLIST
Fname

Audrey -
Lname Address

318 B. 31 St.
1
JACK LOVE 3642 TANACH WAY
EDNA CHANG 2701 ADDISON WAY
CHARLOTTE SAGORIN 2203 SHADY LANE
WILLIAM JO
WILLIAM B. JO
NANCY NI [ J Scope...
JAMES SK « Recall »
[ ] |or...
< Cancel >
[ ] fflhile.

Command

USE EMPLIST.DBF
APPEND
CHANGE

Figure 3.15: The Recall dialog box.


102 MASTERING FOXPRO

CH. 3

unmark only the current record, however; for this example it is best
to use the check boxes, which let you work with groups of records.
Once again, use a scope of All to unmark all the records that you pre¬
viously marked for deletion.
When you experiment with these features, you will see that Toggle
Delete does not generate a command in the Command window; it
resides entirely in the Browse window. On the other hand, Delete,
from the Record menu, generates the command DELETE NEXT 1
as well as FoxPro “talk” that says “1 records deleted.” Similarly,
Recall, from the Record menu, generates RECALL NEXT 1 as well
as talk that says “1 records recalled.” The NEXT 1 at the end of
each of these commands is not necessary: it specifies the scope of the
commands (discussed at length in Chapter 5) to be 1, which means
that they apply only to the current record. As it often does, FoxPro
generates commands with more detail than is actually needed: this is
the default scope for these commands, so you do not need to specify it
if you are working from the Command window. Thus, to mark or
unmark the current record from the Command window, simply
enter the command DELETE or RECALL.
Data can be lost if Records that are marked for deletion are not actually removed from
packing is inter¬
rupted. Because of this,
the file until you select Pack from the Database menu or enter the com¬
the Esc key is disabled mand PACK in the Command window. When you “pack’ ’ the file, the
during packing: pressing program finalizes the deletion by copying all of the records that are not
Esc will not interrupt the
marked for deletion. These are copied to a new file, which replaces the
PACK command as it
does other commands. old file. The process is called packing because it compresses the file into a
Do not turn off the com¬ smaller amount of space by removing the deleted records. Because it
puter while packing is in
takes time to copy the records to a new file, it is done only when you
progress—no matter how
long it takes. If you think select Pack; if you were working with a long file, there would be an
there is danger of a power annoying delay if the file were packed every time you deleted a record.
failure, back up your
When you pack a database, ‘ ‘talk’ ’ will appear on the screen behind the
database file before
packing.
windows to tell you how many records were copied into the new version
of the database file.
Most FoxPro commands that use records will use them regardless
of whether they are marked for deletion, and this can sometimes
cause problems. For example, if you search for records from the state
of California, FoxPro will find those that are marked for deletion as
well as those that belong in the file. The simplest way of dealing with
this problem is to pack the database before using any command that

t
ADDING, EDITING, AND VIEWING DATA 103

you do not want deleted records to get in the way of. At the end of
Chapter 5, after you have learned about logical expressions, you will
be able to learn other methods of keeping records that are marked for
deletion out of your way.
Finally, there is one very dangerous command that you should
know about: ZAP, which eliminates all records from a file. It is
equivalent to entering DELETE ALL and then PACK, except that it
works much more quickly. After you enter ZAP, your records are
gone forever: they cannot be recalled. This is such a dangerous com¬
mand that it should probably not have been included in the dBASE
standard: since it is used in dBASE compatible programs, though,
you should be forewarned.
ZAP is most dangerous in combination with the environment
command SET SAFETY OFF. Normally, FoxPro will ask you if you
want to ZAP all your records before it executes this command. How¬
ever, if you have entered the command SET SAFETY OFF (or turned
Safety off using the View window) earlier in the session, ZAP will
eliminate all your records without giving you any warning.

MOVING THE POINTER _

There are times when you should know where the pointer is even if
you can’t see it. Furthermore, there are times when you want to
move the pointer.
You have already seen that a pointer keeps track of the current
record when you are changing or browsing a file. After you close the
Browse window, the record that had the cursor on it last remains
the current record as long as the file is still open; thus the cursor will
still be on that record when you start to edit the file again. Likewise,
you have seen that when you enter DELETE in the Command win¬
dow, the record that the pointer is on will be marked for deletion.
This occurs even if the Browse window is closed.
When you are working with the pointer, it is useful to remember
that every record in your database file has a record number. Records are
numbered sequentially as they are entered: the first record you
entered in the database is record number 1, and so on.
It is possible to move the pointer even when the Browse window is
closed and you cannot see the pointer. You do this by selecting Goto
104 MASTERING FOXPRO

CH. 3

from either the Record or the Browse menu popups. Either of these
will display the Goto dialog box, illustrated in Figure 3.16.
As you can see, this dialog box gives you four choices of where to
move the pointer:

• Top: moves the pointer to the first record of the database.

• Bottom: moves the pointer to the last record of the database.

System File Edit Database Record Program Window Browse


EMPLIST I
Fname

Audrey
Lname Address

318 B. 31 St.
I
JACK LOVE 3642 TANACH WAY
EDNA CHANG 2701 ADDISON WAY
CHARLOTTE
WILLIAM
WILLIAM B. ( •) Top
NANCY
JAMES ( ) [|ottom « Goto »

( ) Record < Cancel >

( ) Ikip

USE EMPLIST.DBF
APPEND
CHANGE

Figure 3.16: The Goto dialog box.

• Record: displays a text box so you can enter the number of


the record you want to move to. Though you usually will not
know the exact number of the record you want, if you have
an idea of its approximate number this option will generally
be the fastest method for moving the pointer to the place you
want in a long database. If you have a thousand records in
the database, for example, and you know that the record you
want was entered recently, say among the last hundred,
you can use this command to “goto” record 900 and then
scroll through the Browse window beginning at that point.
ADDING, EDITING, AND VIEWING DATA 105

• Skip: displays a text box so you can enter the number of


records by which you want to move the pointer from its cur¬
rent position. The number 1 is entered by default, but you
can edit it to enter any number. If you keep the 1, for
example, the pointer moves to the very next record; if you
enter 1000, the pointer skips ahead 1000 records (assuming
the file is that large). You can also use negative numbers:
enter - 1 to move to the previous record or - 20 to move back
twenty records.

Since the pointer is a very important concept, use this dialog box a
bit to get a feel for it. Open the Browse window before moving the
pointer, so you can see where it goes.

1. If necessary, enter BROWSE in the Command window, to


open the Browse window with its default display, that lets
you see all the records of EMPLIST.

2. Select Goto from the Record menu and select one of the radio
buttons of the Goto dialog box. Remember you must select
the default text button, Goto, to execute the command. Do
this several times to get a feel for moving the pointer.

3. When you are done, close the Browse window.

Notice that the commands that are generated as you make selections
from this dialog box are almost identical to the selections you make.
GOTO commands have two forms: as a typing shortcut, you can
simply enter the command GO, though GOTO is also valid.

GO TOP (or GOTO TOP) moves the pointer to the first


record.
GO BOTTOM (or GOTO BOTTOM) moves the pointer to
In addition to a the last record.
number, you can
use any numerical expres- • GO [RECORD] < number > (or GOTO [RECORD]
sion with SKIP or GO < number >) moves the pointer to the record with the number
RECORD. Expressions
will be covered in Chap¬
indicated. (Do not type the square brackets—they simply
ters 4 and 5. serve to indicate that the word RECORD is optional.)
106 MASTERING FOXPRO

CH. 3

• SKIP < number > moves the pointer the indicated number of
records from the current record. The number can be positive
or negative.

You will see in the next section that there is an easy way of seeing the
contents of the target record when you are working from the Com¬
mand window, without opening the Browse window.

SHORTCUTS USING
THE COMMAND WINDOW _

There are two commands for viewing the file that are very useful
when you are working in the Command window or programming
and that have no equivalent in the menu system.

• DISPLAY displays the contents of the current record on the


screen.
• LIST displays the contents of all the records on the screen.

Both DISPLAY and LIST display records behind the windows. If


any windows are opened, you might have to hide them to see the
records. Both commands will display all the field names at the top of
the display. In general, databases are too wide to fit all the fields
across one screen, but FoxPro will wrap the display to the next line if
it is too wide to fit otherwise. You can also use the DISPLAY and
LIST commands with the names of the specific fields you want to see.
For example, the command

LIST FNAME, LNAME, WAGE

would show you only those three fields of all the records in the data¬
base. Notice that the field names must be separated by commas. This
form of the command lets you choose few enough fields that you can
fit them into the width of one screen.
You will see in Chapter 5 that many commands can be used with
this sort of field list. In some cases the word FIELDS must also be
ADDING, EDITING, AND VIEWING DATA 107

added before the list of fields; to avoid having to learn which com¬
mands require it, it is best to include it whenever it is relevant. Thus,
it is easiest to use the command

LIST FIELDS FNAME, LNAME, WAGE

here, and this is the form these sorts of commands will take through¬

B Like all commands


DISPLAY can be
out the book.
It is easy to look at individual records in the database, then, by
abbreviated to its first
combining GOTO or SKIP commands with the
four letters: just type
DISP. DISPLAY FIELDS <fieldnames>

command. Once you get the DISPLAY command right, with the
fields that you actually want, you can move the pointer to a different
record by moving the cursor to the appropriate commands in the
Command window and then reusing the DISPLAY command.
The limitation of the LIST command is that most database hies are
too long to fit on a single screen, and the records in the database will

D To clean up your
printout while also
scroll by on the screen too quickly for you to read them if you use
LIST. It can be genuinely useful, however, if you add TO PRINT at
the very end of the command, which will send the listing to the
making a more useful
record of the listing, you
printer as well as to the screen. This is usually the easiest way of get¬
can use LIST TO FILE ting a quick-and-dirty report on the data in your hie.
Kfile name > instead of LIST normally displays the record number of each record, but you
LIST TO PRINT. This
can make the printed report look better by displaying the helds with¬
version of the command
will create the same out the record number. Do this by adding OFF after the held list and
listing in a plain DOS before the words TO PRINT when entering the LIST command. For
text file (also called an
example, if you have a database of names, addresses, and telephone
ASCII file). The advan¬
tage to this is that you can
numbers, and you want to give someone a printed list of just the
edit this file with any names and phone numbers, the absolutely easiest way to do it is by
word processor that reads entering
plain text files. The word
processor will automati¬
cally handle the page
LIST FIELDS FNAME, LNAME, PHONE OFF TO PRINT
breaks, and if you change
the column headings a bit (assuming, of course, that these are the names of the helds). This will
and add a header or give you a printed list of all the names and phone numbers in the hie,
footer for each page,
you’ll have a fairly
in three columns, with the name of the held at the top of each
respectable looking column. Note that long lists will print continuously, without allowing
report. for page breaks.
108 MASTERING FOXPRO

CH. 3

As a precaution, it is usually best to enter the command without


TO PRINT first, to make sure that you have the fields that you want
and that they actually fit into the width of the screen—which is the
same as the width of the paper in a standard printer. If it is a long file,
it will take time to list, but you can press Esc to stop the process. Once
you have the fields right, use the up arrow key to edit the command,
and add TO PRINT.
Try these steps to get a report on employee wages:

1. If necessary, close the Browse window and return to the


Command window. Enter CLEAR to clear the screen.

2. Enter

LIST FIELDS LNAME, FNAME, WAGE OFF

The listing is shown in Figure 3.17.

3. If you want to try printing this listing, use the conventional


editing keys to add TO PRINT to the end of the listing com¬
mand, and press Enter.

1 System File tdit. Database Record Program Window


LNAME FNAME WAGE
Levy Audrey 8.00
LOVE JACK 16.20
CHANG EDNA 9.75
SAGORIN CHARLOTTE 22.75
JOHNSON WILLIAM 6.25
JOHNSON WILLIAM B. 19.70
NIXON NANCY 18.25
SKINNER JAMES 8.20

Figure 3.17: Using LIST to get a very quick report.


ADDING, EDITING, AND VIEWING DATA 109

Of course, one of the names is not properly capitalized, and the


names are not in alphabetical order. But in Chapter 4 you will learn
enough about expressions and indexes to deal with these problems.
And in Chapter 5, when you have also learned about queries, you
will use the LIST command again to produce a fairly respectable
report.
You can also use BROWSE or CHANGE or EDIT in the Command
window with this sort of field list. These options are particularly useful to
fit all the information you want into the Browse window. You may also
find it handy to use BROWSE with the option NOEDIT, so that you
cannot make changes in the data inadvertently.

1. Enter

BROWSE FIELDS LNAME, FNAME, WAGE NOEDIT


to see just these fields in the Browse window, as shown in Fig¬
ure 3.18.

2. Try editing one of the fields and you will see that is it impos¬
sible. FoxPro just beeps and does not change the data. This is
because you included NOEDIT in your command.

System File Edit Database Record Program Window Browse


EMPLIST . r. ■
Lname Fname

leyy [Audrey
LOVE JACK 16.20
CHANG EDNA 9.75
SAGORIN CHARLOTTE 22.75
JOHNSON WILLIAM 6.25
JOHNSON WILLIAM B. 19.70
NIXON NANCY 18.25
SKINNER JAMES 8.20

k Command

Figure 3.18: The Browse window if you use BROWSE with a field list.
110 MASTERING FOXPRO

CH. 3

3. Close the Browse window. If you then enter BROWSE LAST,


you will notice that the same options are still being used.

4. To return the Browse window to its default configuration so


that you will be able to see all the fields in future exercizes,
enter BROWSE in the Command window, then close the
Browse window again.

There are many other options of this sort that you can use from the
command line. If you are interested in them, see BROWSE, EDIT
(or CHANGE), and APPEND in Appendix C. Field lists can be used
with many other commands besides these, and they will be covered
in more detail in Chapter 5.
t
U nderstanding
Indexes and Expressions

*
M

To create a simple index, 117


select New from the file menu, select the Index radio button,
then select the OK text button to use the Index On dialog box.
Select a file from the scrollable list in this dialog box to create a
simple index based on a single field. Select OK, and FoxPro
prompts you to name the index.

To create expressions, 121


you may select the Expr text button from the Index On dialog
box to call up the expression builder. Within a single expression
you may combine field names, memory variables, constants
(also called literals), functions, and operators, but a single
expression must contain only one data type. You can use func¬
tions to change the data types of parts of an expression, so that
all of its parts are consistent. Functions and operators are
selected from the popup controls of the expression builder,
which let you choose them by data type.

To change the capitalization of character data, 127


use the functions UPPER(<c/z<2r exp>) to capitalize a character
expression, LOWER(<c/mt-£*/?>) to make it all lowercase, and
PROPER(<cA<2r exp>) to capitalize the first character of each
word and make the other characters lowercase.

To remove unnecessary blanks from character data, 129


use the functions TRIM(<c/z<2r exp>) to trim trailing blanks,
LTRIM(<cA<2r exp>) to trim leading blanks, and ALLTRIM
(<char exp>) to trim both leading and trailing blanks.

To convert data from one data type to another, 129


use the functions VAL( < char exp >) to convert character data to
numeric data, DTOC(<dateexp>) to convert date to character
data, CTOD(<c/zar exp>) to convert character to date data,
and STR(< number exp > [, length] [, decimals]) to convert numeric
data to character (sometimes called string) data.

To work with dates, 131


use the functions DATEQ to return the current system date,
DAY(), MONTH(), or YEAR() to return the day, month, or
year of a date in number form, DOW() to return the day of the
week in number form, and CDAYQ, CMONTHQ, or
CDOW() to return the day, month, or day of the week of a date
in character form.

To include numeric calculations in functions, 134


use the arithmetic operators: + for addition, - for subtrac¬
tion, * for multiplication, / for division, ~ or ** for exponenti¬
ation (raising to a power), and () for grouping.

To create an index that alphabetizes records by name, 141


use the expression builder to index on the expression UPPER-
(LNAME + FNAME). This expression uses the first name as
a tie breaker, so the names are in correct order even if two peo¬
ple have the same last name. It also compares names in upper¬
case form, so they are in correct order even if one is capitalized
and the other is not.

To maintain multiple indexes using the Command window, 155


simply include the names of all the indexes in the command
when you open the database file. The first index mentioned is
the main index that sets the order of the records.
116 MASTERING FOXPRO

CH. 4

AN INDEX OF A DATABASE FILE IS A BIT LIKE AN INDEX


of a book. A book’s index lists subjects covered in the book in alpha¬
betical order and refers you to the pages that they are on. Of course,
it is much faster to look something up in the index and go to the right
page in the book than it is to leaf through the entire book in order to
find the topic that you are interested in.
If you are working with even a moderately large database file, any
database program takes a long time to read through the entire file to
look up a record you want. Even a very small business could easily
have a mailing list with a thousand names in it. If you had to look up
a few names in a list this long, there could be agonizing delays if your
program had to read through the entire list to find them.
On the other hand, the program could find the name very quickly
if the file were indexed. The index would list just the names in alpha¬
betical order and contain pointers showing where each name was in
the actual database. There are methods of searching that let a data¬
base management program find a name very quickly in this sort of
ordered list so that the program can retrieve records in large data¬
bases without any delay.
Of course, the computer can also use an indexed database much
more powerfully than a person can use an indexed book. For
example, the computer can list the entire database in index order so
the user can look at the records in the database in alphabetical order
by name, even though the actual order of the records in the database
is different. Since you can have several different indexes for a single
database, you can use the database in more than one order: you can
look at the records in alphabetical order to find people’s names, and
then you can look at the records in zip code order to see which people
live near each other.

USING SOME SIMPLE INDEXES __

Some indexes are more complex than others. For example, if you
want to use names in alphabetical order, you would not only index on
the last name: in order to make sure that Aaron Smith comes before
Xavier Smith, you need to use the first name as a “tie-breaker” to
determine the order of records whose last names are the same. Fur¬
thermore, as you will see, a name entered using lowercase letters
UNDERSTANDING INDEXES AND EXPRESSIONS 117

would come after a name that is entered in all capital letters. In the
next section, you will learn to use expressions, which let you deal with
this sort of problem.
To begin with, though, you can create a couple of simple indexes,
each of which is based on a single field. Let’s say that you need to use
the records in zip code order when you produce your mailing labels,
and that you also need to produce a special report that uses the
records in order of the date the employee was hired. Try creating
these indexes:

1. Start FoxPro if necessary, making sure that you are in the


\LEARNFOX subdirectory. If you want, enter CLEAR to
clear the screen. Select Open from the File menu and select
EMPLIST.DBF from the Open dialog box. A database file
must be open before you can create an index for it.
2. To create the index file, select New from the File menu.
Select the Index radio button in the New dialog box, and
then select the default text button, OK.

3. The Index On dialog box appears. The scrollable list in this


box lets you index on a single field. If you select a field name
from the scrollable list, its name appears to the right of the
Expr (Expression) text button, since you are actually index¬
ing on an expression made up of one field. Select ZIP from
the scrollable list and, after ZIP appears as the expression, as
in Figure 4.1, select the default text button, OK.

D As you will see,


managing the data¬
4. FoxPro prompts you to enter the index file name. Notice the
popup controls to let you change drive or to move quickly
base can become a bit
through the subdirectory structure, the scrollable list of file
confusing after you have
multiple indexes. To names and subdirectories, and the check box that lets you list
make your life simpler, All Files (rather than just index files); all of these work just as
always give index files
they do in the Open dialog box. You do not need to use any
descriptive names, such
as ZIPS.
of these features now, so simply type ZIPS as the name of the
index, as shown in Figure 4.2. Then select the default text
button OK. That is all you need to do to create the index.
Notice that at this point “talk” appears on the screen to tell
you how many records were indexed.
118 MASTERING FOXPRO

CH. 4

System File Edit Database Record Program Window

INDEX ON:

LNAME c
ADDRESS c
APT NO c « OK »
CITY c
STATE c < Cancel >
1 ZIP C
l
<@xpr. . . > ZIP

[ 3 Enique
<flor... > ommand

ST.DBF

Figure 4.1: Indexing on one field.

System File Edit Database Record Program Window

M
DBF

1
Figure 4.2: Naming the index file.
UNDERSTANDING INDEXES AND EXPRESSIONS 119

5. Select Browse from the Database menu to look at the hie:


scroll right until you can see the Zip held, and note that the
records are in zip code order. Or move the Zip held to the far
left (as you learned to do in the last chapter) so you can see the
zip code along with the names, as in Figure 4.3. Close
the Browse window.

6. You will be repeating essentially the same steps to create


another index on the Date_hired held: Select New from the
File menu. In the New dialog box, select the Index radio but¬
ton, then select OK. In the Index On dialog box, select
DATE_FIIRED from the scrollable list, and select OK. In
the Index File Name dialog box, type DATES, and then
select OK.
7. Now select Browse from the Database menu, and scroll right
until you can see the Date_hired held, or move this held to
the far left so you can see it along with the zip codes and
names. Note that the records are now listed from the earliest
to the most recent date (and are no longer in zip code order),
as in Figure 4.4. Close the Browse window.

System I i 1 <' I ill I I).it ,ih.i:ii' Rncoi il IYoi|i am Window l|row;m


I I Ml M l S I WM
Fname Lname Address

07 000 CHARI 01 I I sac,ok IN


07200 JACK LOVE 5642 TANACH WA
10022 WILLIAM JOHNSON 525 EAST 21 ST
11226 WILLIAM B. JOHNSON 1701 ALBEMARLE
11600 Audrey Levy 518 B. 51 St.
94-025 JAMES SKINNER 1206 FRANCISCO
94500 NANCY NIXON 1124 GRANT AVE
94706 EDNA CHANG 2701 ADDISON W

Figure 4.3: The records displayed in zip code order.


120 MASTERING FOXPRO

CH. 4

System File Edit Database Record .Program Window Browse


EMPLIST
Date_hired Zip Fname Lname Ad]
i
■04/23/76 | 1100221 IWILLI.AM 523
07/16/81 11600 Audrey Levy 318
06/06/82 07000 CHARLOTTE SAGORIN 220
02/01/84 94300 NANCY NIXON 112
09/07/88 94706 EDNA CHANG 270
12/01/88 94025 JAMES SKINNER 120
06/04/89 07200 JACK LOVE 364
12/15/89 11226 WILLIAM B. JOHNSON 170

* Command
_jN ZIP TO C:\LEARN
BROWSE LAST
INDEX ON DATE_HIRED TO C
BROWSE LAST

Figure 4.4: The records displayed in order of date hired.

8. If you changed the configuration of the Browse window to dis¬


play the records as shown in the illustrations, enter BROWSE in
the Command window to use the Browse window in its default
configuration. Then close the Browse window, saving the
default configuration.

Perhaps you were curious about why the Index On dialog box that
lets you name the index includes a scrollable list of the names of exist¬
ing indexes. You can choose one of these names if you want to over¬
write an existing index, replacing it with an index of the same name
based on the expression you have created—as you will do later in this
chapter, when you index by name in two different ways.
There are two other features of this dialog box that you do not need
to worry about for now. The For text button lets you index only
records that meet certain logical criteria; this is essentially a matter of
building a query into an index, which will be covered in Chapter 5.
The Unique check box excludes records with duplicate values in the
field that you are indexing on; thus, only the first record that FoxPro
finds with a given value in that field is indexed. This is an advanced
UNDERSTANDING INDEXES AND EXPRESSIONS 121

feature, useful only with relational databases (which will be covered


in Chapter 7), and it should be used with great caution to avoid over¬

B If you have dBASE


files with .NDX
looking data.
When you used the Index File Name dialog box to create indexes,
indexes, FoxPro automat¬
“talk” appeared telling you how many records were indexed, and
ically converts them to FoxPro also generated the command
.IDX indexes the first
time it uses them. If you INDEX ON ZIP TO C:\LEARNFOX\ZIPS.IDX
want to use them with
dBASE again, keep a
copy of the original
(and a similar command for the DATE_HIRED index) in the Com¬
indexes. You can con¬ mand window. FoxPro index names always have the extension
vert indexes from other .IDX. Different dBASE compatible programs have come up with
compatible programs
yourself, either by con¬
different methods of indexing, and they use different file extensions
verting them to .NDX to show that these indexes cannot be used interchangeably. For
indexes (if the program example, dBASE indexes have .NDX extensions. FoxPro indexes
has a utility that does so),
(with .IDX extensions) usually take up much less disk space than the
or by creating new Fox¬
Pro indexes from scratch, others.
using FoxPro to index on If you are creating indexes from the Command window, you do
the same fields or expres¬
not have to include the full path name (if the index is in the current
sions as the original
indexes.
directory) or the extension. You can just enter the command INDEX
ON ZIP TO ZIPS. Once you get used to it, entering the commands
in this manner is easier than using the menu system.

UNDERSTANDING EXPRESSIONS _
Though simple indexes are useful for many purposes, there are
times when they are not adequate—times when you want to index on
an expression rather than just on a field. As you have seen, you can¬
not simply index on the Lname field to put the records in alphabetical
order, since you also have to use the Fname field as a tie breaker.
In addition, you must make the index put capital and small letters
in proper alphabetical order, since, by default, FoxPro indexes
in ASCII order. You will be better at using FoxPro if you take a
moment to understand what this means. ASCII stands for American
Standard Code for Information Interchange. Just as Morse code rep¬
resents each letter with a series of dots and dashes, ASCII represents
each character with a number. The lowest numbers represent what
are called control characters, such as carriage return. The first of the
122 MASTERING FOXPRO

CH. 4

actual keyboard characters is ASCII character 32, which represents a


blank space. After some punctuation marks and special characters
come ASCII characters 48 through 57, which represent numbers.
After some more special characters come the capital letters from A to
Z, which are ASCII characters 65 to 90. And after a few more special
characters come the small letters from a to z, ASCII characters 97 to
122. IBM-PC compatible computers also have what is called
extended ASCII, with even higher numbered characters for foreign
letters and for box-drawing characters.
If you simply index on a field, FoxPro will order the information
using ASCII numbers, and consider all small letters to come after all
capital letters. Expressions let you overcome this problem and many
others. They are useful not just in indexes but in almost everything
you do in FoxPro, from producing simple mailing labels to writing
advanced programs.
Later in this chapter, you will learn to create expressions using the
“expression builder” dialog box, shown in Figure 4.5. Once you get
accustomed to expressions, though, you will simply type them in.

System, File Edit Expression '

Math String Logical Date

Field Names: Database: Variables:

►EMPNO EMPLIST ►_ALIGNMENT


FNAME B0X
LNAME _INDENT
ADDRESS < Verify > _LMARGIN
APT_N0 _PADVANCE
CITY « OK » _PAGEN0
STATE _PBPAGE
ZIP < Cancel > PCOLNO

Figure 4.5: The expression builder dialog box.


UNDERSTANDING INDEXES AND EXPRESSIONS 123

An expression can include several elements:

• field names

• memory variables
• constants (or literals)

• functions

• operators

Field names, of course, are simply the names that you gave the fields
of your database, such as FNAME and LNAME. As you will see,
the names of all the fields in the database you are working with can be

9 FoxPro automati¬
cally creates certain
selected from a scrollable list in the expression builder dialog box.
Memory variables are used in more advanced expressions, and are

memory variables when it


useful primarily in programming. You will learn about them in
runs, which are called Chapter 8. The names of all active memory variables can also be
system variables. Their selected from a scrollable list in the expression builder dialog box, but
names always begin with
you will ignore them for now.
the underscore character:
for example, one is
named _ALIGNMENT.
These will be included in CONSTANTS
the Variables scrollable
list; you will learn to use Constants (or literals) are letters, numbers, or dates that are used
one of them in Chapter 6. with their literal meaning. For example, if you wanted an expression
to actually include the word “Name:” before each person’s name,
you would use the constant “Name:” as part of that expression.
These are called constants because they are always the same, unlike
the first name and last name, for example, which change for each
record.
Constants that are used in expressions must include delimiters to

H lf you forget to use


delimiters for a
indicate their data type.

• Character constants: must be enclosed in double quotation


character field, FoxPro will
think it is the name of a
marks, single quotation marks, or brackets. For example, you
memory variable or of a could use “Name:” or ’Name:’ or [Name:] in an expression to
field. If you get a puzzling make it include Name:
error message saying that a
variable cannot be found, • Date constants: must be enclosed in curly brackets. If you
it probably means that you wanted to create an expression that calculated the number of
mistakenly used a charac¬
ter constant without
days to the end of the year, for example, it would include a
delimiters. constant such as {12/31/90}.
124 MASTERING FOXPRO

CH. 4

• Number constants: are used without any delimiter. Simply


use the number itself.

When you are working with constants, you have to remember that
an entire expression must be of a single data type. Sometimes you
must convert literals or fields from the date or number type to the
character type in order to make them compatible with the rest of
the expression. This is where functions come in handy.

FUNCTIONS AND OPERA TORS


The four popup controls at the top of the expression builder dialog
box divide all of FoxPro’s functions and operators into four different
types, depending on the type of data they work on. The Math popup
lets you work with numeric data, the String popup with character
data, the Logical popup with logical data, and the Date popup
with date data.
Logical expressions are usually not needed in indexes, so they will
not be discussed here. (They will be presented in the next chapter,
which covers queries.) Figure 4.6 illustrates the three popups you will
be working with in this chapter. As you can see, there are often too
many operators and functions to fit in the popup, but you can scroll
down to get more. Notice the word ‘Text” at the top of the String
popup; you can select this to put the quotation mark delimiters
around text that you enter. Of course, you can also type in the quota¬
tion marks by hand.
? always prints the While you are learning about expressions, you will find it instruc¬
results of the expres¬
tive to try them out by using the ? command, which prints an expres¬
sion, preceded by a new
line. In Chapter 11, you
sion to the screen. For example, if you enter the command ? “THIS
will also learn to use ?? to IS A TEST” in the Command window, the words THIS IS A TEST
print an expression with¬ will appear on the screen, in the same place where the “talk”
out a new line. If you just
use ? without an expres¬
appears. Notice that ?, like all other commands, always evaluates an
sion following it, it will expression. For example, if you enter ? FNAME, FoxPro prints the
just print a new line: this content of the current Fname field. This example used ? with an
is an easy way to skip
expression made up of a single string constant. You will see how
a line.
functions and operators work by using ? with more complex
expressions.
UNDERSTANDING INDEXES AND EXPRESSIONS 125

System- File Edit Expression

r
I
IN
tL

ABS()
ring Logical Date

ACOS()
ASC( )
ASIN()
F AT( , ) Database: Variables:
ATC(,. )
► FN ATCLINE(,) EMPLIST ►_ALIGNMENT C
LN ATLINE(. ) BOX L
AD ATAN() -INDENT N
AP ATN2(, ) < Verify > _LMARGIN N
Cl BAR( ) PADVANCE C
ST CEILING() « OK » “PAGENO N
ZI C0L() J>BPAGE N
DA COS( ) < Cancel > PCOLNO N
DIFFERENCE(.)
DISKSPACE()
ERROR()
-▼-

System File Edit. Expression

"text"
p +
Math gical Date
ft
r INDEX ON: <expr" ALIASt)
ALLTRIM()
CHR( )
CHRTRAN(, )
CURDIR()


Field Names: DBF( ) Variables:
FIELD()
►FNAME c Pj FILTER() ►—ALIGNMENT C
LNAME c n FGETS(,) -BOX L
ADDRESS C 1 FKLABEL( ) -INDENT N
APT NO c I FREAD(, ) -LMARGIN N
CITY c 1 FULLPATH(, ) -PADVANCE C
STATE c 1 GETENV( ) -PAGENO N
ZIP c 1 GETFILE(, ) _PBPAGE N
DATE HIRED D | LEFT(, ) PCOLNO N
LOWER()
LTRIM()
MESSAGE( )
-▼-

Figure 4.6: The Math, String, and Date popups in the expression builder
dialog box.

FUNCTIONS
S A function does not
actually transform or
A function returns a value. Usually this means that a function
works on a piece of data in some way and that the ‘Value” it returns
permanently change the
is the data in a new form. For example, the index you create at the
data it is working on. It
merely lets the expression end of this chapter will use the function UPPER() to convert lower¬
use it in this new form. case characters to uppercase. You will use this function in the form
UPPER(LNAME) to return the data in the Lname field with all the
System File Edit Expression

Math String Logical CDOW()


CMONTH( )
INDEX ON: <expr> CTODf )
DATE( )
DAY( )
DMY( )
DOW( )
Field Names: Database: DTOC()
GOMONTH(, )
►FNAME C EMPLIST AL MDY()
LNAME C 'BO MONTH()
ADDRESS C 'IN SECONDS()
APT_NO C < Verify > 'LM TIME()
CITY C 'PA YEAR()
STATE C « OK » PA
ZIP
DATE HIRED
C
D < Cancel >
PBPAGE
"PCOLNO
B

Figure 4.6: The Math, String, and Date popups in the expression builder
dialog box. (continued)

letters capitalized so that a name originally written with lowercase let¬


ters will be arranged in correct alphabetical order rather than in
ASCII order.
Some functions return a value that depends on the system. For
example DATE() returns the current system date. Logical functions,
which you will look at in the next chapter, return a value of True or
False. Note that all functions end with parentheses, even functions
such as DATE() that never have anything in the parentheses.
Try these two functions out:

1. Enter ? to skip a line. (You must of course press Enter after


the ? to make the cursor move.)

2. Enter ? UPPER(“this is a test”). FoxPro prints THIS IS A


TEST on the screen.

3. Enter ? DATE(). FoxPro prints the system date, as shown in


Figure 4.7. (Of course, the actual date on your screen will
differ from the date in the illustration.)
UNDERSTANDING INDEXES AND EXPRESSIONS 127

System t ile Idit Database Record" Program Window


8 records indexed
8 records indexed

THIS IS A TEST
12/12/90

Figure 4. 7: Using ? to print expressions.

FoxPro offers a tremendous number of functions, as you will see


when you use the scrollable list to choose them. Until you begin pro¬
gramming, though, you can get by with a relatively small number of
functions. The most important are listed here.
These functions act You will find the following functions useful for changing the case of
only on letters and
do not affect any numbers
character data. (The abbreviation char exp within the arrow brackets
or special characters that stands for character expression.)
are included in character
fields. • UPPER(<c/iar exp>) converts letters to uppercase. For
example, UPPER(FNAME) returns the contents of the
Fname field in all uppercase letters, and UPPER(“hE110”)
returns the word HELLO.
• LOWER(<cAar exp>) converts to lowercase, as you might
expect. For example, LOWER(FNAME) returns the
contents of the Fname field in all lowercase letters, and
LOWER(“hEUO”) returns hello.
• PROPER( < char exp > ) converts to the capitalization used for
a proper name, with the first letter of each word capitalized
and rest lowercase. For example, PROPER(ADDRESS)
returns the contents of the Address field, with the first letter
128 MASTERING FOXPRO

CH. 4

of each word capitalized, as you would normally want on


mailing labels. PROPER(‘‘hEllCf’) returns Hello.

Try testing these functions on the fields of your database. Your


database file should still be open with the DATES index, since you
indexed it earlier in this chapter. (If it is not, select Open from the
File menu to open EMPLIST.DBF; then, if you want your results to
match the illustrations, select Open again and open the DATES-
.IDX index.)

1. Enter ? to skip a line.


2. Enter ? LOWER(FNAME) in the Command window. Fox¬
Pro will print the Fname field of the current record in all low¬
ercase letters (even though you entered it in all uppercase).

3. Enter ? PROPER(ADDRESS) in the Command window. Fox¬


Pro will print the Address field of the current record with just
the first letter of each word capitalized, as shown in Figure 4.8.

System File Edit Database Record Program Window


8 records indexed
8 records indexed

THIS IS A TEST
12/12/90

william
523 East 21 St.

Figure 4.8: Using functions to change the capitalization of character data.


UNDERSTANDING INDEXES AND EXPRESSIONS 129

The next group of functions are useful for trimming blanks from
character data. This is often necessary, because when you tell it to
print the held Lname, for example, FoxPro not only prints the char¬
acters that are in the held, it also adds enough blanks at the end to hll
the entire width of the held. These are called trailing blanks. Relat-
edly, if you convert a numeric held to the character type, FoxPro
often adds blanks to the left of the number to pad it out. These are
called leading blanks. Although there are times when blanks
are indispensable (as you will see when you create your next index),
there are also times when you want to get rid of them.
If you want, for example, to produce mailing labels or reports without
unnecessary blank spaces in them, you would use these functions:

• TRIM(<c/iar exp>) trims trailing blanks.

• LTRIM( <char exp>) trims leading blanks.

• ALLTRIM(<cAar exp>) trims both trailing and leading


blanks.

Try these out:

1. Enter ? to skip a line.

2. Enter ? TRIM(“ THIS IS A TEST ”). FoxPro will


indent the words THIS IS A TEST when it prints them,
allowing for the leading blanks. (In this case, you cannot see
that the trailing blanks have been trimmed.)

3. Enter ? LTRIM(“ THIS IS A TEST ”). FoxPro will not


indent the words THIS IS A TEST when it prints them,
since it has trimmed off the leading blanks, as shown in Fig¬
ure 4.9. The trailing blanks are still there, but you cannot
see them.

The next group of functions is useful for converting data from one
data type to another, which is necessary when you are creating an
expression that combines data that is originally of two different types:

• VAL(<char exp>) converts character data to numeric data.


For example, if you ever wanted, for some strange reason, to
130 MASTERING FOXPRO

CH. 4

System File Edit Database Record Program Window


8 records indexed
8 records indexed

THIS IS A TEST
12/12/90

william
523 East 21 St.

THIS IS A TEST
THIS IS A TEST

Figure 4.9: Using functions to trim blanks from character data.

perform a calculation using a zip code, you could not per¬


form it on Zip directly, since that field has been defined as the
character type, but (again, if you ever had a reason to) you
could perform a calculation on VAL(ZIP).

• DTOC(<dateexp>) converts date data to character data. For


example, DTOC(DATE_HIRED) would return the con¬
tents of the Date__hired field as a character string.

• CTOD(<ckr exp>) converts character data to date data.


Older dBASE com¬
patible programs For example CTOD(“ 10/12/90”) uses the quotation mark
did not include the curly delimiters to define 10/12/90 as a literal character string and
bracket delimiters for the uses the CTOD() function to convert the string to the date
date type, and the only
way to use a date con¬
type. It is identical to {10/12/90}, which uses the curly
stant was in the form of bracket delimiters to define 10/12/90 as being the date type.
CTOD(“ 10/12/90”).
For this reason, you will • STR( < number exp > [,length][,decimals]) converts numeric
see this form used fre¬ data to character (sometimes called string) data. Notice the two
quently if you ever look at
optional clauses for length and decimals. If these are left out, the
older books about dBASE
or older programs written default length of the string is 10 spaces and the default number
in dBASE compatible of decimal places is 0: any extra length is thus padded out with
languages. leading blanks and any decimal places are lost.
UNDERSTANDING INDEXES AND EXPRESSIONS 131

You will be trying out a few of these functions in the next section
when you use operators to create more complex expressions. For
now, you should try the STR() and VALQ functions, which are quite
commonly used.

1. Enter ? to skip a line.

2. Enter ? WAGE and FoxPro prints 6.25, the contents of the


current Wage field, indented one space to allow for the tens
digit that is blank in this record.

3. Enter ? STR(WAGE) and FoxPro prints 6, indented nine


spaces. This shows the default width for STR(), with no deci¬
mals and ten spaces wide.

4. Enter ? STR(WAGE,5,2) and FoxPro prints 6.25, indented


one space. The function returns a value that is five spaces
wide (counting the blank tens place and the decimal point as
taking one space each) including the two decimal places. This
looks the same as it did when you entered ? WAGE, as you
can see in Figure 4.10, but the difference is that now it is a
character string that is being printed.

5. Compare these preceding STR() examples with VAL():


Enter ? VAL(“10”), and FoxPro prints 10.00. By default, it
prints two decimal places.

Next are a few functions that you will want to use on occasion to
manipulate dates.

• DATEQ returns the current system date (determined from


when you booted up your computer or, if you have one, the
date in your computer’s clock/calendar).

• DAY(), MONTHQ, or YEAR() return the day, month, or


year, respectively, of a date in number form. For example,
since the date hired for the current record is 04/23/76,
MONTH(DATE_HIRED) is 4.

• DOW() returns the day of the week in number form. For


example, since June 14, 1990 is a Thursday, and since
Thursday is the fifth day of the week, DOW({06/14/90})
returns 5.
132 MASTERING FOXPRO

CH. 4

8 records indexed
8 records indexed

THIS IS A TEST
12/12/90

william
523 East 21 St.

THIS IS A TEST
THIS IS A TEST

6.25
6
6.25
10.00

Figure 4.10: Using STRQ to convert a number to characters and VALQ to


convert characters to a number.

• CDAYQ, CMONTH0, or CDOW() return the day, month, or


day of the week, respectively, of a date in character form. For
example, CMONTH(DATE_HIRED) returns April for the
current record.

You have already tried DATE(). Take a minute now to try out a
couple of other date functions:

1. Enter ? to skip a line.

2. Enter ? CDOW({06/06/90 }) to get the day of the week for that


date. FoxPro prints Wednesday.

3. Enter ? CMONTH(DATE_HIRED) to print the name of the


month that the employee in the current record was hired, as
shown in Figure 4.11.

Finally, two other functions that you might find instructive, even if
they are not necessary, are ASCQ, which returns die ASCII number of
any character, and the opposite function CHR(), which returns the
UNDERSTANDING INDEXES AND EXPRESSIONS 133

System File Edit Database Record Program Window


8 records indexed
8 records indexed

THIS IS A TEST
12/12/90

william
523 East 21 St.

THIS IS A TEST
THIS IS A TEST

6.25
6
6.25
10.00

Wednesday
April

Figure 4.11: Using functions to work with dates.

character for an ASCII number. For example, CHR(65) returns A,


since the capital A is ASCII character 65. Likewise, ASC(“A”) returns
the number 65. With these functions and ? you can use FoxPro as an
ASCII chart. For example, ? ASC(“z”) lets you look up the ASCII
number of that character: FoxPro prints 122 in response. These func¬
tions will be useful when you get to programming. You might also find
that fooling around with them now will help you learn the ASCII
system.
It often makes sense to read the parentheses of a function as if they
were the word “of. ” For example, many people find that if they read
TRIM(FNAME) as “the trim of Fname” or read VAL(ZIP) as “the
val of Zip, ’ ’ then it is easier for them to keep track of the meaning of
Within an expres¬ the functions.
sion as a whole, the You can also use functions within functions. For example, if you
number of left parenthe¬
use STR() to return the number in the Wage field as a character
ses must be equal to the
number of right paren¬ string, it will have leading blanks which you might not want. Since
theses. In complex wages are different amounts and some strings may be longer than
expressions, it is useful to others, you cannot get rid of all the leading blanks with the STR()
count them to make sure
function itself: STR(WAGE,5,2) will have a leading blank if the
you have not left any¬
thing out. amount is less than ten. You can use LTRIM(STR(WAGE,5,2)) to
134 MASTERING FOXPRO

CH. 4

get rid of these leading blanks. The double parentheses at the end
might seem a bit confusing at first, but if a complex expression con¬
fuses you, remember that it is evaluated from the inside out. First
look at the innermost function, STR(WAGE,5,2) in this case. Once
you understand that this is a number converted into string form, it is
easy to see what LTRIM0 is doing to it.

1. Enter ? to skip a line.

Enter ? STR(WAGE, 10,2) to see the wage with a number of


leading blanks, and then enter ? LTRIM(STR(WAGE, 10,2))
to see the same wage without any leading blanks.
Enter ? CDOW(DATEQ) and FoxPro will print the day of the
week that it is today, as shown in Figure 4.12 (though, of
course, your current date will differ).

OPERATORS
The word “operators” sounds very technical and forbidding, but
even if you have never used a computer before, you are already
familiar with some operators, such as + and -, which are used to

System F^ile Edit- Database Record Program Window


8 records indexed
8 records indexed

THIS IS A TEST
12/12/90

william
523 East 21 St.

THIS IS A TEST
THIS IS A TEST

6.25
6
6.25
10.00
Command
Wednesday
April

6.25
6.25
Wednesday

Figure 4.12: Using functions within functions.


UNDERSTANDING INDEXES AND EXPRESSIONS 135

perform the operations of addition and subtraction in elementary


arithmetic. FoxPro includes the usual arithmetic operators and simi¬
lar operators that are used for strings and dates.
The arithmetic operators are:

+ addition

- subtraction

* multiplication

/ division
~ or exponentiation (raising to a power)
* *

() grouping—not a substitute for multiplication

Most of these signs should be familiar. Like virtually all computer


applications and languages, FoxPro uses the asterisk for multiplica¬
tion, instead of the x sign or even the parentheses commonly used in
arithmetic or algebra. Since most computer monitors cannot use a
superscript to represent an exponent, many programs use the caret:
5^2 indicates that the 2 should be above the line as a superscript, so
that this stands for 5 squared (five to the second power). Some pro¬
grams also use * * (to indicate that exponentiation is a step beyond

B As you can see, you


cannot leave out the
multiplication); FoxPro lets you use either of these common symbols.
As in algebra, the parentheses are used for grouping, which indi¬
multiplication sign in
cates what is called the precedence of operations, that is, the order in
FoxPro as you do in which operations are performed. The difference that precedence
algebra. You cannot use makes is very obvious. For example, (2*3) +5 gives you a different
2(3 + 5) to indicate that
result than 2*(3 +5). In the first case, you multiply 2*3 first to get 6
3 + 5 is multiplied by 2.
The asterisk must always and then add 5, so the final result is 11. In the second case, you add
be included to indicate 3+5 first to get 8 and then multiply by 2, so the final result is 16.
multiplication.
If no parentheses are used, exponentiation takes precedence over
multiplication and division; and multiplication and division take
precedence over addition and subtraction. Though you probably
never thought about it, this is the order of precedence that you are
accustomed if you have gone through high school algebra. Think, for
example, about the value of the algebraic expression

2x3 + 4
136 MASTERING FOXPRO

CH. 4

If you’re familiar with the math, you know not to multiply 2 times x
first and then cube the result. Without any thought, you would cube
the value of x first, then multiply the result by 2, and then add 4. This
is the same order of precedence as in FoxPro: exponentiation, then
multiplication or division, then addition or subtraction.
In general, though, it is good to use parentheses to indicate precedence
even if the operations would occur in that order anyway, simply
to make the expression easier to read. For example, (2*WAGE) +4
gives the same result as 2*WAGE +4, but it is easier to understand
immediately when you read it. Likewise, because spaces are op¬
tional before and after operators, you should use whatever spacing
you need to make the expression easy to read.
Using the arithmetic operators with ? acts as a simple calculator, as
shown in Figure 4.13:

1. Enter ? to skip a line.

2. Enter ? 2*8 and FoxPro prints 16.


3. Enter ? 1/3 and FoxPro prints 0.33.

System File Edit Database Record Program Window

THIS IS A TEST
12/12/90

william
523 East 21 St.

THIS IS A TEST
THIS IS A TEST

6.25
6
6.25
10.00

Wednesday
April

6.25
6.25
Wednesday

16
0.33

Figure 4.13: Using FoxPro expressions as a calculator.


UNDERSTANDING INDEXES AND EXPRESSIONS 13 7

This works because, as we mentioned previously, a command always


returns results.
Notice that the FoxPro arithmetic operators print two decimal
places by default. You can vary the number of decimal places, how¬
ever, by using, for instance in the preceding example, STR(l/3,9,8)
to print eight decimals.
In addition to the arithmetic operators, FoxPro includes a simple
set of date and string operators.
Date operators simply let you add and subtract dates. They are the
same as the arithmetic addition and subtraction operators. Thus, +
adds dates. For example, {01/01/91} +90 gives the date that is
ninety days into calendar year 1991. Predictably, - subtracts dates.
For example, DATE() -DATE_HIRED gives you the number of
days between the current system date and the date hired for the cur¬
rent record—it tells you how long someone has been working for you.
Try these two simple date calculations:

1. Enter ? to skip a line.

2. Enter ? {06/06/90} - {05/06/90}. FoxPro prints 31, the


number of days between the two dates.
3. Enter ? DATE() + 7. FoxPro prints the date a week after the
current date, as shown in Figure 4.14.

String operators are used to concatenate strings, that is, to put two
strings together as one.

• + concatenates strings including blanks.

• - concatenates strings eliminating blanks.

The - to eliminate the blanks is simply a shortcut and is not actu¬


ally necessary.

FNAME - LNAME

is the same as

TRIM(FNAME) + TRIM(LNAME)
138 MASTERING FOXPRO

CH. 4

william
523 East 21 St.

THIS IS A TEST
THIS IS A TEST

6.25

6.25
10.00

Wednesday
April

6.25
6.25
Wednesday

16
0.33

12/19/90

Figure 4.14: Using FoxPro calculations with dates.

since these fields only have trailing blanks to trim. When you actually
work with FoxPro, you will find this shortcut very convenient. In this
book, though, we will generally use the + operator to concatenate
strings and will use functions to trim unnecessary blanks, in order to
get you accustomed to the trimming functions and to give you more
insight into what is happening when you concatenate strings.
Note that the string operators must be fiddled with a bit to print a
full name, since a simple - concatenation would not leave a space
between the strings. To print a name, you have to include a blank
space as a constant. For example,

TRIM(FNAME) + " " + TRIM(LNAME)

would give you something like JOHN SMITH. The quotation


marks may look strange at first, but you have to remember that they
are enclosing the blank between them, which is a literal, and that this
expression thus concatenates three character strings.
Even though the different types of operators look the same, you
cannot use them to combine characters with dates or numbers. First,
you must use functions to convert the data to the same data type.
UNDERSTANDING INDEXES AND EXPRESSIONS 139

Since it is a very common error to forget to do this, let’s make this


error on purpose so you can recognize what it looks like.

1. Enter ? to skip a line.

2. Enter

?'Today is " + DATE()


and FoxPro will display the alert shown in Figure 4.15. Its
error message is rather obscure, but you should remember to
connect it with this error, which is one of the most common
errors you will make when you work with expressions. Press
any key to make the alert disappear.

What the alert means, of course, is that “Today is ” is a different


data type from DATE(). Now let’s fix the problem.

3. Enter

? "Today is " + DTOC(DATE())


FoxPro will print a message that includes the current date.

System File Edit Database Record Program Window


523 East 21 St.

THIS IS A TEST
THIS IS A TEST

6.25
6
6.25
10.00

Wednesday
April

6.25
6.25
Wednesday
Command
16 - {05/06/90
0.33
Oporator/oporand typo misma t.ch.
31 " + DATE( )
12/19/90 ■ ■ r

Figure 14.15: An alert appears if data types are mixed.


140 MASTERING FOXPRO

CH. 4

4. Enter

? "The hourly wage of" + FNAME + LNAME +


" is " + WAGE
and FoxPro will display the same alert, because WAGE is a
different data type from everything preceding it. Press any
key to make the message disappear.

5. Use the up arrow key to edit the previous command. Enter

? "The hourly wage of" + FNAME + LNAME +


" is " + STR(WAGE)
FoxPro will now print the expression, but it will be filled with
unnecessary blanks and the wage will not have decimals.
(You may have to hide the Command window to see it all.)

a Despite the fact that


a lengthy command
6. Edit the command again. Enter

takes up more than one ? "The hourly wage of" + TRIM(FNAME) + " " +
line on a printed page, TRIM(LNAME) + " is " + LTRIM(STR(WAGE,5,2))
you should of course type
it as a single command The function TRIM() has eliminated the unnecessary
without hitting Enter blanks, but notice that you had to add a literal blank between
until you reach the end of
FNAME and LNAME so it did not come out
the whole thing. As long
as it is less than 255 WILLIAM JOHNSON
characters long, it will all
fit in the Command Likewise, do not forget to include the spaces after of and
window; you just have to before and after is.
scroll to see the entire
command. 7. Edit the command once more to get the capitalization right
and to add a dollar sign and a period at the end: Enter
? "The hourly wage of" + PROPER(TRIM(FNAME) + " "
+ TRIM(LNAME)) + " is $" + LTRIM(STR(WAGE5,2)) +
✓/ //

The results of this series of commands are shown in Figure 4.16.


The one other very common error, which you might have made
while you were doing this exercise, is using unbalanced parentheses.
Fortunately, the alert that tells you about this error is not difficult to
understand.
UNDERSTANDING INDEXES AND EXPRESSIONS 141

System File Edit Database Record Program Window


6.25

6.25
10.00

Command
? "The hourly wage of + FNAME + LNAME + " is " + WAGE
? "The hourly wage of + FNAME + LNAME + " is " + STR(WAGE)
? "The hourly wage of + TRIM(FNAME) + " " + TRIM(LNAME) + " is ' LTRIM(STR
? "The hourly wage of + PROPER(TRIM(FNAME) + " " + TRIM(LNAME)) ’ is $" +

16
0.33

31
12/19/90

Today is 12/12/90

The hourly wage of WILLIAM JOHNSON is 6


The hourly wage of WILLIAM JOHNSON is 6.25
The hourly wage of William Johnson is $6.25.

Figure 4.16: Getting a string expression right.

USING EXPRESSIONS IN INDEXES _

By now you should have a very solid understanding of expressions


and know more than enough to start creating complex indexes using
the expression builder. You will begin by creating an index using the
names in alphabetical order, and then go on to create another com¬
plex index that is useful for arranging records in descending order.

ALPHABETIZING BYNAME
As you have seen, to put your records in alphabetical order, you
need to index by last name using the first name as a ‘ die-breaker’ ’
when last names are the same. The way to do this is to index on the
expression LNAME + FNAME.
FoxPro alphabetizes by comparing the ASCII numbers of charac¬
ters in a word. The ASCII number for the blank character comes
before any of the characters that represent letters, and this fact is vital
142 MASTERING FOXPRO

CH. 4

for alphabetizing correctly. Thus, because fields in FoxPro are pad¬


ded with trailing blanks to fill their entire width; SMITH comes
before SMITHERS. FoxPro compares these names letter by letter to
alphabetize them, and when it gets up to the E in SMITHERS and
the first trailing blank following SMITH, it compares those two char¬
acters and decides that the blank, hence SMITH, comes first. For
this reason, you cannot trim blank spaces using the TRIMQ function

S You could
also index on
or the - operator when you are indexing alphabetically by name.
In ASCII order, small letters all come after capital letters. To make
the expression
sure that your list is alphabetized in dictionary order, rather than
UPPER(LNAME) ASCII order, you should use the function UPPER() to capitalize the
+ UPPER(FNAME), letters of the expression that you are indexing on. In the next
which is identical to
example, you will start off by indexing on LNAME + FNAME , to
UPPER(LNAME
+ FNAME). see what ASCII order looks like, then you will index on the expres¬
sion UPPER(LNAME + FNAME), to get proper dictionary order.
Though these are simple expressions, you will create them the long
way in order to get experience with the expression builder dialog box,
illustrated in Figure 4.17. As you have seen, the expression builder
includes four popup controls across the top, which let you access the

System File Edit Expression

1
I Math String Logical Date

Field Names: Database:

►FNAME C EMPLIST
LNAME C
ADDRESS C
APT_NO C < Verify >
CITY C
STATE C « OK »
ZIP C
DATE HIRED D < Cancel >

Figure 4.17: The expression builder dialog box.


UNDERSTANDING INDEXES AND EXPRESSIONS 143

Math, String, Logical, and Date functions and operators. It also


includes a scrollable list of field names on the lower left, with all
except the memo fields of the current database. The scrollable list on
the lower right includes all memory variables: since you have not cre¬
ated any, it contains only system variables, beginning with an under¬
score. The popup control in the center lets you select database files,
which will be useful when you are working with relational databases
(to be covered in Chapter 7). The Verify text button right under it
lets you make sure that an expression is valid; you are quite familiar
with the OK and Cancel text buttons right under that. The expres¬
sion that you will create will appear in the large text box that stretches
all the way across this dialog box and has the words ‘‘INDEX ON:
<expr>” on its upper edge. Alternately, you may type expressions
directly in this text box. Though this would be easier with the simple
expressions you are using now, you will use the other controls to
create them as an exercise.

1. If you want, enter CLEAR to clear the screen. Then, as you


did earlier, create the index by selecting New from the File
menu, then the Index radio button, then the OK text button.

2. When the Index On dialog box (which you used before)


appears, select the Expr text button to call up the expression
builder.

3. Select LNAME from the scrollable list of field names. This


causes emplist - >lname to appear in the text box. This longer
version of the field name, indicating that you are using the
LNAME field from the EMPLIST file, is not necessary unless
you are working with a relational database that has more than
one file open at a time.

4. Since you will be combining two character fields, select the


String popup control, then select + . This causes the + to
appear after the field name in the text box.

5. To complete the expression, select FNAME from the scrolla¬


ble list of field names. It is added to the text box after the + ,
so that it now says emplist ->lname -i-fname.
144 MASTERING FOXPRO

CH. 4

6. To make sure the expression is valid, select the Verify text


button. An “Expression is valid” message should appear in
the upper right of your screen.

7. Since this is the expression you want to index on, select the
default OK text button. The expression builder dialog box
disappears, and the expression that you generated is filled in
to the right of the Expr text button of the Index On dialog
box. (Remember that you could have just typed the expres¬
sion in here, rather than using the expression builder.)

8. Select OK to create the index.

9. The Index File Name dialog box appears. You do not need to
change the drive or directory: just type NAMES as the name
of the new index. Then select OK. The command

INDEX ON EMPLIST->LNAME + EMPLIST->FNAME TO


NAMES
is generated in the Command window. The ‘‘talk” tells you
that records have been indexed.

10. To check the effect of the index, select Browse from the Data¬
base menu. Notice that all the names are now in alphabetical
order except Audrey Levy’s. JACK LOVE comes before
Audrey Levy, as shown in Figure 4.18, because capital LO
comes before Le in ASCII order. Close the Browse window.

To correct this error, you will create a new index UPPER


(LNAME + FNAME)), which will compare the two strings using
capital leters. Then you will again give the index the name NAMES,
so that it overwrites the old, incorrect NAMES index. The one prob¬
lem you will run into is that FoxPro will not let you overwrite an index
when it is open, since that could corrupt your data. In this exercise,
then, you will open the ZIPS index to close the NAMES index. This
will give you experience opening an index, which is very easy to do.

L Select Open from the File menu, then the popup control
(which now says Database), and then Index. (Notice, inci¬
dentally, the text button New: you can also create new
indexes with this dialog box, as you will in the next step.)
UNDERSTANDING INDEXES AND EXPRESSIONS 145

System 1r i 1 e I (1 j t D. it abase Recor d Progr am Window Drowse |


1
Fname Lname Address

It DNA ICHANG 12701 ADDISON WAY


WILLIAM JOHNSON 523 EAST 21 ST.
WILLIAM B. JOHNSON 1701 ALBEMARLE RD.
JACK LOVE 3642 TANACH WAY
Audrey Levy 318 B. 31 St.
NANCY NIXON 1124 GRANT AVE.
CHARLOTTE SAGORIN 2203 SHADY LANE
JAMES SKINNER 1206 FRANCISCO ST.

▼ Command
hourly wage of "
CLEAR
INDEX ON emplist->lname
BROWSE LAST

Figure 4.18: Indexing in ASCII order does not alphabetize properly.

Select ZIPS.IDX from the scrollable list of indexes in the


Open dialog box (shown in Figure 4.19) to open the ZIPS
index. Notice the command generated: SET INDEX TO
ZIPS.IDX. (If you want, select Browse from the Database
menu to see that the file has changed to zip code order, then
close the Browse window to continue the exercise.)

To create a new index in a different way, again select Open


from the File menu. The dialog box already has Index as its
type, since you selected that earlier. Select the text button
New, which calls up the same Index On dialog box you have
been using to create indexes all through this chapter. Select
the Expr text button to get the expression builder again.

3. Select the String popup control. Scroll down and select the
UPPER() function from the popup. Notice that die cursor is
now in the UPPER() function’s parentheses in the expres¬
sion box.

4. Select LNAME from the scrollable list of fields. LNAME now


appears in the parentheses, and the cursor moves outside.
146 MASTERING FOXPRO

CH. 4

System file Id it Database. Record Program Window


8 records indexed

Open:

[••] Drive
DATES.IDX
NAMES.IDX
•ZIPS. IDX
Directory LEARNFOX

« Open »

[ ] All Files < New >

Index Type < Cancel > y wage of "

list->lname

1
BROWSE LAST

Figure 4.19: Opening an index with the Open dialog box.

5. Press the left arrow key once to move the cursor back one
space into the parentheses. Select the String popup control
and select + from the popup. The + goes into the parenthe¬
ses, and the cursor moves out of the parentheses again.

6. Press the left arrow once again to move the cursor back into
the parentheses. Select FNAME from the scrollable list of
fields to complete the expression you want. Select Verify to
make sure it is right.

7. Select OK. The expression is filled in to the right of the Expr


text button in the Index On dialog box. Select OK, and the
Index File Name dialog box appears.

8. Since you want to overwrite the earlier NAMES index you


already created, use the scrollable list of file names to select
NAMES.IDX. That name appears in the text box. (Note
that ZIPS is dimmed on this list: you cannot select it because
it is already open. That is why you had to close the NAMES
index before overwriting it. Even if you try to get around the
UNDERSTANDING INDEXES AND EXPRESSIONS 147

dimming by typing its name in the text box, FoxPro will dis¬
play an alert and refuse to overwrite an index that is already
open.)

Select OK and FoxPro displays an alert asking if you want to


overwrite an existing index (not the same as overwriting a
currently open index). This alert is shown in Figure 4.20.
Select Yes (you can just press Y).

Select Browse from the Database menu and you will see that
the records are now in proper alphabetical order, not ASCII
order. Audrey Levy is now before JACK LOVE, as in Fig¬
ure 4.21. Close the Browse window.

Going through the steps of recreating the index was a useful lesson
in using the expression builder, but it also shows that it is sometimes
easier to use the Command window. You could have created the new
index by closing the first index, pressing the up arrow key to move
the cursor to the command

INDEX ON EMPLIST- >LNAME + EMPLIST - >FNAME TO


NAMES

Systfpm file IcJit Database Record Program Window


8 records indexed

Index file name:

Drive c I
L DATES.IDX

C:\LEARNFOX\NAMES.IDX already ( ■x i s ts ,
overwrite it? • c ■' '■ ' ¥ s

< Yes > E wmrmmr


[ ] All Files •< Cancel >

NAMES.IDX
list->lname

L
SET INDEX TO ZIPS.IDX

Figure 4.20: FoxPro displays an alert before overwriting an existing index.


148 MASTERING FOXPRO

CH. 4

System File Edit Database Record Program Window Browse


EMPLIST =
Fname

EDNA
Lname

ICHANG
Address

1 12701 ADDISON WAY


1
WILLIAM JOHNSON 523 EAST 21 ST.
WILLIAM B. JOHNSON 1701 ALBEMARLE RD.
Audrey Levy 318 B. 31 St.
JACK LOVE 3642 TANACH WAY
NANCY NIXON 1124 GRANT AVE.
CHARLOTTE SA60RIN 2203 SHADY LANE
JAMES SKINNER 1206 FRANCISCO ST.

T Command
■■■CDlast
SET INDEX TO ZIPS.IDX
INDEX ON UPPER(emplist->
BROWSE LAST

Figure 4.21: Records indexed in proper alphabetical order by name.

then just editing that command so it reads

INDEX ON UPPER(EMPLIST- >LNAME + EMPLIST


->FNAME) TO NAMES

and pressing Enter.


FoxPro functions are As you can see, using the expression builder is a bit unwieldy,
all listed in the Help
window. If any function in
because there are so many functions and operators to choose among.
the scrollable lists of the However, the expression builder lets beginners create expressions,
expression builder puzzles and it is useful as a learning tool, to get you familiar with FoxPro’s
you, you can always open
functions and operators. After you have used it for a while, you will
the Help window to find
out what it does. Playing find that you have learned the FoxPro functions that you use fre¬
with the Help window quently and that it is usually easier just to type expressions into the
and expression builder
Index On dialog box than to use the expression builder-—though
together, in this way, is an
easy way to learn FoxPro the expression builder will still be useful for expressions that use more
functions. obscure functions.
UNDERSTANDING INDEXES AND EXPRESSIONS 149

INDEXING IN DESCENDING ORDER


Normally, indexes arrange records in ascending order, from the
smallest to the largest. If you index on a date field, the record with
the earliest date comes first; on a numeric field, the smallest number
comes first; and on a character field, characters with the smallest
ASCII number come first, for example, A comes before Z.
There are times when you want records in descending order. You
might want a report on employees that lists the most recently hired
first or that lists those with the highest wage first. FoxPro does not
give you a direct method of indexing in descending order, but it is
easy to create expressions that trick it into indexing date and numeric
fields in descending order. All you have to do is index on an expres¬
sion that subtracts the date or number in the field from some large
date or number. For example, lets say that you want to list your
employees from those with the highest wage to those with the lowest
wage. You can index on the expression 100 - WAGE. Of course,
the higher the WAGE is, the smaller the value of 100 - WAGE is.
Try creating this descending order index:

1. As you did earlier, create the index by selecting New from the
File menu then the Index radio button, and the OK text but¬
ton. From the Index On dialog box, select the Expr text
button to call up the expression builder.

2. Simply type 100 in the text box. Then use the Math popup
control and select - . Then use the scrollable list of field
names and select WAGE. The expression should now read
100 -- emplist - >wage. (Of course, you could have just
typed in 100 - WAGE at the Expr text button.)

3. Since this is the expression you want to index on, select OK.
From the Index On dialog box, select OK to create this
index. In the Index File Name dialog box type WAGES as the
name of the new index. Then select OK.

4. To check this index, select Browse from the Database menu.


Scroll across the fields until you can see that the records are in
wage order from the highest to the lowest wage, as in Fig¬
ure 4.22. Close the Browse window.
150 MASTERING FOXPRO

CH. 4

System File Edit Database Record Program Window Browse


EMPLIST
State Zip Date hired Wage Probation Notes 1
H 06/06/82 22.75
NY 11226 12/15/89 19.70
CA 94300 02/01/84 18.25
NJ 07200 06/04/89 16.20
CA 94706 09/07/88 9.75
CA 94025 12/01/88 8.20
NY 11600 07/16/81 8.00
NY 10022 04/23/76 6.25

▼ Command
UPPER(emplist->
BROWSE LAST
INDEX ON 100 - emplist->
BROWSE LAST

Figure 4.22: Indexing in descending order by wage.

If you wanted to, you could do the same thing with a date field. To
list the most recently hired employees first, index on the expression
{12/31/99} - DATE__HIRED. The later the date hired is, the smaller
the time between it and the end of the century.

MAINTAINING INDEXES _
When you use the File menu popup to create a new index or open an
existing index, all other indexes are automatically closed. This might not
seem to be a problem, since you can only use records in one order, but
there is actually a reason to open many indexes simultaneously.
If you add or change data in a database, the only indexes that will
reflect the additions and changes are those that are open at the time
you make the changes. Indexes that are not open will not be updated.
There are two ways of dealing with this problem.

• You can reindex the file before you work with the indexes that
were closed when you changed the file. You do this by open¬
ing the index and then selecting Reindex from the Database
menu.
UNDERSTANDING INDEXES AND EXPRESSIONS 151

• You can use the Setup dialog box from the Database menu to
open more than one index simultaneously. One will be the
main index and the records will be displayed in the order that
it indicates, but all of the indexes will be updated each time
that you add or edit records in the database file. Up to 21
indexes may be open at one time.

Each of these options has advantages and disadvantages, and the


choice you make will depend on how you are using the index.
The disadvantage of reindexing is that FoxPro actually starts from
scratch when it rebuilds an index; it indexes on the same expression
and uses the new index to replace the old one, and reading through
the entire database file to create a new index can take time if the file is
long. The disadvantage of opening all the indexes is that it takes time
to open them before you work with the file. (The additional extra
time that it takes to update them while you are editing the file is not
noticeable.)
If you use an index frequently, then, it is generally best to keep it
open whenever you edit or add data to the database. The bit of extra
time this takes saves you a long wait when you need to use the file
with that index. On the other hand, if an index is used for a report
that is produced only once a year or once every few months, it might
be easier to use Reindex to rebuild that index before producing the
report than it is to open the index during perhaps hundreds of data
entry sessions in order to keep it updated. You should find the
method of maintaining indexes that is easiest for you in each individ¬
ual case.

m This is a very com¬


mon error in prac-
tice. If records that you
Of course, you can also reindex to rebuild an index if you forgot to
open it during some of your data entry sessions and the index thus
know you added seem to was not updated properly. Just select Reindex from the Database
have disappeared, the menu or use the REINDEX command, and all the indexes that are
first thing you should do
currently open will be rebuilt with all the data in the file.
is try to Reindex the
database. Nine times out
of ten, that will solve
the problem.
REINDEXING
Try adding a new record with just one index open. The WAGES
index should still be open; if not, open it before doing this exercise.
You will see that a new record you enter with this index open
152 MASTERING FOXPRO

CH. 4

disappears when you use the file with another index. Then, you will
use Reindex to make it reappear.

1. Select Append from the Record menu. As the new record,


enter Fname: MICHELLE Lname: PERLOW Address: 224-
1423 RESEARCH BLVD. Apt_no: 22-41 City: SANTA
CLARA State: CA Zip: 94304 Daiejmed: 05/18/88 Wage: 9.75
Probation: N Notes: (none).

2. Select Browse from the Browse menu, to see this record


among the others. Scroll over to see that it has been inserted
in the proper wage order. Press Ctrl-End or click the close
box to save the change.

3. Now select Open from the File menu, and select a different
index—DATES.IDX—from the Open dialog box. Note
that FoxPro generates the command SET INDEX TO
DATES.IDX in the Command window.
4. Select Browse from the Database menu. The new record is
not in the Browse window, as shown in Figure 4.23, because
the current index was not open when you appended it.

System File Edit Database Record Program Window Browse


EMPL1ST ‘ :
1 Fname Lname Address

■WILLIAM 1623 EAST 21 ST.


Audrey Levy 318 B. 31 St.
CHARLOTTE SAGORIN 2203 SHADY LANE
NANCY NIXON 1124 GRANT AVE.
EDNA CHANG 2701 ADDISON WAY
JAMES SKINNER 1206 FRANCISCO ST.
JACK LOVE 3642 TANACH WAY
WILLIAM B. JOHNSON 1701 ALBEMARLE RD.

▼ Command
JLAST
APPEND
SET INDEX TO DATES.IDX
BROWSE LAST

Figure 4.23: The new record is nowhere to be seen using the DATES index.
UNDERSTANDING INDEXES AND EXPRESSIONS 153

5. Select Reindex from the Database menu. “Talk” appears to


inform you that FoxPro is reindexing the file. Close the
Browse window, then select Browse from the Database menu
to open it again. The Browse window reappears with the new
record included, as shown in Figure 4.24.

MANAGING INDEXES
USING THE SETUP DIALOG BOX
Of course, it would be tedious work to reopen each of the other
indexes individually and reindex each one separately. Instead, try
using the Setup dialog box to open all of them at once:

1. If you want, enter CLEAR to clear the screen. Select Setup


from the Database menu. The Setup dialog box appears, as
in Figure 4.25. Note that the DATES index is in the box
under the word Indexes, to show that it is currently active. It
also has a bullet next to it to show that it is the main index, the
one that sets the order in which the records are displayed.

System File Edit Database Record Program Window Browse


EMPLIST t. . . ; "
Fname
="
|WILLIAM
Audrey
Lname

IJOHNSON
Levy
Address

1523 EAST 21 ST.


318 B. 31 St.
1
CHARLOTTE SAGORIN 2203 SHADY LANE
NANCY NIXON 1124 GRANT AVE.
MICHELLE PERLOW 224-1423 RESEARCH BL
EDNA CHANG 2701 ADDISON WAY
JAMES SKINNER 1206 FRANCISCO ST.
JACK LOVE 3642 TANACH WAY
WILLIAM B. JOHNSON 1701 ALBEMARLE RD.

* Command
|EX TO DATES.IDX
BROWSE LAST
REINDEX
BROWSE LAST

Figure 4.24: After reindexing, the new record reappears.


System File Edit Database Record Program Window

Database: EMPLIST
Structure: <Modiffl> Indexes: Index

►FNAME C 15 0 •DATES < 0dd... >


LNAME C 20 0 (Modify. . . >
ADDRESS C 25 0 < Remove >
APT NO C 5 0 <Set Ordeo

Fields: 11 Length: 117 Index expr:


Index filter:

R
L[ ]J Set
set Fields...
t
( ) Offl
[ 1 Fiflte
c (•) Ofif
ter... « OK »
[ J Forfla
Sat...

Figure 4.25: The Setup dialog box, with one index active.

2. Select the Add text button. The Open Index File dialog box
appears. Select NAMES.IDX from the scrollable list of
index files. It is added to the list under DATES.

3. Repeat the procedure in Step 2 to select WAGES.IDX and


ZIPS.IDX from the scrollable list. Now, all the indexes are
listed in the setup dialog box, as in Figure 4.26. Select OK to
confirm this setup.

4. Select Reindex from the Database menu. FoxPro talk will tell
you that it is reindexing all four of the index files that are
open.

Now you know how to open more than one index. You can do the
same thing before adding records, and all open indexes will be
updated. You will not “lose” records when you use one of these
indexes as the main index, as you did earlier. If you are skeptical, you
can try it yourself, since all the indexes are now open.
When you select one of the indexes from the list in the Setup dialog
box, the expression that it is indexed on appears to the right of the
words “Index expr:” just below the list of indexes.
UNDERSTANDING INDEXES AND EXPRESSIONS 155

Edit Database Record Program Window

Database: EMPLIST
Structure: <ModifH> Indexes: Index

►FNAME C 15 0 •DATES
LNAME C 20 0 NAMES <Modify...>
ADDRESS C 25 0 WAGES < Remove >
APT NO C 5 0 ZIPS <Set Order>

Fields: 11 Length: 117 Index expr:


Index filter:
[ ] Set Fields.
( ) Offl (•)
[ ] FiOter... « OK »
[ ] Format...

wmm BROWSE LAST

l CLEAR
SET INDEX TO C: LEARNFOX

Figure 4.26: The setup dialog box with multiple indexes open.

In addition, once you have selected an index, the Modify, Remove,


and Set Order text buttons become active.

• Modify: calls up the Index On dialog box so that you can


modify the expression used as the basis for the index that has
been selected.

• Set Order: uses the index that has been selected as the main
index, which determines the order in which the fields are dis¬
played (and moves the bullet next to it in the list).

• Remove: removes the index you selected from the list, so it is


no longer open.

These three text buttons are very important, and you should take a
moment to try them out. Other features of the Setup dialog box will
be discussed later: the Set Fields and Filter check boxes in Chapter 5,
since they are most often used with queries, and the Format check
box in Chapter 9, when we discuss custom screens.
When you work from the dialog box, you always must use two
steps to open a file and index—generating a USE command and then
156 MASTERING FOXPRO

CH. 4

a SET INDEX TO command. Once you become experienced,


though, you might prefer working right from the command line,
where you can combine these two steps by listing the indexes you
want active as part of the USE command. The name of the database
file just needs to be followed by the word INDEX and a list of in¬
dex files, and the first index listed will be the main index that sets the
order in which the records are displayed. For example, if you entered

USE EMPLIST INDEX NAMES, DATES, WAGES, ZIPS

the EMPLIST database would be opened with the records displayed


in alphabetical order, and all of the indexes would be updated if you
modified the file.

SORTING __

As you know, indexing a file changes only the apparent order of the
records, while the actual way that they are arranged in the database file
remains the same. It is possible, however, to change the actual order of
the records by choosing Sort from the Database menu.
When you sort, you create a new database file to place the sorted
records in. Sorting is rarely used in FoxPro, since it is slower and
clumsier than indexing, but you should take a moment to look at the

a Of course, it is
impossible to sort or
features of the Sort dialog box, illustrated in Figure 4.27.
The upper portion of this dialog box contains what is called a field
picker. Select the field that you want from the scrollable list labeled
index on memo fields, so
the scrollable list in the
Database Fields, on the upper left, and then select the Move text
field picker leaves out button to move it into the box labeled Sort Order, on the upper right.
memo fields. You can sort on more than one field. Add fields to the Sort Order list
in order of their importance: a field lower on this list is only used as a tie¬
breaker if all the fields higher than it are identical. For example, to sort
on the full name, you would put LNAME first and FNAME second in
the Sort Order box. The order you end up with would be the same as
if you indexed on the expression LNAME + FNAME. If you change
your mind about adding a field to the Sort Order list, you can remove it
by using the Remove text button.
The box labeled Field Options, in the center of the dialog box,
includes two radio buttons to let you sort in Ascending or Descending
UNDERSTANDING INDEXES AND EXPRESSIONS 15 7

System File Edit Database Record Program Window

Database Fields: Sort Order:

FNAME C 15 0 < Move ■* >


LNAME C 20 0
ADDRESS C 25 0 < Remove >
APT NO C 5 0
CITY C 20 0 - Field Options —
STATE C 2 0 (•) Ejscendlng
ZIP C 5 0 ( ) descending
DATE HIRED D 8 0 [ J Qgnore Case
WAGE N 5 2

Database: r Input - r Output -

[Scope. . . < Safle As... > [ ] FieQds... <gancel >


EMPLIST Bor...
Ehile... « OK »

Figure 4.27: The Sort dialog box.

order (with Ascending as the default) and a check box to let you
choose to ignore case (upper and lowercase). To sort in alphabetical
order by name, you should check this box in addition to moving
LNAME and FNAME to the Sort Order box.
The Database popup control on the bottom left lets you access
other databases that are open and create a sorted file that includes
fields from more than one existing file. To do this, you must be work¬
ing with a relational database and must open multiple files simultane¬
ously and relate them to each other, a relatively advanced feature of
FoxPro that you will learn about in Part II of this book. The Input
box in the bottom center includes Scope, For, and While check boxes
that let you choose which records go into the new file; similar check
boxes are used in many FoxPro dialog boxes, and you will learn
about them in the next chapter.
The Output box next to the Input box includes a Fields check box:
selecting it displays a new dialog box that lets you choose which fields
will be included in the new sorted file.
After you have chosen all of the sort options you want, you may
choose the Save As text button. The Sort Destination File dialog box
158 MASTERING FOXPRO

CH. 4

appears. Within this dialog box, enter a new name for the output file,
and then select the Save text button; or you could simply have typed
the name for the new hie in the text box under the Save As text but¬
ton. When you are finished, select the OK text button of the Sort dia¬
log box.
Rather than using the Sort dialog box, you can enter the command
SORT in the Command window. However, this is a complex com¬
mand. For a discussion of how to use this command, see Appendix C.
Using Queries
and Advanced Expressions
To create a logical expression, 165
use a relational operator to make a comparison. The relational
operators are: = for equal to, < > for not equal to, = = for
identical to, $ for included in, > for greater than, < for less
than, > = for greater than or equal to, and < = for less than or
equal to.

To make a query without using an index, 174


add a FOR clause to a command; or check the For check box of
the dialog box that you use to generate that command and use the
expression builder to create the logical expression to be used as
your criterion. If you use FOR, FoxPro searches the entire data¬
base for a record where the criterion you entered is true.

To make a query using an index, * 174


add a WHILE clause to a command; or check the While check
box of the dialog box that you use to generate that command. If
you use WHILE, FoxPro searches the database beginning with
the current record and continues its search only as long as the cri¬
terion you entered remains true. Thus, before using WHILE,
you must index the database properly and put the pointer on the
first record where the criterion is true.

To make an unindexed search for a single record, 177


use the command LOCATE FOR <logical exp>, or select
Locate from the Record menu and check the For check box.
LOCATE FOR finds the first record in the database where the
expression is true. Use the command CONTINUE or select
Continue from the Record menu if you need to find the next
record where the expression is true.
To make an indexed search for a single record, 181
use the command SEEK < expression >, or select Seek from the
Record menu. Do not use a logical expression with SEEK: use
an expression of the same data type that is used as the key of the
current index. SEEK finds the first record where the key ex¬
pression of the index is the same as the expression you use for
the search.

To make an unindexed search for many records, 184


add FOR Klogical exp> to a command that works with many
records, or check the For check box in the dialog box that is
used to generate that command. For example, the command
COPY FOR Klogical exp> will copy all the records for which
the expression is true.

To make an indexed search for many records, 185


add WHILE <expression^ to a command that works with
many records, or check the While check box in the dialog box
that is used to generate that command. For example, COPY
WHILE <expression^ will continue to copy as long as the
expression that the current record is indexed on matches
the expression in the command. Note that before using
WHILE, you must index properly and use SEEK to put the
pointer on the first matching record.

To create a quick report, 204


use the command LIST followed by a field list and a FOR or
WHILE clause. Add the word OFF at the end to omit the
record numbers. Add TO PRINT or TO FILE Kfile name^> to
send the listing to the printer or to a plain text file.
164 MASTERING FOXPRO

CH. 5

A QUERY TELLS A DATABASE PROGRAM TO FIND


records that meet some criterion—for example, to find the record of a
person with a certain name, or to find all of the records with addresses in
the state of California. Obviously, you want different types of results
from these two queries. For the first you want one record and for the sec¬
ond you want a whole list of records. FoxPro gives you several methods
of making queries, which are useful for different purposes:

• You can find a single record that meets the criterion. Then, if
you want, you can repeat the query to see if there is a second
record that meets the criterion. This method is useful for
tasks such as looking up someone by name; and repeating the
query is useful if you get someone else with the same name
the first time you try.

• You can find all the records that meet the criterion by com¬
bining queries with commands that work with the entire
database. For example, you can build a query into the Copy
command, so that records that meet the criterion are copied
into a new file when you use that command. This method has
piany uses. For example, it can be used to produce mailing
labels for everyone who meets the criterion-—for example, for
every employee who lives in California.

• In addition to these two basic ways of querying, FoxPro gives


you special query techniques. You can create what is called a
filter, which lets you use the entire database just as you nor¬
mally would but filters out the records that do not meet the
criterion. You can also build a query into an index in such a
way that the index is automatically updated as the file is
maintained; after you do this, only records that meet the cri¬
terion are accessible when the database is used with that
index as the main index.

This chapter will mainly deal with the first two of these methods.
You will find later in the chapter that it is easy to use the same princi¬
ples with other commands and special techniques.
USING QUERIES AND ADVANCED EXPRESSIONS 165

WORKING WITH
LOGICAL EXPRESSIONS
D in an actual applica¬
tion, of course, if
-

Any query must contain an expression that is either true or false—


that is, a logical expression. For example, if you wanted to make a
you think there is any
possibility of the state’s
query to find the employees who live in California, you would have to
not being capitalized, you use the expression STATE = “CA”. Later, you will examine this
should use the expression sort of expression in more detail. For now, just note that it makes
UPPER(STATE) = “CA”.
FoxPro look at each record to see if the contents of the State field are
The examples leave out
the UPPER0 function to equal to the letters CA. If they are, the expression STATE = “CA”
save you the trouble of is evaluated as true. If not, the expression is evaluated as false.
entering it and because
It is important to understand that the criterion you use in a query
state names are less often
miscapitalized than peo¬ must be a logical expression that FoxPro evaluates as true or false. By
ple’s names. printing a couple of sample expressions using ?, you can get a firm
grasp of the fact that FoxPro evaluates expressions:

1. If necessary, start FoxPro and enter CLEAR to clear the


screen.

2. In the Command window, enter ? 1 + 1. FoxPro prints 2.

3. Enter ? 1 + 1 = 2. FoxPro prints .T., as shown in Figure 5.1.

System File Edit. Database Record Program Window


2
T.

Figure 5.1: Evaluating a numeric and a logical expression.


166 MASTERING FOXPRO

CH. 5

In the first example, FoxPro evaluates the expression 1+1 and


comes up with the result 2. The operation it performs to get this result
is addition, indicated by the + operator.
In the second example, FoxPro evaluates the expression 1+1=2 and
comes up with the result .T., which stands for True. (As you will see,
FoxPro often uses dots in this way as delimiters in logical expressions.)
The operation it performs to get this result is comparison, indicated by
the = operator.

LOGICAL FUNCTIONS
Operators are not the only expression elements that give a result of
true or false. Some functions, called logical functions, will also return
.T. or .F. Though they generally are used in programming, logical
functions are sometimes handy during ordinary use of FoxPro.
One common example is the function EOF(), which stands for End
Of File. As long as the pointer is on one of the records of the file, EOF()
is false. If you are at the last record, though, and you use the command
SKIP to move the pointer to the next record, EOF() will become true, to
indicate that you are beyond the point where records exist.
EOF() also becomes true if you make a query and FoxPro does not
find what you are looking for. The pointer goes through all of the
records looking for the criterion you gave it, and passes by the last
record without finding it. To indicate this, it makes EOF() true. You
will use this function in Chapter 10 when you start programming.

RELATIONAL OPERATORS
Logical functions and operators are included in the Logical popup
control of the expression builder dialog box, shown in Figure 5.2.
Although all the operators on this popup are referred to loosely as log¬
ical operators, it is more precise to divide them into relational and
logical operators.
Relational operators are used to make comparisons. They can be
used to compare numbers, strings, or dates.
The = operator, which you glanced at earlier, is an example. You
can use expressions such as DATE_HIRED = {10/10/85} or
USING QUERIES AND AD VANCED EXPRESSIONS 167

System File Edit .Expression

()
<
Math String

INDEX ON: <expr> <>


<-
>-
$
at m

Field Names: Databa .1.


. F.
►FNAME C .NOT.
EMPLIS
LNAME C .AND.
ADDRESS c .OR.
APT NO c < Verify BETWEEN(,,)
CITY c BOF( )
STATE c « OK CAPSLOCK()
ZIP c CHRSAW()
DATE HIRED D < Cancel DELETED()
EMPTY()
EOF()
FCLOSE( )
-▼-

Figure 5.2: The Logical popup control of the expression builder.

WAGE = 10 or UPPER(LNAME) = “SMITH” to find records


where those fields have those values.
Though relational operators can be used with data of various
types, the data being compared must be of the same type. For
example, you could not use UPPER(LNAME) = {10/10/85}. Since
there is a character expression to the left of the = and a date expres¬
sion to the right, FoxPro would display an alert with an error message
saying there is a type mismatch, as shown in Figure 5.3. On the other
hand, FoxPro would let you use the expression UPPER(LNAME)-
= DTOC({l0/10/85}) without displaying an error message; though
you obviously will not find someone with this name, the logical
expression is valid, because it compares two character expressions.
The relational operators are listed in Table 5.1. Most will probably
be familiar to you, since they are used in mathematics. There are
three operators meaning “not equal.” You may use whichever one
you find convenient when you are typing from the keyboard. Only
one is actually included on the popup.
168 MASTERING FOXPRO

CH. 5

Figure 5.3: Alert indicating there is a data type mismatch.


< >, which is com¬
Table 5.1: The Relational Operators
monly used in
mathematics, is the only %
symbol for “not equal Operator Meaning
to” included on the
Logical popup. # was
= is equal to
common in earlier
dBASE compatible lan¬ > is greater than
guages, but it is some¬
< is less than
times confusing to
beginners, who tend to > = is greater than or equal to
read an expression like
WAGE # 10 as “wage < = is less than or equal to
number 10” rather than
< > or # is not equal to
as “wage not equal to
or ! =
10.” In dBASE compat¬
ible languages, this # sign $ is contained in (used only for character data)
is supposed to represent
an equals sign with two = — is identical to (used only for character data)
vertical lines through it to
show that is not true. !
was added to FoxPro as
another way of represent¬ Except for $ and = =, all of these operators can be used with char¬
ing “not,” which it acter, numeric, or date data. $ and = = can be used only for charac¬
represents in other com¬
ter data.
puter languages; it is used
in combination with = to $ is used to search for a substring. For example, you can use the
mean “not equal to.” expression “BROADWAY” $ UPPER(ADDRESS) to find
USING QUERIES AND AD VANCED EXPRESSIONS 169

the records of people who live on a street named Broadway. You can
read this expression as “ BROADWAY is contained in upper of
ADDRESS.” This operator applies only to character data; it can be

a If you enter the


command SET
used to search memo as well as character fields.
Though the difference may not be obvious, = = , which means “is
identical to,” is not the same as = , which means “is equal to.” For
EXACT ON, only strings
that are identical will example, if you secirch for UPPER(LNAME) = “SMITH”, FoxPro
match, even if you use = . will find people named SMITHSON and SMITHERS as well as
To go back to the default
SMITH. This feature of = is generally useful, as you will see. How¬
method, enter the com¬
mand SET EXACT OFF ever, where you want only an exact match, you could use = = . Since
You can also use these these operators are tricky, you should try them out.
commands through the
View window, which will
1. Enter ? “SMITHSON” = “SMITH”. FoxPro evaluates the
be discussed in Chapter 7.
expression as true and prints .T.

2. Enter ? “SMITHSON” = = “SMITH”. (You can do this


most easily, of course, by editing the previous command.)
FoxPro evaluates the expression as false and prints .F., as
shown in Figure 5.4.

One other point you should consider, while you are at it, is that in
these comparisons, FoxPro uses the second string as the criterion and

Figure 5.4: The difference between = and


170 MASTERING FOXPRO

CH. 5

compares the first string with it. In Step 1, for example, it uses
‘‘SMITH” as the criterion, and it looks through “SMITHSON” to
see that all the letters in “SMITH” are matched. Thus, it would not
find that the reverse, “SMITH” = “SMITHSON”, is true: when
it looks at “SMITH”, it would not find that all the letters in
“SMITHSON” are matched. Try this out by entering ? “SMITH”
= “SMITHSON”. FoxPro evaluates the expression and prints .F.
This example shows why actual queries have the form LNAME =
“SMITH” rather than “SMITH” = LNAME. For the same rea¬
son, you can find all the names that begin with the letter A by using
the criterion UPPER(LNAME) = “A”.

LOGICAL OPERATORS
Though the relational operators that were listed in Table 5.1 are
loosely referred to as logical operators, this section will look at the logi¬
cal operators in the stricter sense of the term. These operators, used
to create more complex expressions, are shown in Table 5.2.

Table 5.2: The Logical Operators

Operator Meaning

.AND. both halves of the expression must be true for the


entire expression to be evaluated as true

.OR. either half of the expression must be true for the


entire expression to be evaluated as true
Because ! is a recent
innovation specific .NOT. or ! the expression that follows must be untrue for the
to FoxPro, it is probably entire expression to be evaluated as true
best to avoid it in pro¬
0 used for grouping
grams lest you make
them incompatible with
other dBASE compatible
database management Notice that, like .T. and .F., the logical operators begin and end
systems. Of course, there with dot delimiters (except for !, which is a recent addition to the
is no problem to using !
in queries or other
dBASE standard, and is a shortcut meant to save you keystrokes).
expressions that, unlike
programs, are meant to USING ANDOR., AND NOT.
be used only within your
own FoxPro system. The logical operators are used to build complex expressions, and
you should look at a few examples to see how they work.
USING QUERIES AND AD VANCED EXPRESSIONS 171

.AND. and .OR. are both used to build a complex expressions


out of two logical expressions. For example, if you wanted to find rec¬
ords of employees who live in California, you would use the expres¬
sion STATE = “CA”. If you wanted to find employees who live in
New York, you would use the expression STATE = “NY”. And if
you wanted to find employees who live in either state, you would
combine the two with .OR. to make the complex expression

STATE = "CA" .OR. STATE = "NY"

It is important to remember that ordinary language does not use the


words “and” and “or” in exactly this way. People might say colloqui¬
ally “I want a list of the employees from California or New York.” But
they might also say “I want a list of the employees from California and
New York,” intending no difference in meaning. When you are work¬
ing with computers, though, you have to use .AND. and .OR. in their
precise logical sense. The complex expression

STATE = "CA" .AND. STATE = "NY"

would only be true if both halves of it were true—that is, if FoxPro


found a record where the contents of the State field were, at the same
time, both CA and NY, which, of course, is impossible.
The effect of the .AND. and .OR. operators is that .AND. is
exclusive—the expression is true only if both halves are true at once,
which can exclude a lot of records—and .OR. is mclusive: the expres¬
sion is true if either half is true, so that more records are included.
.OR. is thus used for broadening your queries: for example, for
finding people from more than one state. .AND. is useful for narrowing
your queries by adding more criteria. For example, the expression

STATE = "CA" .AND. WAGE < 10

would be used to narrow the query so that it finds only some of the
employees from California: those with wages less than $10.
172 MASTERING FOXPRO

CH. 5

If you find these STATE = “CA” could be used to find the records for all the states
operators confusing, except California; that is, it would find every record that is left out by
you should add the words
“it is true that” when
the expression STATE = “CA”. You simply have to remember to
you read the expressions use .NOT. before the entire logical expression it refers to.
to yourself. Read
STATE =“CA” .OR.
STATE = “NY” as “it is USING PARENTHESES FOR COMPLEX EXPRESSIONS
true that the STATE
equals CA or it is true You can combine complex logical expressions with .AND. and
that the STATE equals .OR. indefinitely, creating more and more complex expressions.
NY,” and you will not
When expressions contain more than one of these operators, it is best
confuse the .AND. with
the .OR. operator. Like¬
to group them using parentheses to indicate precedence.
wise, .NOT. is some¬ For example, let’s say that you want to find employees from Cali¬
times clearer if you read fornia and from New York who earn less than average wages for the
it as “it is not true that.”
area. You know that the average wage in California is $10 and that
Thus, it is probably best
to read .NOT. STATE the average wage in New York is $11.
= “CA” as “it is not true To find the records from California, you would use the expression
that the STATE
equals CA.”
STATE = "CA" .AND. WAGE < 10

To find the records from New York, you would use the expression

STATE = ^NY" .AND. WAGE <11

Then, to find all the records you want, you would combine these two
with .OR. to get

(STATE = "CA" .AND. WAGE < 10) .OR. (STATE = "NY" .AND.
WAGE < 11)

ORDER OF PRECEDENCE
In Chapter 4, you saw that if you leave out parentheses, numeric
expressions are evaluated in default algebraic order. In fact, all Fox¬
Pro expressions are evaluated in the following order of precedence if
you leave out parentheses.

1. exponentiation

2. multiplication and division

3. addition and subtraction


USING QUERIES AND AD VANCED EXPRESSIONS 173

4. character string concatenation


5. relational operators

6. .NOT.

7. .AND.

8. .OR.

The reason for some of this order of evaluation is obvious. Clearly,


FoxPro has to evaluate numeric expressions before it can compare
them: for example, if it is evaluating the expression 1 +1 = 2, it must
use the addition operator + to evaluate 1+1 before it can use the
relational operator = to see if the entire expression is true.
Likewise, FoxPro must give relational operators precedence over
logical operators. For example, if it is evaluating STATE =“CA”
.OR. STATE = “NY”, it must evaluate STATE = “CA” to see
if it is true and must evaluate STATE = “NY” to see if it is true
before it can determine if the entire complex expression is true. There
is no need to use parentheses to make the order of precedence clearer.
On the other hand, when you get down to the logical operators
themselves, things become less obvious. It is possible to leave out the
parentheses and to rely on the default order of precedence when you
are working with expressions that have more than one logical opera¬
tor, but it makes expressions that are this complex hard to read,
which makes errors more likely. Moreover, these errors are often
hard to detect, since they will only result in your query not finding
every record you want. For these reasons, it is best always to use
parentheses in expressions whenever they may be useful for clarity,
even if they are not needed.

TO INDEX OR NOT TO INDEX _


One basic choice that you must make before making queries is
whether or not to use an index.
There are many cases where using an index is essential. For
example, if you are looking up employees by name in a large data¬
base, the delays would be intolerable if you did not use an index and
the program had to read through every record in sequence to find
each name that you wanted.
174 MASTERING FOXPRO

CH. 5

There are also cases where an index is not useful. If all of your
employees lived in two states, for example, it would be foolish to use
an index to search for state names. The program would have to read
through about half the file anyway just to read all the records with the
state you wanted, so using an index would not save much time. In
this case, maintaining an index is more trouble than it is worth.
Likewise, there is no need to use an index to produce a report if
you plan to go do something else while the report is being printed. If
time is not a concern, there is no reason to go to the trouble of main¬
taining an index.

FOR AND WHILE CLA USES


There are two different clauses that you can add to FoxPro com¬
mands depending on whether you want to query with an index or
without an index.

• FOR clauses: If you precede a logical expression with the


word FOR, FoxPro will do an unindexed search. It will read
through the entire file in sequence, starting with the first
record, to find records where that expression is true.

• WHILE clauses: If you precede a logical expression with the


word WHILE, FoxPro will assume that you are doing an
indexed search. You should only use this sort of clause to search
the field that is currently being used as the main index. FoxPro
will assume that the pointer is already on the first record that
you want and that all of the records that you want follow imme¬
diately after that record. It is called a WHILE clause because
the search continues only while the criterion remains true.

If you are working in the Command window, there are many


different commands that you could use with, for example, the clauses
FOR STATE = “CA” or WHILE STATE = “CA” in order to
build a query into the command. If you are working from the menu
system, likewise, you will find that many dialog boxes have For and
While check boxes—like the Copy To dialog box shown in Fig¬
ure 5.5.—which let you build queries into these menu choices and
thus generate commands that include FOR and WHILE clauses.
USING QUERIES AND ADVANCED EXPRESSIONS 175

Figure 5.5: A dialog box with For, While, Scope, and Fields check boxes.

The Scope and Fields check boxes that are grouped with the For
and While check boxes in this dialog box are useful for refining que¬
ries, but they involve side issues that are not essential. They will be
covered later in this chapter.

PREPARING TO USE WHILE


Using a FOR clause with a command is very simple. Since FoxPro
reads through the entire file in sequence to find matching records,
there is no opportunity for problems to arise—except for the big
problem of the extra time it takes.
Using a WHILE clause, though, is a bit more difficult. It will be
easier to understand by looking at an example.
Let’s say that you have a very large database and that you want to
use just the records of the employees whose names begin with the let¬
ters L through O. You could do this by using a command that
includes the clause WHILE UPPER(LNAME) > = “L” .AND.
UPPER(LNAME) < “P”.
Before you can use this command, though, you must first be using
the EMPLIST database with the NAMES index active as the main
176 MASTERING FOXPRO

CH. 5

index, so the names are already in alphabetical order. Then you must
put the pointer on the first record that begins with L. Only then can
you use a command containing this WHILE clause. When you use
a WHILE clause, FoxPro begins by looking at the current record
(where the pointer is) to see if it meets the criterion. If it is, then Fox¬
Pro looks at the next record and sees if it meets the criterion. It con¬
tinues to look at records in this manner until it finds a record that
does not meet the criterion, at which point it stops the search.
Think about the pitfalls this process involves—since they some¬
times come up and it will be helpful if you can recognize the disease
when you see the symptom:

• If you used a WHILE clause on a file that was not indexed, it


would not find all the records that matched. They would be
scattered through the file, and FoxPro would certainly find a
record that did not match before it found every record that
did match.

• If you used a WHILE clause without moving the pointer to


the first record that matched, it would look at the current
record, and if it didn’t meet the criterion, would stop search¬
ing without having found any records.

• If you had an indexed file and the pointer was on a record


that matched, but was not on the first record that matched,
then the query would find only the records that came after that
location of the pointer, not those that came before.

None of these problems can occur when you use a FOR clause,
which automatically begins at the first record and reads through the
entire file, and so it is best to use a FOR clause when possible.
There are cases, though, when you are working with large files,
when the extra speed of a WHILE clause makes all the trouble
worthwhile. In addition, WHILE clauses are particularly useful in
programming, since all the preliminaries are done automatically by
the program. There is also a short-cut command for putting the
pointer on the first applicable record before using a WHILE clause,
which you will learn in the next section.
USING QUERIES AND ADVANCED EXPRESSIONS 177

MAKING QUERIES FOR


SINGLE AND MUL TIPLE RECORDS _

As you have seen, you can use queries to find either a single record
or all records that match a certain criterion. In either case, you can
decide to do either an indexed or an unindexed search.

UNINDEXED QUERIES FOR A SINGLE RECORD


The most common way of querying for a single record is to use the
command LOCATE FOR. You could also select Locate from
the Record menu and use the For check box in the Locate dialog box
that appears (shown in Figure 5.6).

System Fite Edit Database Record Program Window

[ ] Scope...
« Locate »
[ ] |or...
< Cancel >
[ ] jjjhile.

H Though it is pos¬
sible to use both a
Figure 5.6: The Locate dialog box.

As you can see, the Locate dialog box has a For, a While, and a
FOR and a WHILE
clause in a command in Scope check box. Many dialog boxes have these three check boxes
this way, it is confusing together, but in this case, arranging them this way is a bit misleading,
and should be avoided. If
since they are not parallel options here, as they usually are. LOCATE
you do use both, the
WHILE clause takes must have a FOR clause; the WHILE and SCOPE clauses are
precedence. optional and merely limit the number of records that FoxPro
178 MASTERING FOXPRO

CH. 5

searches through. (When you look at Scope at the end of this chapter,
you will see that it merely lets you specify that some command be car¬
ried out on the next 10, 20, or whatever number of records you
choose. The While option can also be used in combination with FOR
to carry out the LOCATE FOR command only for as long as the
WHILE condition is true.
The basic way of using the Locate dialog box, then, is by checking
the For check box. When you do so, the expression builder will
appear, so you can enter the logical expression that you will be using
as the criterion for your search. For example, to find the record for
somebody named Johnson, you would enter the expression
UPPER(LNAME) = “JOHNSON”.
LOCATE FOR will begin with the first record in the database file
and read through it sequentially until it finds a match, regardless of
where the pointer is when you begin—the same way that FOR
clauses normally work. If it does not find any record that matches,
FoxPro “talk” will display a message saying “End of Locate
Scope. ’ ’ In addition, the pointer will be set at the end of the file posi¬
tion, so that the function EOFQ is true.
If LOCATE FOR finds the record you want, but you also want to
see the next record that meets the criterion, select Continue from the
Record menu (or use the command CONTINUE).
Try these two commands, which you are bound to use frequently
for the everyday work of looking up records:

1. Select Open from the File menu, and when the Open dialog
box appears, select EMPLIST.DBF. In order to see the
pointer being moved by the commands, open the Browse
window by selecting Browse (from the Database menu
popup).

2. Select Locate from the Record menu to display the Locate


dialog box.

3. Select the For check box to display the expression builder.


Note that above the text box it says FOR Clause: <expL>
to remind you that a logical expression is needed in the FOR
clause. To create this expression, first select the String popup
control, and select UPPERQ from the list that pops up.
USING QUERIES AND ADVANCED EXPRESSIONS 179

Select LNAME from the Field Names list. Then select the
Logical popup control, and select = from the list that pops
up. Select the String popup control again, and select “text”
from the list that pops up. Type JOHNSON in the quotation
marks that have appeared. This gives you the complete
expression you want, as shown in Figure 5.7. (Alternately,
you simply could have typed the expression UPPER
(LNAME) = “JOHNSON”.)

System File Edit. Expression


EMPLIST
Fname

[Audrey! Math String Logical Date


JACK
EDNA
CHARLO |UPPER(empl1st->1name) - "JOHNSON"
WILLIA
WILLIA
NANCY
JAMES Field Names: Database: Variables:
MICHEL
FNAME EMPLIST ►_ALIGNMENT
►LNAME BOX
ADDRESS “INDENT
APT_NO < Verify > "lmargin
CITY PADVANCE
STATE « OK » “PAGENO
ZIP “PBPAGE
DATE HIRED < Cancel > “PCOLNO

Figure 5. 7: Building the expression to be located.

4. Select the default text button, OK, to return to the Locate


dialog box. Select the default text button, Locate, to find the
first record that matches the criterion. The pointer moves to
the first record with the last name of Johnson, as shown in
Figure 5.8.
5. Select Continue from the Record menu popup. The pointer
moves to the next record with the last name of Johnson, as
shown in Figure 5.9.

The command generated in the Command window is

LOCATE ALL FOR UPPER(emplist - >lname) = "JOHNSON"


180 MASTERING FOXPRO

CH. 5

System File Edit Database Record Program Window Brovvse .


EMPLIST
Fname Lname Address

Audrey Levy 318 B. 31 St.


JACK LOVE 3642 TANACH WAY
EDNA CHANG 2701 ADDISON WAY
CHARLOTTE SAGORIN 2203 SHADY LANE
WILLIAM JOHNSON 523 EAST 21 ST.
WILLIAM B. JOHNSON 1701 ALBEMARLE RD.
NANCY NIXON 1124 GRANT AVE.
JAMES SKINNER 1206 FRANCISCO ST.
MICHELLE PERLOW 224-1423 RESEARCH BL

f Command
MiQ HjH” = "SMITHSON"
USE EMPLIST.DBF
BROWSE LAST
LOCATE ALL FOR UPPER(emp

Figure 5.8: Using LOCATE to find a record.

System File Edit Database Record Program Window Browse


EMPLIST
Fname Lname Address

Audrey Levy 318 B. 31 St.


JACK LOVE 3642 TANACH WAY
EDNA CHANG 2701 ADDISON WAY
CHARLOTTE SAGORIN 2203 SHADY LANE
WILLIAM JOHNSON 523 EAST 21 ST.
■WILLIAM B. IJOHNSON 11701 ALBEMARLE RD.
NANCY NIXON 1124 GRANT AVE.
JAMES SKINNER 1206 FRANCISCO ST.
MICHELLE PERLOW 224-1423 RESEARCH BL

y Command
fill 1ST. DBF
BROWSE LAST
LOCATE ALL FOR UPPER(emp
CONTINUE

Figure 5.9: Using CONTINUE to find the next record with the same value
USING QUERIES AND AD VANCED EXPRESSIONS 181

As usual, generated commands contain more than is really needed.


The word ALL is the scope of the command, and (as you will see later
in this chapter) merely means that the entire database file is searched.
Since this is the default scope, it is not necessary to include it if you
are typing in the Command window. Likewise, as you have seen, it is
not necessary to include the file name. From the Command window,

a You can also use


LOCATE and
you could simply enter LOCATE FOR LNAME = “JOHNSON”.
Of course, this exercise in using LOCATE and CONTINUE does
CONTINUE without not seem very useful when you are working with this small a file,
opening the Browse where you can see the two Johnsons as soon as you open the Browse
window, to move the window. These commands are essential, however, when you are
pointer without its being
working with a larger file that has people named Johnson scattered all
visible to the user. This is
often essential in pro¬ through it.
gramming, where you
want the user to be able
to search for a given
INDEXED QUERIES FOR A SINGLE RECORD
record in order to view or
edit it but you don’t want SEEK is a shortcut method for finding the first record in an indexed
to give the user access to
file that matches the criterion, and it is generally used before you use a
the entire file.
command with a WHILE clause based on the same criterion.
Before you use SEEK, the database must be indexed on the held
that your query is based on, and that index must be active as the
D Normally, the
pointer will move to
main index. Since it does an indexed search, FoxPro can find the first
matching record very quickly, even in a large database. If it does not
the end of a file if the find a match, the pointer is put at the end of the hie and EOF()
search is unsuccessful.
But if you use the com¬
becomes true.
mand SET NEAR ON Since seek works only on the indexed held, it can let you enter the
before using SEEK, the criterion in an easy way: you simply have to enter the value that
pointer will be placed at
the indexed held must match, and not an entire logical expression.
the record that comes
nearest to matching; then To hnd the hrst person named JOHNSON in a hie indexed on
you can browse nearby UPPER(LNAME) + UPPER(FNAME), you simply need to use
records. This is very
the command SEEK “JOHNSON”. FoxPro assumes that you want
useful if, for example,
you misspelled a name.
to hnd that value in the held that is currently the main index, so it will
SET commands will be search for the hrst record where UPPER(LNAME) +
discussed in Chapter 7, as UPPER(FNAME) = “JOHNSON”. (Remember that there is a
part of the discussion of
the View window.
match as long as the beginning of the string you are searching
matches; thus, this criterion will be true as long as the last name is
Johnson.)
182 MASTERING FOXPRO

CH. 5

To do a seek using the menu system, select Seek from the Record
menu, and FoxPro will display the expression builder so you can
enter the expression that matches the main index. As you will see, the
expression builder reminds you that you do not have to enter
the entire logical expression that is your criterion. You just enter the
second half of the expression, which FoxPro assumes you want to
match with the fields in the main index. Try it:

1. Select Open from the File menu popup. When the Open dia¬
log box appears, select the Type popup control and select
Index from the list that appears. Then select NAMES.IDX
from the list of indexes. The names in the Browse window are
now listed alphabetically.

2. Select Seek from the Record menu. The expression builder


appears with the words Value to SEEK < expC > above the
text box where you enter the expression, to remind you that
you just need a character expression here, and not a logical
expression as you do with most queries.

3. Type “LOVE” in the text box, as shown in Figure 5.10. (If


you want, you can select '‘text” from the String popup con¬
trol to put the quotation marks in the text box.) Then select
the default text button, OK. FoxPro moves the pointer to the
proper record.

4. Select Seek again from the Record menu. Then type


“LEVY” in the expression builder’s text box, and select the
default text button, OK. FoxPro finds the appropriate
record, even though it comes before the current location of
the pointer, and even though the case does not match.

The example above shows that SEEK does an indexed search of the
entire database: it does not just begin where the pointer is.
When you are entering the criterion for the SEEK command, think
carefully about the exact expression that the index uses. At first, it
might seem puzzling that SEEK seemed to ignore capitalization when
it found “LEVY”. Remember, though, that SEEK was searching
using the main index, thus, the expression UPPER(LNAME) +
UPPER(FNAME). The index expression capitalized the LNAME
field; thus, it did match the criterion “LEVY”.
USING QUERIES AND ADVANCED EXPRESSIONS 183

System File^ Edit Expression


EMPLIST
Fname

Math String Logical Date


WILLIA
WILLIA
Audrey
JACK
NANCY
MICHEL
CHARLO Field Names: Database: Variables:
JAMES
►FNAME C EMPLIST ►_ALIGNMENT C
LNAME C BOX L
ADDRESS C _INDENT N
APT_NO C < Verify > _LMARGIN N
CITY C _PADVANCE C
STATE C « OK » _PAGENO N
ZIP C _PBPAGE N
DATE HIRED D < Cancel > PCOLNO N

Figure 5.10: Entering a value to seek.

If you want to find After you have done a SEEK in this way, the index is still open as
the next single
record that meets the
the main index, and the pointer is on the first record with the value
criterion after you have you want. This leaves you all ready to use a command with a
used a SEEK, all you WHILE clause.
need to do is look at the
next record in the Browse
window. Since this is a
search on the key field of QUERIES FOR MULTIPLE RECORDS
the index, the next record
that matches the criterion
When you query for all the records in a file that match the crite¬
(if there is one) is simply rion, many database management programs automatically put the
the next record in the file. results of a query in a new database file, which they call the Answer
file or something similar. Then, if you want a report or mailing labels
that contain only the records that match the query, you must produce
the report or labels using the Answer file.
FoxPro and other dBASE compatible programs do not require
you to go through this unwieldy process. You can add a FOR or a
WHILE clause to many commands—including the commands that
you use to produce reports or labels—and, in essence, build the
query into the command.
As an exercise to learn how to use the FOR and WHILE clauses,
you will make a query that works like a conventional query that puts
184 MASTERING FOXPRO

CH. 5

all the matching records into a new file. There are times when you
need to make this sort of simple query. It is very easy to do this using
FoxPro by selecting Copy To from the Database menu and checking
For or While in its dialog box—or by using the COPY command with
a FOR or WHILE clause—to copy the records that match the crite¬
rion into a new file. You can even name the new file ANSWER.DBF
if you want.
You have already learned how to make queries using LOCATE
and SEEK for a single matching record. By using COPY with FOR
and WHILE clauses, you will get a general idea of how to make que¬
ries for all the matching records in a file—so that you will also be able
to use FOR and WHILE with other menu choices or commands.

AN UNINDEXED MULTI-RECORD QUERY


Since FOR is easier, you should try it first:

1. If you want, close the Browse window and enter CLEAR to


clear the screen. Select Copy To from the Database menu
popup, and when the Copy To dialog box appears, select the
For check box.

2. Select STATE from the list of field names. Select the Logical
popup control and select = from the popup that appears.
Then select the String popup control and select “text” from
the popup that appears. Type CA in the quotation marks.
Select the default text button OK to confirm the expression
and return to the Copy To dialog box.

3. Type ANSWER1 in the text box under the Save As text but¬
ton. This will be the file containing all the records that match
your STATE = “CA” criterion. The dialog box should now
look like Figure 5.11. Select OK to copy.

4. Select Open from the File menu. When the Open dialog box
appears, use the Type popup control to select Database.
Then select ANSWER 1 .DBF from the scrollable list of files.
Select Browse from the Database menu to view it. Scroll until
you can see the State field, and you will see that all the
records are from California. Then close the Browse window.
USING QUERIES AND ADVANCED EXPRESSIONS 185

System File Edit. Database Record Program Window

Figure 5.11: Using COPY FOR to create an Answer file.


As usual, the command is generated in the Command window in a
lengthy form:

COPY TO C:\LEARNFOX\ANSWER1 .DBF FOR emplist - >


state = "CA"

In general, if you are working from the Command window, you can
copy the database file that is currently open simply by using the
command

COPY TO <file name >

and the file name does not have to include the .DBF extension. To
build a query into the command by adding a FOR clause, you could
simply enter

COPY TO ANSWER1 FOR STATE = "CA"

AN INDEXED MUL TI-RECORD QUER Y


You can also do the same thing using WHILE, but you must per¬
form the preliminaries first: use the file with an index and place the
pointer on the first matching field.
186 MASTERING FOXPRO

CH. 5

Even though this database hie is not indexed on the State held, you
can use a WHILE clause with it if you remember that California resi¬
dents have zip codes beginning with a 9. You will use the ZIPS index
you created and use the criterion Zip = “9” to copy all the California
records. Notice how convenient it is that Zip code is a character held and
matches the criterion even if there are other characters after the 9.

1. Select Open from the File menu. When the Open dialog box
appears, select EMPLIST.DBF from the list of hies. Select
Browse from the Database menu (though it is not necessary)
so you can see what you are doing.
%

2. Select Open again from the File menu. When the Open dia¬
log box appears, use the Type popup control to select Index.
Then select ZIPS.IDX from the list of hie names. Scroll right
until you can see the State and the Zip fields.

3. Select Seek from the Record menu. Type “9” in the text box
as the character expression to seek. (Do not forget to include
the quotation marks.) Then select OK. The pointer moves
to the first California record, as shown in Figure 5.12.

System File Edit Database Record Program Window Browse


EMPLIST ' > =!
Apt_no City State Zip Date_hired Wage

EAST ORANGE NJ 07000 06/06/82 22.75


18 ELIZABETH NJ 07200 06/04/89 16.20
F-23 NEW YORK NY 10022 04/23/76 6.25
D-14 BROOKLYN NY 11226 12/15/89 19.70
Far Rockaway NY 11600 07/16/81 8.00
■ MENLO PARK CA 9402b 12/01/88 - 1 8.201
PALO ALTO CA 94300 02/01/84 18.25
22-41 SANTA CLARA CA 94304 05/18/88 9.75
2B BERKELEY CA 94706 09/07/88 9.75

▼ Command
QOL1ST.DBF
BROWSE LAST
SET INDEX TO ZIPS.IDX
SEEK "9"

Figure 5.12: Moving the pointer to prepare to use WHILE.


USING QUERIES AND ADVANCED EXPRESSIONS 187

4. Select Copy To from the Database menu popup. When the


Copy To dialog box appears, select the While check box. The
heading of the expression builder text box asks for a WHILE
Clause: <expL>. Type ZIP = “9” as the logical expression
(or create the same expression using the expression builder).
Then select OK.

5. In the Copy To dialog box, type ANSWER2 in the text box


under the Save As text button, as the name of the file to copy
to. Then select OK to copy the file.

6. To see the result, select Open from the File menu. When the
Open dialog box appears, use the Type popup control
to select Database. Then use the list of files to select
ANSWER2.DBF. Select Browse from the Database menu
and scroll right until you can see the State and Zip fields.

Notice that the file has the same records as the ANSWER 1 file but
that they are in zip code order. Even though this file is not indexed,
that is the order in which you copied the records.
If you were working from the command line, you would have
entered

USE EMPLIST INDEX ZIPS

then

SEEK "9"

and then

COPY TO ANSWER2 WHILE ZIP = "9"

You can see that it is not worth going through the extra effort of
using WHILE with a database file as small as this one: the time you
save is not noticeable. With a file that has a thousand records,
though, the difference in speed is definitely worth the effort, and even
the smallest businesses often have mailing lists or other files that are
this long.
188 MASTERING FOXPRO

CH. 5

TRICKING FOXPRO INTO COPYING THE STRUCTURE


You will find it instructive at this point to try making an error. Use
COPY WHILE without using SEEK first, so that the pointer is not on
a matching record to begin with.

1• Repeat Steps 1 and 2 from the previous exercise to open and


browse the EMPLIST file, open the ZIPS index, and view
the State and Zip fields.

2. Skip Step 3 from the previous exercise, which uses Seek to


move the pointer. Then repeat Step 4 to enter a WHILE
clause in the Copy To dialog box. Repeat Step 5, but enter
ANSWER3 as the name of this file, and then copy the
file. To view the result, open ANSWER3.DBF and select
Browse, as you did in Step 6.

As you can see, the ANSWER3 file has no records in it. The cur¬
rent record did not meet the criterion of the WHILE clause, so Fox¬
Pro did not go any further. You may now close the Browse windows.
In Chapter 2, you learned the COPY STRUCTURE command,
which you used from the Command window to create a new database
with the same structure as an existing one. What you just did is
equivalent to copying the structure.
To trick FoxPro into copying the structure using the menu system,
just use COPY TO with some untrue criterion. Using an impossible
criterion, such as WHILE 1=2, ensures that FoxPro will not copy
any records.
But there is an even easier way of doing it. Remember that when
FoxPro uses a WHILE clause, it performs whatever you have
instructed it to do until it reaches a record for which it evaluates the
logical expression as .F.. You can save it the trouble of doing the eval¬
uation by simply entering .F. as the logical expression of the WHILE
clause to begin with.
There is no need to index when you do this. The index is used with
WHILE just to make sure that all the matching records are found, a
consideration which does not apply in this case.
USING QUERIES AND AD VANCED EXPRESSIONS 189

To save time, try doing this from the Command window:

1. Enter USE EMPLIST.

2. Enter COPY TO ANSWER4 WHILE .F.

3. When FoxPro is done copying, enter USE ANSWER4 and


then enter DISP STRU. You will see that the file has the same
structure as EMPLIST but no records, as shown in Fig¬
ure 5.13.

System File Edit Database Record Program Window


4 records copied
4 records copied
0 records copied
0 records copied
Structure for database: C:\LEARNF0X\ANSWER4.DBF
Number of data records: 0
Date of last update : 01/08/90
Field Field Name Type Width
1 FNAME Character 15
2 LNAME Character 20
3 ADDRESS Character 25
4 APT NO Character 5
5 CITY Character 20
6 STATE Character 2
7 ZIP Character 5
8 DATE HIRED Date 8
9 WAGE Numeric 5
10 PROBATION Logical 1
11 NOTES Memo 10
** Total ** 117

Figure 5.13: FoxPro has been tricked into copying just the structure.

Of course, you can do the same thing from the menu system by
repeating all the steps you used in the previous examples but entering
.F. in the expression builder text box: you can type it in or select it
from the Logical popup.

QUERYING WITH OTHER DATA TYPES


It is very simple to search character or numeric fields. You gener¬
ally use the equals, greater than, and less than operators with both
190 MASTERING FOXPRO

CH. 5

these data types. The = operator is used most commonly when you
are searching character fields, and the >, <, > = , and < = opera¬
tors are most common when you are searching numeric fields. It will
take an extra moment, though, to look at how to search memo and
logical fields.
The 4‘included-in” operator, $, can be used for character fields,
but is most commonly used to find a substring in a memo. In the next
exercise, for example, you will look for employees who are connected
with the Christmas fund-raising drive. The only trick to this query is
figuring out all the different ways you might have entered the data in
the memo field. You need to search for both XMAS and CHRIST¬
MAS in both upper and lower case. Even then, you should read each
memo individually, since one says that the employee cannot help with
the fund raising.
When you are basing a query on a logical field, you do not need to
use a logical expression. You may recall that logical expressions are
evaluated as true or false. The content of a logical field, however, is
already one of these values (.T. or .F.). Thus, to find all the people in
the EMPLIST database who are on probation, you can use a query
with FOR followed by the logical field PROBATION. FoxPro will
evaluate this logical field just as it would evaluate any logical expres¬
sion: as true or false. Likewise, you could use the criterion FOR
.NOT. PROBATION to find the records of employees who have .F.
in the field.
The following exercise will used unindexed queries, using COPY
with a FOR clause, though you could just as well use LOCATE FOR
and CONTINUE.

1. Select Copy To from the Database menu, and select Save As.
Type ANSWER5 in the text box, next to Save As, as the
name of the file to copy to, and select the For check box. In
the expression builder, type

"XMAS $ UPPER(NOTES) .OR. "CHRISTMAS" $ UPPER


(NOTES)"
and select OK. Then select OK from the Copy To dialog box
to execute the command.

2. Select Open from the File menu and select ANSWER5.DBF


from the scrollable list of file names. Select Browse from the
USING QUERIES AND AD VANCED EXPRESSIONS 191

Database menu to view the file. Look at the Notes fields of


each record to see that all match the criterion of the query, as
shown (for example) in Figure .5.14. When you are done,
close the Browse window.

System File Edit Database Record Program Window


I ANSWERS->NOTES =

"XMA

Figure 5.14: Looking at the results of a query for a memo field.

3. Again select Open from the File menu popup and select
EMPLIST.DBF from the scrollable list of file names. Select
Copy To from the Database menu. Type ANSWER6 in the
text box near Save As. Then select the For check box. When
the expression builder appears, select the field PROBA¬
TION from the scrollable list of field names: this field name
will complete the FOR clause in the expression builder.
Select OK to use this expression, and select OK to execute
the command.
4. Select Open from the File menu once more and select
ANSWER6.DBF from the scrollable list of file names. Select
Browse from the Database menu popup to view the file.
Scroll to see the Probation field and confirm that all of them
are .T., as shown in Figure 5.15. Close the Browse window.
192 MASTERING FOXPRO

CH. 5

System Frl-e Edit Database Record Program Window Browse


I ANSWER6
State Zip Date hired Wage Probation Notes

NJ ||07200|I06/04/89 111 6.20IIT IlMemo


CA 94706 09/07/88 9.75 T memo
NY 11226 12/15/89 19.70 T memo
CA 94025 12/01/88 8.20 T memo

▼ Command

11 NOTES Memo 10 1 COPY TO ANSWER6 FOR empl


Total ** 117 USE ANSWER6.DBF
I BROWSE LAST
3 records copied I
4 records copied ; "-.N;c '. :.'-y

Figure 5.15: Looking at the results of a query for a logical field.

When you were looking at the memo fields, you might have
noticed that fund raising was spelled in three ways: fund raising,
fund-raising, and FUNDRAISING. This gives you an idea of what
you are up against when you are searching memo fields.

DEALING WITH DELETED RECORDS


One problem that you will have to deal with when you are using
any of these query techniques is how to handle records that are
marked for deletion.
In many cases, you do not want these records: you may have
removed them from your file, and you do not consider them part of
your data, but you may not have gotten around to using the PACK
command to finalize the deletion.
Yet FoxPro, by default, includes records that are marked for dele¬
tion in the output of commands, and this can sometimes create prob¬
lems. For example, if you use a FOR clause to find the records of
certain people you want to telephone, FoxPro will include records
that you have marked for deletion—and you might end up telephon¬
ing people you thought you had scratched off your list.
USING QUERIES AND AD VANCED EXPRESSIONS 193

You now know enough to be able to deal with these problems in


several ways.
The most obvious technique is to use PACK before you use any
command where deleted records might cause a problem. This
method does not take any thought, but it can waste time if you are
working with a large database. If you delete records frequently and
use these commands frequently, you might have to pack your data¬
base dozens of times, which might take hours.
Many people find the Another way to handle the problem is to use the SET DELETED
SET DELETED command. You can access this command through the menu system
command confusing, since
SET DELETED ON is
by using the View window, which is discussed in Chapter 7, but it is
the command that turns off also easy to use it through the Command window. If you enter the
the deleted records. It is command SET DELETED ON, commands that select records will
easy to remember if you
not include any records that are marked for deletion. If you enter the
realize that it means: set
the feature that eliminates command SET DELETED OFF, the commands will include records
deleted records on. marked for deletion again.
You can also use the function DELETED0 in combination with a
single command. If a record is marked for deletion, DELETED0
returns .T.; if it is not, DELETEDQ returns .F.. By adding .AND.
.NOT. DELETED0 to a logical expression, then, you can do a
query that leaves out records marked for deletion. For example, you
can use the command

COPY TO ANSWER1 FOR STATE = "CA" .AND. .NOT.


DELETEDO

in order to make a query that is similar to the first one you made in
this section but that leaves out deleted records.
You can access DELETEDQ through the logical popup of the
expression builder, so you can also generate this function by working
with the menu system.
As you can see, there are many ways of accomplishing the same
task when you are using FoxPro. The dBASE compatible language
gradually grew, with more commands and functions to let you do
things more conveniently. There is no need to learn all of the com¬
mands and functions—since many of them just do the same things in
different ways that different users prefer. You should just be aware of
them and learn the ones that let you do what you want in a way that is
easiest for you.
194 MASTERING FOXPRO

CH. 5

SPECIAL TECHNIQUES -

You have learned the basic techniques for making queries to find
either one record or all the records that match a criterion:

• to do an unindexed search for a single record, use LOCATE


and CONTINUE

• to do an indexed search for a single record, use SEEK


• to do an unindexed search for all matching records, use a
FOR clause

• to do an indexed search for all matching records, use a


WHILE clause

These techniques are the workhorses that you will constantly use
when you are working with FoxPro.
FoxPro also provides two special techniques that you might find
make your job much easier on occasion. Both of these are similar to
what you have already learned, and it should be easy for you to pick
them up at this point.

SETTING A FILTER
There are often times when you want to perform a long series of
commands, all of which apply only to records that meet some crite¬
rion. Obviously, it would be unwieldy to use the For check box or a
FOR clause with each of these commands separately. For this rea¬
son, FoxPro also gives you the option of setting a filter.
After you set a filter, you do not need to worry about adding the
criterion to each command. Records that do not meet your criterion
are filtered out indefinitely, until you remove the filter.
Using the menu system, you can set a filter by selecting Setup from
the Database menu popup. Then use the Filter check box of the
Setup dialog box, which lets you enter a criterion in the expression
builder. After you do this, only those records that match the criterion
will be used with commands you select. The filter will continue to be
active until you remove the check from the check box.
USING QUERIES AND AD VANCED EXPRESSIONS 195

1. If you want to clear the screen, enter CLEAR. Select Open


from the File menu. Then select EMPLIST.DBF from the
Open dialog box.

2. Select Setup from the Database menu. When the Setup dia¬
log box appears, select the Filter check box. The expression
builder appears, with SET FILTER Expression: <expL>
over the text box. Type STATE = “CA” in the text box (or
use the expression builder to create the same expression).
Then select OK.

3. The expression you created appears next to the Filter check


box of the Setup dialog box, as shown in Figure 5.16. Note
the command generated:

SET FILTER TO STATE = "CA"


Select OK.

4. Select Browse from the Database menu. Since the filter has
been set, only the California records are visible. Only they
will be used with any command.

System File Edit Database Record Program Window

Database: EMPLIST
Structure: <ModJLffl> Indexes: Index

►FNAME C 15 0 < Qdd... >


LNAME C 20 0 <Modify.. . >
ADDRESS C 25 0 < Remove >
APT NO C 5 0 <Set Order>

Fields: 11 Length: 117 Index expr:


Index filter:
[ ] Set Fields...
( ) OB (•) Oflf
IKlBjiryaa—iSTATE "CA" « OK »
[ ] Format...

CLEAR
USE EMPLIST.DBF
SET FILTER TO STATE = "C

Figure 5.16: Using the Setup dialog box to set a filter.


196 MASTERING FOXPRO

CH. 5

5. Select Setup from the Database menu and select the Fil¬
ter check box again. The expression builder appears, with
STATE = “CA” entered as the expression in its text box.
Press Del to delete the expression. Then select OK to return
to the Setup dialog box. The check in the Filter check box dis¬
appears, and the command SET FILTER TO is generated in
the Command window. Select OK, and you can see all the
records in the Browse window again. Close the Browse
window.

B ln some cases, filters


are useful for simpli¬
You can create a filter from the Command window by entering
SET FILTER TO <logical exp>. You can remove the filter by enter¬
fying commands. Even if
ing the command SET FILTER TO without any logical expression
you only want to use the
criterion once, it is some¬ included; you might want to read this as “set filter to nothing.”
times easier to under¬ Keep in mind that a filter works like a FOR clause: it reads all the
stand what you are doing
records in the file to find the matching ones. This means that a filter is
if you use a filter to set up
the criterion, then use the slow if you are working with a large file.
command, and then
remove the filter. This is
particularly true if the
BUILDING A QUERY INTO AN INDEX
command has many
other clauses besides the You saw in the last chapter that the Index dialog box contains both
FOR clause. When you
a For and a While check box. Now you know how to use these check
have multiple criteria that
would have to be com¬ boxes: you use them to create indexes that include only the records
bined, creating a complex which meet a certain logical expression. For example, you can create
and difficult to under¬
an index that includes only records of employees who live in Califor¬
stand logical expression,
it also may be easier to nia. Whenever you update the database with that index active,
use a filter for one crite¬ records will continue to be included in that index as long as they are
rion and a FOR clause from California. Any time you want to query for records in Califor¬
for the other.
nia, all you have to do is use the file with this index as its main index,
and FoxPro will return even the most recent California additions to
the database; records not from California will be disregarded.
This is similar to setting a filter, but since it involves an index, it is
much faster when you are working with a large file. As usual, you get
the extra speed at the cost of doing the extra work of maintaining
the index.
It is most common to create the index using the For check box,
rather than going through the extra trouble of using While. In the
USING QUERIES AND ADVANCED EXPRESSIONS 197

following example, then, you will use the For check box to see how
powerful a query built into an index is.

1. Select New from the File menu. From the New dialog box,
select the Index radio button. Then select OK.

2. When the Index On dialog box appears, move the cursor to


the right of the Expr text button and type

UPPER(LNAME) + UPPER(FNAME)
(Or you could select the Expr text button and use the expres¬
sion builder to create this same expression.)

3. Select the For text button. The expression builder appears.


Type STATE = “CA” in the text box, or use the expression
builder to create this same logical expression. Then select OK.

4. The Index On dialog box now includes both the expression to


index on and the logical expression of the FOR clause, as in
Figure 5.17. Select OK to create the index. When FoxPro
displays the Index File Name dialog box, type CALNAMES

INDEX ON:

►FNAME C
LNAME C
ADDRESS C « OK »
APT_NO C
CITY C < Cancel >
STATE C

<gxpr...> UPPER(LNAME) + UPPER(FNAME)

[ ] Unique
HZMHB3 STATE - "CA"

Figure 5.17: Indexing with a FOR clause.


198 MASTERING FOXPRO

CH. 5

and select OK. Note that the command generated is like the
usual INDEX command plus the usual FOR clause:

INDEX ON UPPER(LNAME) + UPPER(FNAME) FOR STATE =


"CA" TO C:\LEARNFOX\CALNAMES.IDX

5. Select Setup from the Database menu. Select the Add text
button four times in order to add each of the four indexes to
the index list. Then select the NAMES index from the
Indexes list, and select the Set Order text button to make this
the main index. The Setup dialog box should now look like
Figure 5.18. Select OK.

System F ile I<1 i t Database Record Program Window


4 records indexed
Master index: C:\LEARNFOX\NAMES.IDX

Database: EMPLIST
Structure: <Modiffl> Indexes: Index

►FNAME C 15 0 CALNAMES < AokL.


LNAME C 20 0 DATES <Modify...>
ADDRESS C 25 0 •NAMES < Remove >
APT NO C 5 0 WAGES <Set Order>

Fields: 11 Length: 117 Index expr:


Index filter:
[ ] Set Fields.

E i Mi
' ‘ ob (•) Oflf

I
iter.. . « OK »
lat. . .

SET FILTER TO
INDEX ON UPPER(LNAME) +
SETINDEXH^^UIARNKIX

Figure 5.18: Setting up the database to add data with all indexes active.

6. Select Browse from the Database menu. You now can see all
the records in the Browse window in alphabetical order.
Select Append Record twice (from the Browse popup) in
order to enter these two new employees:

Fname: JOSEPH Lname: CRUZ Address: 1450 VALENCIA


ST. Aptjno: 4 City: SAN FRANCISCO State: CA Zip: 94101
Date_hired: 03/04/90 Wage: 19.00 Probation: T Notes: (none)
USING QUERIES AND ADVANCED EXPRESSIONS 199

Fname: HENRIETTA Lname: JOHNSON Address: 2204


GRAND CONCOURSE Apt_no: 18-F City: BRONX State: NY
Zip: 10405 Datejiired: 03/12/90 Wage: 6.05 Probation: T
Notes: (none)

Then press Ctrl-End to save the changes.

7. Select Setup again from the Database menu. Select CAL-


NAMES from the list of indexes. Then select Set Order to
make it the main index, and select OK. Then select Browse
from the Database menu. Notice that the Browse window
includes the one new record from California that you just
added.

8. Select Setup once again from the Database menu. Select


DATES from the list of indexes. Then select Set Order to
make it the main index, and select OK. Notice that both of
the new records that you just added are at the end of the data¬
base, since they are the two with the most recent Date_hired.
Close the Browse window.

Despite its power, the query built into an index obviously is not
useful for every purpose. You have to weigh the time saved by build¬
ing the query into an index against the time lost by having to main¬
tain the index. Using this sort of query is worthwhile if you are
working with a large file and need to make the query frequently.

RESTRICTING THE QUERY _


In general, the dialog boxes that you use to make queries include a
check box for Scope as well as ones for For and While. Some of these
dialog boxes also include a check box for Fields.
Unlike For and While, the Scope and Fields check boxes are not
essential to making queries. They are simply conveniences that let
you restrict what will appear in the result. If you think of how the
database appears in the Browse window—in the form of a table—
then Scope cuts the query off vertically by determining how many
records will be considered, and Fields cuts the query off horizontally,
by determining which fields will appear in the result.
200 MASTERING FOXPRO

CH. 5

SCOPE
Scope merely refers to the number of records that FoxPro searches
in the course of performing a command. Many commands can be
used with Scope clauses: they do not necessarily have any inherent
relation to FOR and WFIILE clauses.
Appendix C, your reference book of Commands and Functions, or the
listings in the Help window can tell you which commands can be
used with Scope clauses and where they must be placed if other
clauses are also used. Descriptions of these commands include the
word [scope] to indicate where a Scope clause goes, with the square
brackets indicating that it is optional. The word scope, though, is not
actually used in the clause. Instead, Scope clauses consist of any of
the following words:

• ALL The command acts on all of the records of the data¬


base (unless some other clause, such as a FOR or a WHILE
clause, restricts it)
• NEXT < number > The command acts on whatever number
of records is specified, counting the current record (where the
pointer is) as the NEXT 1.

Record numbers • RECORD <number> The command acts on the record


always refer to the
whose number is specified. This option is not often useful, as
order in which the
records appear in the
you do not usually know the numbers of particular records
actual database—not to in your database.
the order in which they
seem to appear because • REST The command acts on the records beginning with the
an index is being used. current record and continuing until the last record in the file.
Record 1 is the first
record that you entered in
Commands have a default scope—the scope that is usually most
the database, not the first
record in alphabetical convenient to use them with. For example, DELETE has a default
order or any other scope of NEXT 1, since you usually want to delete just the current
index order.
record. You have already used DELETE without specifying a scope,
and you have seen that it just deletes the record where the pointer is.
But you can also use commands such as DELETE ALL or DELETE
NEXT 10 to override the default scope.
In Chapter 3, you learned two commands which both let you view
data, the main difference being that one—DISPLAY—lets you view
one record and the other—LIST—lets you view the entire database.
USING QUERIES AND AD VANCEI) EXPRESSIONS 201

| One other minor Now you can see that the main difference between these commands is
■■I difference between their default scope. DISPLAY ALL is virtually identical to LIST, and
the two is that DISPLAY
ALL will display records
LIST NEXT 1 is virtually identical to DISPLAY (though there are a
one screen at a time, couple of other, very minor, differences apart from their scope).
pausing and asking you To see how to use these options through the menu system, by
to press any key to see the
using a Scope check box, you will try deleting all of your records.
next screen. This
difference makes DIS¬ Don’t worry—remember that this command just marks records for
PLAY ALL the easiest deletion, and you can use Recall with a Scope check box to get them
way of scrolling through
all back.
data to view it on the
screen if you are working
from the Command 1. If you want to clear the screen, enter CLEAR. Select Delete
window. from the Record menu. When the Delete dialog box appears,
select the Scope check box. When the Scope dialog box
appears, as shown in Figure 5.19, select the All radio button.
Then select OK to return to the Delete dialog box, and select
Delete. Notice that the command DELETE ALL has been
generated. Select Browse from the Database menu, and note
that all the records have bullets to their left to indicate that
they are marked for deletion.

System File Edit Database Record Program Window

Scope:

« OK »

< Cancel >

Figure 5.19: The Scope dialog box.


202 MASTERING FOXPRO

CH. 5

2. Select Recall from the Record menu. When the Recall dialog
box appears, select the Scope check box. When the Scope
dialog box appears, select the All radio button. Then select
OK to return to the Recall dialog box and select Recall. If
you check the Browse window at this point, you will notice
that the command RECALL ALL is generated and that all
the bullets have disappeared to indicate that the records are
no longer marked for deletion. Close the Browse window.

When you first used the Scope check box with either Delete or
Recall, the Next radio button was chosen and the default scope 1 was
written to its right. Because this is the default scope of the command,
just the current record is deleted or recalled if you do not use the
Scope check box at all.

FIELDS
Just as you can use a command with a Scope clause to restrict the
records that the command applies to, you can also use a command
with a FIELDS clause to restrict the fields that it applies to. You
should check Appendix C, your Commands and Functions reference, or
the Help window to see where the fields list fits into the syntax of any
given command.
You can use a
Unlike a Scope clause, which cannot contain the word scope, a
FIELDS clause with
expressions instead of just
FIELDS clause can either contain the word FIELDS followed by
with field names in order a list of fields (or expressions) or it can simply contain the list of fields
to make the output look (or expressions). In either case, commas must be included between
better. For example, in
each of the fields or expressions in the list. Some commands require the
the next exercise, you will
use PKOPER(TRIM . word FIELDS. To avoid confusion, it is best to always use the word
(FNAME) + “ ” + LNAME) FIELDS if you are working from the Command window.
to get a better-looking
Like a scope, a fields list can be combined with many commands
listing than you would get
with just FNAME, LNAME. and can also be used in conjunction with FOR or WHILE clauses.
For example, try using Copy to create a new file that has only the
names and addresses of the employees who live in California.

1. If you want to clear the screen, enter CLEAR. Select Copy


from the Database menu.
USING QUERIES AND AD VANCED EXPRESSIONS 203

2. When the Copy dialog box appears, select the For check box. In
the text box of the expression builder, enter STATE
= “CA” (or use the expression builder to create this expres¬
sion). Then select OK to return to the Copy dialog box.

3. Select the Fields check box. FoxPro displays the field picker
dialog box shown in Figure 5.20. Select the FNAME,
LNAME, ADDRESS, APT_NO, CITY, STATE, and
ZIP fields from the scrollable list of fields to move them to the
Selected Fields list. Then select OK to return to the Copy
dialog box. Enter ANSWER7 in the text box near Save As
and select OK to copy the file.

System File Edit Database Record Program Window

Database Fields: Selected Fields:

FNAME C 15 0 < Move -» >


LNAME C 20 0
ADDRESS C 25 0 < 011 ■» >
APT NO C 5 0
CITY C 20 0
STATE C 2 0 < Remove >
ZIP C 5 0
DATE HIRED D 8 0 < Clear >

Database:
<Cancel >
EMPLIST
« OK »

Figure 5.20: The field picker dialog box called by selecting the Fields check box.

4. Select Open from the File menu, and select ANSWER7 from
the list of files in the Open dialog box. Select Browse from the
Database menu to look at the new file. Scroll right to see that
it includes only the fields you listed and only the records from
California. Close the Browse window.

5. Since all these ANSWER files were just created as exercises,


you can delete them now. Enter USE to close the current file.
204 MASTERING FOXPRO

CH. 5

The DOS command Then enter RUN DEL ANSWER?. * to use DOS to delete all
uses two wild-card these hies.
characters. ? stands for
any single character; it
makes the command
Many menu selections include only For, While, and Scope check
include all the files with boxes in their dialog boxes, and leave out the Fields check box. If you
numbers following the are working with these menu choices, you can still restrict the fields
word ANSWER. *
they apply to by using the Setup dialog box first.
stands for any word; it
makes the command You can set fields in much the same way that you set a filter. You
include the memo files use the Filter check box of the Setup dialog box to set a filter that
with .FPT extensions as
works just like having a FOR clause in a command. Likewise, you
well as the database files
with .DBF extensions. can use the Set Fields check box of the Setup dialog box in the same
way. It works just like having a FIELDS clause in a command—with
one difference: the Set Fields check box has On and Off radio buttons
under it. This allows you to turn off the fields setting temporarily and
then turn it on again without going through the bother of choos¬
ing the fields again.
You can do the same thing working from the Command window
by using the command SET FIELDS TO Kfield names >. This com¬
mand is used together with the commands SET FIELDS OFF and
SET FIELDS ON, which temporarily suspend and reactivate the
field setting you have chosen. The command SET FIELDS TO ALL
will make all of the fields in the current database active.

THE EASIEST POSSIBLE REPORT


ON A QUERY: LIST WITH OPTIONS
Remember in Chapter 3 you used the command LIST to create the
simplest possible report—easier than anything you can do with
the menu. You can also use LIST in combination with a FOR clause
and a held list to create rather precise custom reports without using the
special report generator (which you will learn about in the next chapter).
Of course, the appearance of the report will not be as good as it would be
if you had used the report generator to design it, but LIST is the easiest
way to get a quick printout of your data for your own use—for example,
if you simply want to print out names and phone numbers of people
who live in California, so you can telephone them today.
USING QUERIES AND ADVANCED EXPRESSIONS 205

Since you can use expressions as part of the field list, you can even
include calculated fields in the report. Try, for example, getting an
alphabetical listing of the names and wages of your employees who
live in California, and add a calculated field, using the expression
40 * WAGE to calculate basic weekly wages (assuming that all em¬
ployees work a base 40-hour week).
Remember that the
OFF used with the
1. Enter CLEAR, then enter USE EMPLIST INDEX NAMES
LIST command simply
makes the command 2. Enter
leave out the record
numbers, which you do LIST FIELDS LNAME, FNAME, WAGE, 40*WAGE FOR STATE =
not want in an alphabeti¬ "CA" OFF
cal listing. OFF usually
comes at the end of a 3. To make the listing look nicer, you can combine the first and
LIST command—only last names, so the listing has a single name column. Enter
TO PRINT and TO '
FILE can come after it— LIST FIELDS PROPER(TRIM(FNAME) + " " + (LNAME)),
so, to avoid confusion, WAGE, 40*WAGE FOR STATE = "CA" OFF
you must remember that
it has nothing to do with
the preceding clauses. If the listing on the screen, shown in Figure 5.21, looks good to
you, you can add TO PRINT at the very end of the command in
order to get a quick printout of the data you need.

System File Edit Database Record Program Window


LNAME FNAME WAGE 40*WAGE
CHANG EDNA 9.75 390.00
CRUZ JOSEPH 19.00 760.00
NIXON NANCY 18.25 730.00
PERLOW MICHELLE 9.75 390.00
SKINNER JAMES 8.20 328.00

PROPER(TRIM(FNAME)+" "+(LNAME)) WAGE 40*WAGE


Edna Chang 9.75 390. 00
Joseph Cruz 19.00 760 . 00
Nancy Nixon 18.25 730. 00
Michelle Perlow 9.75 390. 00
James Skinner 8.20 328. 00

Command
CLEAR
USE EMPLIST INDEX NAMES
LIST FIELDS LNAME, FNAME
LIST FIELDS PROPER(TRIM(

Figure 5.21: Using LIST with options to create a report.


206 MASTERING FOXPRO

CH. 5

Do not use propor¬ If you want a report that includes page breaks, page headers and
tional fonts when footers, and the like, you can add TO FILE Kfile name> after OFF to
you print the data of a
save the output of the report in a plain ASCII text file. Most word
text file generated by Fox¬
Pro. Remember that processors can import ASCII hies (some call them DOS text hies)
FoxPro pads out the and they can add any formatting you want to the data. You can
space between columns
change the headings above the columns and even use a variety of
by using the blank char¬
acter. Proportional fonts fonts if your word processor supports them.
use less space for blanks You can see now how worthwhile it is to know about FoxPro
than for other characters,
commands—and about the different types of expressions and clauses
so that they will not align
the columns properly. Of that can be used with many of them. Though they have taken you a
course, you can use bit of extra time to learn, the extra power that they give you will more
proportional fonts to add than repay you for the trouble. As you have just seen, a one-line com¬
a report title.
mand can produce an entire report for you.
Of course, there are also times when you want reports with more
sophisticated features—-for example, reports that group your data to
make it easier for you to analyze. For these, you can use the FoxPro
report generator, which you will learn about in the next chapter.
WBBSB
Generating
Reports and Mailing Labels
■MM

Creating a report
is a two-step process. First design the report form: either enter
the command CREATE REPORT Kfile name'> or select New
from the File menu and select the Report radio button to design
the report using the report layout window. After the report
form is designed, select Report from the Database menu to call
up the Report dialog box, which lets you print the actual
report. The Form text button in this dialog box lets you choose
among report forms you have already designed.

To add additional bands to the report layout window,


select Title, Summary, or Groupings from the Report menu.
The report layout window has detail, header, and footer bands
when you first call it up.
*

To add boxes to the report,


select Box from the Report menu. If you are using a mouse,
move the pointer to where you want one corner of the box, then
click and drag to create the box. Release the button when you
are done. If you are using the keyboard, move the cursor to
where you want one corner of the box, and press the space bar
to start drawing. Use the arrow keys to position the opposite
corner of the box, then press Enter when you are done.

To group data,
select Data Grouping from the Report menu to call up the
Group dialog box, which lets you add, change, or delete a
grouping. When you add a grouping, the Group Info dialog
box appears, to let you specify the field or expression on which
the data is grouped. When you are done, bands appear for the
header and footer of the group. You must also index correctly in
order for the final report to be grouped properly.
To add a field expression to the report, 226
select Field from the Report menu to call up the Report Expres¬
sion dialog box. Then select a field name from the scrollable
list, or type an expression in the text box, or select the Expr text
button to use the expression builder to create the expression.

To add and edit text, 232


just type text where you want it in the report; when you are
done, press Enter to make the line of text an object. To edit a
text object, select it and then select Text from the Report menu.

Creating mailing labels, 243


like creating a report, is a two-step process. First design the
label form: either enter the command CREATE LABEL <file
name> or select New from the File menu and select the Label
radio button, which lets you use the label layout window. After
the label form is designed, select Label from the Database
menu to call up the Label dialog box, which lets you print the
actual labels. The Form text button in this dialog box lets you
choose among label forms you have already designed.

To lay out labels, 246


select Layout from the Label menu to select any of the standard
label layouts. Edit the specifications of any standard layout to
create a custom layout; and select Save Layout from the Label
menu to save it.

To add field expressions to labels, 247


just type them into the label layout window, or select Expr from
the Label menu to use the expression builder.
212 MASTERING FOXPRO

CH. 6

REPORTS AND MAILING LABELS ARE AMONG THE


most important applications of any database program. Now that you
have a thorough background in FoxPro basics, it will be easy for
you to learn to use the program’s report and label generators. These
features of FoxPro let you lay out the report or labels on the screen—
an easy, visual approach to designing the final product.
To make the best use of these features, you must be able to use
FoxPro expressions to specify what will be in the report or label, to
use indexes to print out the data in the order you want, and to use
FOR or WHILE clauses to determine what data is printed out. For
example, you can use expressions such as PROPER(ADDRESS) to
capitalize reports and labels properly. You can use indexes to print
out reports in alphabetical order or mailing labels in zip code order.
And you can use a FOR clause to print out labels only for a state you
specify.
By now, you have a strong enough background in these funda¬
mentals that it should be easy for you to use them with the report and
label generators.

CREATING REPORTS _

There are two steps to creating FoxPro reports. First, you must
design the report form. Then you can actually produce the report.
The report form determines how field data, text, and graphics are
laid out, and also lets you group and summarize data.
You create a new report form in the same way you create a new
database file or a new index: simply select New from the File menu
and then select the Report radio button. This command lets you use
the report layout window, shown in Figure 6.1. As usual, FoxPro
names the report form Untitled until you select Save As from the File
menu to save it and give it a name. (If you are working from the
Command window, you can enter the command CREATE REPORT
to use the report layout window in this way. Alternately, you can
enter CREATE REPORT Kfile namey to name the report from the
beginning.)
GENERATING REPOR TS AND MAILING LABELS 213

Figure 6.1: The report layout window.

Before you can create a report, a database file must be open. You
should also open the index you want to use for the report. (As you will
see later, you can save the report’s “environment” so that the index
is opened automatically when you want to produce the report.)
As you can see from the illustration, a Report menu pad is added
to the menu bar when you are using the report layout window. You
can see that the report is divided into bands: you can use the menu to
add expressions or graphic characters in any of these bands, and you
can simply type text into them.
Also notice the status line at the top of the window. The numbers at
the left, next to R and C, tell you the Row and Column of the cursor
location. The word to the right of that tells you what action is currendy
being performed, such as moving the cursor, drawing a box, or defining
a held. The final item of the status line tells you the band where the cur¬
sor is located.
The report layout window will be discussed in detail in the next
section.
When you have finished designing the report and save it, FoxPro
adds the extension .FRX to the name you give the report. If you save
the environment also, FoxPro gives the extension .FRV (which
stands for FoxReport View) to the file where it is saved.
214 MASTERING FOXPRO

CH. 6

DBASE, FoxBase, You can modify an existing report form, also, in the obvious way.
and other earlier
You selected New from the File menu popup to create a report form;
dBASE compatible pro¬
grams saved report forms
now you select Open to modify one. After selecting Open, you would
with the extension .FRM. select the Report radio button, and select from the scrollable list the
If you are running older name of the report form you want to modify. (From the Command
applications on FoxPro, it
window, simply enter MODIFY REPORT Kfile name >.)
will be able to use these
.FRM reports without Once you have designed and saved the report form that you want,
any trouble, and will you can use it at any time to produce actual reports. To do this, you
include them in the list of
select Report from the Database menu, and FoxPro displays the
report forms for you to
choose from. The one Report dialog box shown in Figure 6.2.
possible confusion arises
if you are working from
the command line, where
you can enter the report’s -System tile Edit Database Record Program Window

name without the exten¬


sion: If there are two Report:
reports with the same < h orm. . . > [X] Unvironment
name, FoxPro will use
the one with the .FRX
Pflaln
extension and ignore the 1 1
Jjo Eject
■ 1

one with the .FRM ■ 1


SummarQ
Heading
extension.
1 1
To ||rlnt « OK »
0° File
(•’ jjonsole On ( ) Console ®ff < Cancel >

Figure 6.2: The Report dialog box.

To determine which report form is used, you can either type the
name of any existing report form for the current database into
the text box, or select the Form text button to choose from a list of all the
reports for the current database. As you can see from the figure, this dia¬
log box includes an Environment check box. If you saved the environ¬
ment when you created the report form, checking this option will
automatically open the index you need and set the other environmental
variables that you saved in the .FRV file.
This dialog box also includes Scope, For, and While check boxes,
so that you can select which records to include in the report. If you
GENERATING REPOR TS AND MAILING LABELS 215

have designed a report form that lists employee names and addresses,
for example, you can use the For check box to print out the report
with only the employees from California, only the employees who
earn more than a certain wage, or whatever.
The dialog box also includes a set of check boxes that let you
choose these printing options:

• Plain: prints the report with a page header only on the first
page, and suppresses headers on following pages.

• No Eject: stops the printer from automatically ejecting the


final page of the report after printing it.

• Summary: prints only the data in the summary band of the


report. (You will learn below how to add this summary
band.)

• Heading: lets you add an extra heading line to each page of


the report—just type the extra heading in the text box.

Reports will be Finally, this dialog box also has check boxes that let you decide
printed or sent to a whether to send the report to the printer or to a text file on disk. The
text file more quickly if
you select the Console Off
Console On and Console Off radio buttons next to these check boxes
radio button. Remember determine whether the report is displayed on the screen while it is
also that the command to produced. If the Console On radio button is selected and neither To
produce a report, like
Print nor To File is checked, the report is simply displayed on the
most commands, is inter¬
rupted if you press Esc— screen.
a feature that is often To produce a report from the Command window, enter REPORT
useful when you are
FORM <Lfil,e namey to produce a report. The most important options
producing a report on
large databases.
with this command are a FOR or WHILE clause to determine which
records are printed, which can be followed by TO PRINT or TO
FILE Kfile name> to send the output to the printer or a text file
respectively. (See Appendix C for all the options that can be used
with this command.)
This discussion has given you a general idea of the two-step process of
creating reports: designing the report form and then producing the
report. Now we will look in detail at how to design a report form.
216 MASTERING FOXPRO

CH. 6

THE REPORT LA YOUT WINDOW


The layout window that you use to design report forms is divided
into three bands, each with several lines. There are bands for page
header, detail, and page footer. The header and footer, of course,
appear at the top or bottom of each page. You use the detail band to
enter an example of what you want included in the report. The data
that you want in the report is entered in the detail band just once; the
final, printed report repeats it for each record to be included.
In addition to the three bands that are in the report layout window
to begin with, you can use the Report menu popup to add bands for
the following:

• title: The report title appears only once at the beginning of


the report, unlike the header, which is repeated at the top
of each page.

• summary: The report summary appears at the end of the


report, unlike the footer, which is repeated at the bottom of
each page. It is common for the summary to include some
calculation—for example, the total number of workers and
the total payroll.

• groupings with headers and footers: Groupings let you divide


your data. For example, you can group all the employees
from each state.

You can choose to have your titles and summaries on pages sepa¬
rate from the rest of the report. Groupings can also begin at whatever
point they naturally occur or, if you choose, on a new page. You can
also use the menu to add or remove lines for each band. Bands may
be any number of lines, but the entire report form may have no more
than a total of 255 lines for all the bands combined.
Any of the bands can include

• fields or field expressions, which you place by using the


Report menu

• text that you simply type anywhere on the form and which
you can edit by using the Report menu
GENERATING REPOR TS AND MAILING LABELS 217

• lines or boxes, which you add using the Report menu. These
simple graphics are created using the line characters that are
part of the extended DOS character set. They can be used to
make the report look more attractive and to highlight impor¬
tant data.

The Report menu also lets you preview the page, that is, to see on
the screen what the printed report will look like. If you are not
satisfied with the layout you created, it is very easy to change it.
Anything that you enter in the report layout window is an object. A
block of text becomes an object when you press Enter or reach the
end of a line. Before you press Enter, you can edit the text in the ordi¬
nary way. After you press Enter, it can be selected and manipulated,
but can be edited only by selecting the Text option from the Report
menu popup. Fields and expressions, lines and boxes, and even
words or lines of text are all treated as objects, which you can select
and then move or delete using either a mouse or the keyboard, in the
ways described below.

MANIPULATING OBJECTS USING A MOUSE


H To place the pointer
or the cursor on a
To select an object in the layout window using the mouse, put the
pointer on it and click. To select more than one object at once, hold
box, you must place it on
one of the lines that
Shift the whole time you are clicking on the objects.
makes up the border of Once the objects are selected, drag them to move them. When
the box. they are located where you want them, click anywhere outside the
object (or press Enter) to deselect them. Pressing Del or Backspace
will delete an object that is selected.
To resize an object, place the pointer on it and press Ctrl and the
mouse button. The box blinks to show that it is selected. Drag
the mouse to make the box larger or smaller, and release the mouse
button to deselect it when it is the right size.

MANIPULATING OBJECTS USING THE KEYBOARD


You can move the cursor anywhere in the layout window by using
the arrow keys. Or you can press Tab or Shift-Tab to move the cur¬
sor from object to object.
218 MASTERING FOXPRO

CH. 6

To select an object in the layout window using the keyboard, place


the cursor on it and press the space bar. To select more than one
object at once, hold the Shift key while using the arrow key to move
the cursor; when the cursor is in the new object, press Shift and the
space bar to select it.
Once the object is highlighted to show it is selected, use the arrow
keys to move it. When it is located where you want it, press Enter to
deselect it. You can delete an object that is selected by pressing the
Del or Backspace key.
Since you can only To resize an object, place the cursor on it and press Ctrl and the
move the bottom
and right lines of a box to
space bar. The box blinks to show that it is selected. Use the right or
resize it using the key¬ down arrow keys to resize the box. Press Enter to deselect it when it is
board, it is best to move it the right size.
before resizing it, if you
need to do both. First
move the upper left cor¬
ner of the box to where THE REPORT MENU
you want it to be. Then
adjust the right and
Most of the options of the Report menu popup, shown in Fig¬
bottom lines. ure 6.3, are simple and easy to use. If you select Field, however, you
call up the Report Expression dialog box, which contains a number
of special features. These special features are not often needed. We
will cover them here briefly, but keep in mind that the best way to
learn to create reports is to look through the entire Report menu rela¬
tively quickly to see what it can do.

PAGE LAYOUT
If you select Page Layout from the Report menu, you can use the
Page Layout dialog box shown in Figure 6.4 to set margins, page
length, and the like.
Page Length determines how many lines will be printed on a single
page. FoxPro subtracts the number of lines for the top and bottom
margins from the total number of lines on the page to determine how
many lines to print. The default Page Length setting of 66 lines is
what almost all printers print on ordinary 8V2-by-l 1-inch paper.
Change this setting only if you are using some unusual paper (such as
legal-size paper) or have a printer that does not print the standard
66 lines per page.
GENERATING REPORTS AND MAILING LABELS 219

Figure 6.3: The Report menu popup.

Figure 6.4: The Page Layout dialog box.


220 MASTERING FOXPRO

CH. 6

Top Margin and Bottom Margin determine the number of blank


lines that appear at the top and bottom of each page. On most
printers, six lines are equal to one inch, and this is often a good set¬
ting for each margin.
It is best to set the Printer Indent (Columns) determines the size of the left margin.
left and right mar¬
gins when you first begin
Most fonts on most printers print ten characters to the inch; so 10 is
designing the report, so often chosen for the left margin.
that you can take the The Right Margin Column (in combination with the printer
ultimate printing width
indent) determines the size of the right margin. Your computer
into account as you lay
out the data. screen displays 80 characters across, and most printers print only
80 characters of an unproportioned font. (At 10 characters per inch,
most printers will not print more than 80 characters even though
8V2-inch paper has enough space for 85.) If you choose 10 for the
printer indent so that there is a 1-inch left margin, choosing 65 for
the right margin column will create a 1-inch right margin: the 10
columns of the left margin plus the 65 columns of text add up to
75 columns, which is 10 columns, or 1 inch, away from the right edge
of the page. These are standard margins; of course, the actual right
and left margins you choose depend on how much data you have to
fit into your report and how wide your printer is. A report can be a
maximum of 255 columns wide.

PAGE PREVIEW
If you select Page Preview from the Record menu you can see on
the screen how the report will look when it is printed out. Page Pre¬
view does not display type styles, such as bold, underline, or italic,
but it does include text, field expressions, lines, and boxes, just as
they will appear in the printed report.
If your report is wider than your screen, you can scroll right and
left to see the entire width of the report. At the bottom of the Page
Preview window is a status line which tells you the column where the
cursor is and also includes two text buttons—Done and More.
You can go through the report a screen at a time by selecting
More, or select Done at any time to stop previewing the report.
GENERATING REPORTS AND MAILING LABELS 221

DATA GROUPING
Selecting Data Grouping from the Report menu popup lets you
group data. A grouped report might, for example, print the data for
each state separately, and it could include a header and footer
for each state. Often the group footer includes a calculated field that
summarizes the data in the group.
When you add a grouping, new bands appear in the report layout
window to hold the group header and group footer. You can work
with these bands in the same way you work with any other bands.
Selecting Data Grouping calls up the Group dialog box, shown in
Figure 6.5. As you can see, this dialog box lets you add, change, or
delete a grouping. The scrollable list on the left represents groups that
have already been added; you can select a group from the list to
change or delete. This list can include up to 20 levels of groupings.
For example, you can group by state, by city within each state, and
so on. In the illustration, records have been grouped by state; within
each state, they are grouped by city; and within each city, they are
grouped by zip code. Notice how the bands for these groupings
are placed in the report layout window (still visible on the left behind
the dialog box).

System File Edit Database Record Program Window Report


UNTITLED.FRX
R: 0 C: 0 1| Move I Page Header ||__
PgHead
PgHead
PgHead
PgHead
r1—STATE Group: _
r2-CITY QHKQHB
r3-ZIP 1: STATE
Detai1 2: CITY
Detail ►3: ZIP
Detail < Qdd >
Detail
L-3-ZIP < @hange >
L2-CITY
L1—ST ATE < Delete >
PgFoot
PgFoot
PgFoot
PgFoot
' ^

Figure 6.5: The Group dialog box.


222 MASTERING FOXPRO

CH. 6

When you add a new grouping or change an existing one, the


Group Info dialog box shown in Figure 6.6 appears to let you specify
how the data is grouped.
By far the most important feature of the Group Info dialog box is
the Group text button. You can type the expression that you want the
group to be based on to the right of this text button, or you can select
it to call up the expression builder to create the expression. Usually,
the grouping expression is something simple—a field name such as
STATE. You might also want to use a simple expression such
as UPPER(STATE), if there is a chance that the state names are not
all capitalized.

Figure 6.6: The Group Info dialog box.

Apart from this basic feature, the Group Info dialog gives you a
few optional check boxes:

• Swap Page Header: makes the group header appear on the


first page of each group instead of the ordinary page header.

• Swap Page Footer: makes the group footer appear on the last
page of each group instead of the ordinary page footer.

• New Page: makes each new group start on a new page.


GENERATING REPOR TS AND MAILING LABELS 223

The New Page check box is automatically selected when Swap Page
Header or Swap Page Footer is selected, since these can only be used
if each new group begins on a new page.
There one important precaution that you must remember if you
use data groupings: you must index your data properly to make sure
that the data is grouped correctly. If you group on State without
indexing, for example, FoxPro will print a new group footer and
header each time it comes to a record where the state is not the same
as it was in the previous record. The options on the menu system just
make the report print the previous group’s footer and the new
group’s header whenever there is a change in the data in the expres¬
sion that you are grouping on.
What if you want to group by state but you also want the names of the
employees within each state to be alphabetized? You have to index on
UPPER(STATE + LNAME +FNAME) or on some equivalent
expression. The index itself must put the records in the right order for
the grouping.

TITLE/SUMMARY
Selecting Title/Summary from the Report menu displays the
Title/Summary dialog box shown in Figure 6.7, which lets you add a
title or summary to the report.
As you can see from the illustration, there are two check boxes
under both Report Title and Report Summary. Checking the first
adds a title band or summary band to the report layout window. You
can work in these bands in the same way that you work in other
bands. Checking the second check box in each pair makes FoxPro
print out the report title or report summary on a separate page.
You might want to use the tide band not just for a one- or two-line
title but for an abstract of the report. Similarly, you could use it for a
cover letter to each person who gets the report. This is one case where
you would want it to appear on a separate page.
Of course, the title actually appears below the header of the first
page, even though the title band is above the page header band. Simi¬
larly, Summary actually appears above the footer of the last page,
even though its band is below the page footer band.
224 MASTERING FOXPRO

CH. 6

Figure 6. 7: The Title/Summary dialog box.

BOX
After you select Box from the Report menu, the word Box appears
on the status line and you can add boxes or lines anywhere in the
report layout window.
If you are using a mouse, move the pointer to where you want a
corner of the box to be. Click and drag on a diagonal to create the
box, and release the mouse button when you reach the point where
you want the opposite corner.
If you are using the keyboard, move the cursor to where you want
a corner of the box to be, and press the space bar. Then press the
arrow keys to move the opposite corner into position. Once the box is
the size you want it to be, press Enter.
You create lines in exactly the same way you create boxes, using
either the mouse or the keyboard: just be sure to stretch the box in
only one of the basic directions—up, down, left, or right. (You can¬
not draw diagonal lines—only horizontal or vertical. As soon as you
try to draw a diagonal line, you are necessarily creating a box.)
If you select an existing box (by using the mouse or by putting the
cursor on it and pressing Enter) you will call up the Box dialog box,
shown in Figure 6.8. As you can see from the illustration, the Box
dialog box includes radio buttons that let you choose what character
GENERATING REPOR TS AND MAILING LABELS 225

Figure 6.8: The Box dialog box.

the box or line is made of. The basic choices are Single Line or Dou¬
ble Line. But you can also select Character to display the dialog box
shown in Figure 6.9 that lets you choose any DOS character. For
example, you might want to create a box made of asterisks to high¬
light some very important data. As you can see from the illustration,

Figure 6.9: The Select a Character dialog box.


226 MASTERING FOXPRO

CH. 6

you can even make a box out of smiling faces (if your printer will
print such characters).
If the box you are drawing occurs entirely in the detail band of the
report, the Float As Band Stretches check box appears in this dialog
box. If it is selected, the box will expand vertically if you make the
band larger to display more field data. If it is not selected, the box will
remain the same size when you expand the band, so that the addi¬
tional data will end up outside the box. If you put a box around a
memo field, you should select this check box so that longer memos do
not overflow the size of the box.
Remember that a box or line is an object, and you can move,
resize, or delete it as you do other objects. See the previous sections
on Manipulating Objects Using a Mouse and Using the Keyboard.

FIELD

Selecting Field from the Report menu popup calls up the Report
Expression dialog box shown in Figure 6.10, which lets you place field
expressions in the report layout window as follows: First place the cursor
where you want the field to be located. Then select Field from the
Report menu. Then type the expression to the right of the Expr text but¬
ton (or select the Expr text button to call up the expression builder,
which you can use to create the expression just as you did in earlier
chapters). When you move the cursor after entering the expression (by
pressing Tab or using the mouse), the expression’s width is automati¬
cally entered. Choosing OK places the expression.
You can include a page number in an expression by selecting
_PAGENO from the list of memory variables. This should be used in
the header or footer for long reports.

Formatting Fields The Format text button calls up the Format


dialog box shown in Figure 6.11, which lets you format the field you
are placing in a variety of ways. As you can see from the illustration,
this includes four radio buttons to indicate the data type of the field
GENERATING REPOR TS AND MAILING LABELS 227

Figure 6.10: The Report Expression dialog box.

Figure 6.11: The Format dialog box.

that is being formatted—Character, Numeric, Date, or Logical. The


Editing Options check boxes change according to the data type of the
field being formatted. The options for all the data types are sum¬
marized in Table 6.1.
228 MASTERING FOXPRO

CH. 6

Table 6.1: Editing Options Check Boxes Available for Formatting Data

Radio Check
Button Boxes
Selected Available Effect

Character Alpha Only only letters are allowed

To Upper letters are capitalized


Case

R non-format characters are not


stored, though they are displayed

' Edit “SET” the date is displayed using


Date whatever format is determined by
the current SET DATE command
(an environment command
covered in Chapter 7)

British Date the date is displayed in the


European format

Trim both leading and trailing blanks


are trimmed

Right Align data is right-justified

Center data is centered on the line

Numeric Left Justify data is left-justified, like character


data

Blank if the expression’s value is zero,


If Zero nothing is printed

(Negative) negative numbers are printed in


parentheses, as they usually are in
accounting

Edit “SET” the date is displayed using


Date whatever format is determined by
the current SET DATE command

British Date the date is displayed in the


European format
GENERATING REPORTS AND MAILING LABELS 229

Table 6.1: Editing Options Check Boxes Available for Formatting Data
(continued)

Radio Check
Button Boxes
Selected Available Effect

Numeric CR CR (which stands for Credit)


If Positive appears after all positive numbers

DB DB (for Debit) appears after all


If Positive negative numbers

Leading pads out the length of the field with


Zero leading zeros

Currency displays the expression in currency


format

Date Edit “SET” the date is displayed using


Date whatever format is determined by
the current SET DATE command

British Date the date is displayed in the


European format

Logical none none

In addition to the options that are available through check boxes,


you can enter templates to the right of the word Format in the upper
left of the dialog box, to format an expression on a character-by¬
character basis. A template is a series of symbols that control the for¬
mat of the entry. The special formatting characters are summarized
in Table 6.2. Any character apart from these special characters can
also be used in a template as a literal, which means the character itself
will appear in the formatted expression. For example, you can format
Social Security numbers using the template 999-99-9999. In this
case, the 9s are symbols that let the user enter only numbers, and the
hyphens are literals.
230 MASTERING FOXPRO

CH. 6

Table 6.2: Special Characters for Format Templates

Character Effect

A displays only letters

L displays only logical data

N displays only letters or numbers

X displays any character

9 displays only numbers when used with character


data, or displays numbers and signs when used
with numeric data

# displays numbers, blanks, and signs

$ displays a dollar sign in a fixed location before a


numeric value (if the value includes leading blanks,
there will be a space between the dollar sign and
the number)
<0- <fr>
4P4P displays a floating dollar sign before a numeric
value (if the value includes leading blanks, the
dollar sign will move right so there is no space
between it and the number)
* uses asterisks to fill the leading blanks of a numeric
value (this is often used on printed checks)

• shows the location of a decimal point

adds commas to separate values to the left of the


decimal point

Text is always
displayed on the
Selecting Type Style Selecting the Style check box calls up the Style
screen in Normal style— dialog box shown in Figure 6.12, which lets you determine the type style
even when you preview in which the fields will be printed. The number of style options you are
the page using Page
given depends on the capabilities of your printer. At most, you are given
Layout from the Record
menu. The attributes you the choice of Normal, Bold, Italic, Underline, Subscript, Superscript,
choose are visible only Condensed, and Double-sized type.
when you print out the
report.

Creating Computed Fields Selecting the Totaling check box calls up


the Total dialog box shown in Figure 6.13, which lets you create
GENERATING REPOR TS AND MAILING LABELS 231

Figure 6.12: The Style dialog box.

Figure 6.13: The Total dialog box.

computed fields. As you can see, this dialog box contains six radio
buttons, to select the calculation to be performed on the field:

• None: no calculation is performed

• Count: counts the number of fields


232 MASTERING FOXPRO

CH. 6

• Sum: totals all the values of the field

• Average: finds the average value in the field

• Lowest: finds the lowest value in the field

• Highest: finds the highest value in the field

The default calcula¬ For example, if you had WAGE as the field expression in the Report
tion in the Total Expression dialog box and you checked the Totaling check box, and
dialog box is None. If you
then selected the Average radio button in the Total dialog box, you
do not select the Totaling
check box and use this would create a calculated field that finds the average wage. Notice
dialog box, then no calcu¬ that the Total dialog box includes the Reset popup control, which
lation is performed.
determines how often the calculation will be done. The default is End
of Report, which does the calculation only once, at the end, obvi¬
ously. If you have grouped data, you can also select the name of any
of your groups from the popup, and perform the calculation for each
group; or you can select End of Page from the popup, for example, if
you want to put the total in a footer. The Total field itself must always
be numeric.

Other Features of the Report Expression Dialog Box If you select the
Suppress Repeated Values check box, then if the value of the field is
the same for more than one record, only the first occurrence of the
value will be printed. For example, if you have a report that is
indexed by state, you might want to put the State field at the far left of
the report and select this option so that each state’s name appears
only once.
Finally, you should remember that after a field expression is placed
it is an object, and you can select it and manipulate it as you do any
object. See the previous sections on Manipulating Objects Using a
Mouse and Using the Keyboard.

TEXT

Unlike the case with boxes and field expressions, you do not have
to use the Report menu to position text in the report layout window.
If you wish, you can select Text from the Report menu popup at any
time to enter the Text mode, but the main reason for doing so would
be to edit text that has already been added.
GENERATING REPOR TS AND MAILING LABELS 233

To add text, you can just put the cursor where you want it to begin
and start typing. Until you either press Enter or reach the end of a
line, you can edit the text; after that, the line of text you added is
treated as an object and must be selected and manipulated like a box
or graphic object. The whole block of text is then treated as a single
object.
ft) To edit text after it becomes an object, you can select the object
and then select Text from the Report menu. Alternatively, you can
edit text by moving the mouse pointer to it and pressing Ctrl while
you click the mouse, or by moving the cursor to it and pressing Ctrl
and the space bar.
If you select a text object that is in the detail band by using the
mouse or by placing the cursor in the text and pressing Enter,
the Text dialog box, shown in Figure 6.14, appears.

• Float As Band Stretches: If you check this box, the text will be
printed on the line following the last line of a vertically
stretched field. Fields that use this option must be placed on a
$

line below the first line of the vertically stretched field.

• Style: This check box calls up the same Style dialog box
discussed in the previous section on field objects. The Style

Figure 6.14: The Text dialog box.


234 MASTERING FOXPRO

CH. 6

dialog box lets you determine the type style in which the text
is printed.

ADD LINE
If you press Shift Selecting Add Line from the Report menu popup lets you make
when you open the bands larger by adding a line to them. The new line is added above
Report menu—by press¬
ing Shift-Alt-R if you are
the current position of the cursor. Select the option as many times as
using the keyboard or by you want for any band; the only limit is that the total number of lines
holding down the Shift in all the bands may not be more than 255.
key while you pop up the
menu using the mouse—
the popup wiD include an REMOVE LINE
Add Line After option
instead of the ordinary Selecting Remove Line from the Report menu lets you make
Add Line option. This bands smaller by deleting the line that the cursor is in. If you have
option inserts the line
after the current position
already entered anything on this line when you select this option,
of the cursor. FoxPro will ask if you want to delete the objects on the line. If you
choose Yes, it will delete both the line and the objects on it.

BRING TO FRONT AND SEND TO BACK


\

These two options change the way in which overlapping expres¬


sions appear. For example, if you draw a line that partly covers a text
object but you actually want the text object to appear in front of the
line, you can use either one of these options to rearrange them: select
the text object and then select Bring to Front, or alternatively, se¬
lect the line object and then select Send to Back.

CENTER
Select an object and then select Center from the Report menu in
order to center the object on its line. Note that the location of the
‘ Tenter” of the line depends on the margins that you choose by
selecting Page Layout. Furthermore, if you are centering a field
object, you must choose the Center check box from the Format dia¬
log in addition to choosing this option.

QUICK REPORT
Selecting Quick Report from the Report menu calls up the Quick
Report dialog box shown in Figure 6.15. You can use this dialog box
GENERATING REPORTS AND MAILING LABELS 235

Figure 6.15: The Quick Report dialog box.

to place field data in the report automatically, so you do not have to


place each field expression individually.
You can see that this dialog box contains two radio buttons and
two check boxes:

• Column Layout: places the fields in the detail band one next
to another, from left to right.

• Form Layout: places the fields in the detail band one above
another, from top to bottom. The detail band will automati¬
cally stretch to hold all the fields.

• Title: determines whether the field name will be placed above


each field (if they are arranged in column layout) or to the left
of each field (if they are arranged in form layout).

• Field: displays the field picker dialog box (which you looked
at in the last chapter) to let you choose which fields are ini¬
tially displayed in the quick report.

Since it only includes fields and not field expressions, the Quick
Report option is of limited use.
236 MASTERING FOXPRO

CH. 6

A SAMPLE REPORT
With this background, you should have no trouble creating a sophis¬
ticated sample report. In this exercise, you will create a report that
groups employees by state, listing their names (alphabetically) and their
wages. Among other features, the report will include group footers with
the number of employees and the average wage for each state and a
report footer with the same information for all the employees.

1. If necessary, enter CD\LEARNFOX and then enter FOX¬


PRO. Then enter CLEAR if you want to clear the screen.
You will begin work on the report by opening the database
file and creating the index needed to create a report grouped
on state and arranged alphabetically by name within each
state. Thus, select Open from the File menu and select
EMPLIST.DBF. Then select New from the File menu,
select the Index radio button, and select OK. When the
Index On dialog box appears, type

UPPER(STATE + LNAME + FNAME)


to the right of the Expr text button (or use the expression builder
to create this expression), and select OK. Then, when the Index
File Name dialog box appears, type ST_NAME (for State
Name) and select OK.

2. The EMPLIST file is now open with this new index active,
so you are ready to design the report. Select File New from
the File menu popup, select the Report radio button, and
then select OK to call up the report layout window.

3. Set the report margins using Page Layout from the Report
menu. Make the top margin 6 rows, the bottom margin 6
rows, the printer indent 10 columns, and the right margin
column 65. Then select OK.

4. Add a title and summary band to the report: Select Title/


Summary from the Report menu. Select both the Title Band
and the Summary Band check boxes. Select OK.

5. Add a few extra lines to the title band: The cursor should
already be in the title band. Select Add Line from the Report
menu to add an extra line. Repeat this step two more times,
so the title band has four lines in all.
GENERATING REPOR TS AND MAILING LABELS 23 7

6. Add the title: Press the down arrow to move the cursor to the
second line of the title band, and type

Employee Wages by State


Press Enter to finish creating this text object. Now select the
text object you just created. (Since the cursor is in it, you can
just press the space bar.) Then select Center from the Report
menu to center it on the line. Press Enter to deselect it.

7. Put a box around the tide: Move the cursor to row 0, column 19
(one row up from and two columns to the left of where the tide
begins). Then select Box from the Report menu. Use the key¬
board or the mouse to draw the box so it is centered around the
tide, as shown in Figure 6.16.

Figure 6.16: Centering the report title.

8. Create the page header: First remove one line from the PgHead
band. Move the cursor to that band and select Remove Line
from the Report menu. Move the cursor to the top line of the
page header band and to the left edge of the screen. Select Field
from the Report menu. To the right of the Expr text button,
type

"data accurate as of " + DTOC(DATE())


238 MASTERING FOXPRO

CH. 6

Press Tab and note that the width of the expression you
entered, 30, automatically appears. Select OK. Note also
that the expression as it now appears on the report seems
incomplete. This is because it can take up only 30 spaces, the
actual width the expression’s result will occupy on the report.
9. Add group bands: Select Data Grouping from the Report
menu. When the Group dialog box appears, select Add. Then,
when the Group Info dialog box appears, type STATE to the
right of Group, and select OK. This returns you to the Group
dialog box where STATE is added as group 1. Select OK.
Notice that the group header and footer named 1-STATE have
been added to the report layout window.

10. Add the group header: Move the cursor to that band. Select
Add Line twice from the Report menu so that there are three
lines in the band. Move the cursor to its second line, at the
left edge of the screen. Select Field from the Report menu. In
the Report Expression dialog box, to the right of the Expr
text button, type (in all capital letters)

"EMPLOYEES IN THE STATE OF " + UPPER(STATE)


and press Tab. The width—28—is entered automatically.
Select OK.

11. Enter the detail line: Move to the detail band. Select Remove
Line twice from the Report menu to make it just two lines.
Move the cursor to the second line of the band, flush with the
left margin. Select Field from the Report menu. Since the
WAGE of the detail line is not used in a calculation, you can
enter the entire detail line as a single string expression. In the
Report Expression dialog box, to the right of the Expr text but¬
ton, type

PROPER(LNAME + " " + FNAME) + " $" + LTRIM(STR


(WAGE,5,2))
This expression capitalizes the last and first name properly
and puts a blank between them to make sure there is a space
between columns. It also uses STR() to convert the wage
from a number to a string five characters long, with two deci¬
mal places. It adds this to the expression with a space and a
GENERATING REPORTS AND MAILING LABELS 239

dollar sign before it, using LTRIM to make sure that there is
no space between the number and the dollar sign. Press Tab,
and the width—42—is automatically entered. Select OK.

12. Add the group footer, which will summarize how many
workers there are in the given state and their average wage:
Move the cursor to the group footer line. Select Add Line
three times from the Report menu so that there are four lines
in the band. Move the cursor to the second line in the band,
at the left margin. Select Field from the Report menu to call
up the Report Expression dialog box. You can count any
field to get the number of workers; we’ll use LNAME. Enter
this to the right of the Expr text button. Then select the
Totaling check box to call up the Total dialog box. Select
the Reset popup control and select STATE from the popup
that appears; then select the Count radio button; and select
OK to return to the Report Expression dialog box. Since a
computed field must be numeric, select Format, then select
the Numeric radio button and select OK. Since you know
that there will be no more than 99 employees in any of the
states, enter 2 as the width of the computed field. Then select
OK. Only the first two letters of the field name, in this case
LN, are displayed to show where the number goes.

D Do not press the


space bar to add
13. Since this number will be word-wrapped by default, you can
continue with text to its right: Press the right arrow key twice
spaces between columns.
to leave one blank space after the field. Then select Field from
It will only select the
object, since the cursor is the Report menu. In the Report Expression dialog box, type
on the object that you just
finished creating.
"EMPLOYEES FROM " + STATE + AVERAGE WAGE"
to the right of the Expr text button. Press Tab to automati¬
cally add the width—31—and select OK.

14. Press the right arrow key twice to leave a space before the
amount of the wage. You want to left-justify this amount so
that there are no extra spaces between it and the preceding text
if the number is small. Select Field from the Report menu. In
the Report Expression dialog box, type WAGE to the right
of the Expr text button. Select the Totaling check box. In the
Total dialog box, select the Reset popup control and select
240 MASTERING FOXPRO

CH. 6

STATE from the popup. Select the Average radio button,


then select OK. In the Report Expression dialog box, select
the Format text button to call up the Format dialog box, and
select the Numeric radio button. Among the editing options,
select the Left Justify and Currency check boxes; then select
OK. Back in the Report Expression dialog box, increase the
Width to 6 to allow for the dollar sign you just added, and then
select OK.

15. Add a page footer: Move the band to the last line of the footer
band. Type

Report on wages by state


and press Enter. Then press the space bar to select the new
text object, select Center from the Report menu to center it,
and press Enter to deselect it.

16. Finally, add the report summary: Move to the summary


band. Select Add Line three times from the Report menu to
make it a total of four lines. (The extra lines are not visible as
you add them, because they appear beyond the bottom of the
screen.) Move the cursor to the fourth line, at the left margin.
Adding the summary line at this point is almost exactly like
totaling the wages for each state as we did in Step 14. First,
though, repeat Step 12, which you used to add the group
footer—but do not select the popup control: leave it at the
default value, End of Report, so that it gives the count of
employees in the entire database.

17. Press the right arrow twice and type

EMPLOYEES IN TOTAL: AVERAGE WAGE


Then repeat Step 14, which you used to add the average to
the group footer, but once again leaving the popup control
at the default value, End of Report, to get an overall average.
The layout window is shown in Figure 6.17 (though some of
the layout has scrolled beyond the top of the window).

18. Select Page Preview from the Report menu to preview the
report. The first screen displayed should look like Fig¬
ure 6.18. Select More if you want to page through the report.
Select Done when you have seen enough.
GENERATING REPOR TS AND MAILING LABELS 241

System File Edit Database Record Program Window Report


UNTITLED.FRX
R: 23 C-. 0 i Move || ' Summary

PgHead
PgHead
r1—STATI
r1-STATE|"EMPL0YEES IN THE STATE OF "
rl-STATf
Detai1
Detail _|PROPER(LNAME+" "+FNAME)+" $"+LTRIM(STR(WA6E
L1—STAT
Ll-STATE|LN "EMPLOYEES FROM " + STATE + WAGE
Li—STAT
Li-STAT
PgFoot.
PgPoot
PgFoot
PgFoOt Report on wages by state
Summar
Summar
Summar
SummaryflLN EMPLOYEES IN TOTAL: AVERAGE WAGE WAGE

Figure 6.17: The final layout of the report.

Figure 6.18: Using the Page Preview feature to test the report.

19. Select Save As from the File menu to use the Save Report As
dialog box, shown in Figure 6.19. Note that the Save Envi¬
ronment check box is already checked: this is the default.
Type the name ST_WAGE (for the State Wage report), as in
J

242 MASTERING FOXPRO

CH. 6

Figure 6.19: The Save Report As dialog box.

the illustration, and select Save. Now that you are finished
designing the report, close the report layout window as you
would any window.

20. Now select Report from the Database menu. Note that in the
Report dialog box, shown in Figure 6.20, the Environment
check box is already checked by default, which means that
the index will be opened automatically. Select the Form text
button at the upper left to call up the Report file dialog box,
and select STJWAGE.FRX.

21. In the Report dialog box, neither To Print nor To File have
been checked, but the Console On radio button is selected.
This means that when you produce the report, it will be dis¬
played on the screen but will not go to the printer or to a text
file. (You can change these settings if you want.) Select OK
to produce the report. Be patient: it can take a while before it
scrolls by. If you are just producing it on the screen, all the
information is displayed just as it would be on a page.

You might want to modify this report and try other features of the
report generator on your own. For example, you could try different
type styles or try making each group start on a new page, or try using
GENERATING REPOR TS AND MAILING LABELS 243

System File Edi.t. Database Record Program Window


11 records indexed

Report:

< f- arm. . [X] [Jnvironment Scope. . .

Shiie!..

lain
_ Eject
Summarjjj
Heading

To flrint
' Do File
,• fflonsole On ( ) Console

Figure 6.20: The Report dialog box.

the _PAGENO memory variable in the expression builder to add a


page number.

CREA TING MAILING LABELS -


FoxPro’s mailing label generator works a bit like its report genera¬
tor. Of course, creating labels is much simpler, since labels do not
need to include graphics, summary fields, titles, footers, or many of
the other features of reports.
As with reports, there are two steps to creating FoxPro labels.
First, you design the labelform, which determines how field data (and
other text, if you want it) is laid out. Once you have the label form
you want, you can actually produce the labels.
You create a new label form in a familiar way: select New from the
File menu and then select the Label radio button. This calls forth

H The open index and


other environment
the label layout window, shown in Figure 6.21. When you are using the
label layout window, a Label menu pad is added to the menu bar.
settings can be saved in A database must be open for the Label radio button to be enabled,
an .LBV file, just as a
report environment can
since the label form (like the report form) uses fields from the current
be saved in an .FRY file. database; you should also open the appropriate index if you want
244 MASTERING FOXPRO

CH. 6

System File Edit Database Record Program Window Label


_ UNTITLED. I BX__

Remarks 3 1/2" x 15/16" x 1

Margin Width Number Across


\-t -1-35 -► 1

e
H T Spaces
i 5 i—t —►
9 Between
h
■(- T

t
1 Lines Between
i

Figure 6.21: The label layout window.

your labels to be printed out in a special order. As usual, FoxPro


names the label form Untitled.
If you are working from the Command window, you can enter the
command CREATE LABEL Kfile name> to name the label form
from the beginning; of course, you should first enter

USE <database file name> INDEX <index file name>

As with reports, you can modify an existing label form by selecting


Open from the File menu or by using the command MODIFY
LABEL <file name>.
The next section explains in detail how you use the layout window
to design the label form. You can use the menu to select from a num¬
ber of standard layouts, and you can also customize any of the stan¬
dard layouts. You fill in the layout with FoxPro expressions to show
where the field information should be.
Once you have the layout you want, you will save it in the usual
way by selecting Save As from the File menu. As with reports, the
Save As dialog box saves the index and other environment settings by
default. It also automatically adds the extension .LBX to the name
you enter.
GENERATING REPORTS AND MAILING LABELS 245

After you have designed and saved the label form you want, you
can print the labels at any time by selecting Label from the Database
menu to call up the Label dialog box, shown in Figure 6.22.
This dialog box is very similar to the dialog box you use when you
select Report from the Database menu to print a report. As you can
guess, the Form text button lets you choose which of the existing label
forms to print, and the Environment check box next to it lets you use
the environment setting that you saved when you created the labels.
The Scope, For, and While check boxes let you print labels for
records that meet certain criteria. The To Print and To File check
boxes let you send the labels to the printer or to an ASCII file, and the
Console On and Console Off radio buttons determine whether
the labels are displayed on the screen, just as with reports.

Figure 6.22: The Label dialog box.

The one difference is the Sample check box. This feature lets you
print a single sample label in order to check the alignment of the label
paper in your printer. The sample label will contain asterisks to show
you where data goes on the label. After the sample is printed, a dialog
box appears asking if you want another sample. If the printer is out of
alignment, you can move the label paper and then select Yes from
this dialog box to see if the new alignment is correct. If the paper is
correct, select Do Labels to print all the labels.
246 MASTERING FOXPRO

CH. 6

From the Command window, you would enter LABEL FORM


Kfile name>. The most important option for this command is a FOR
or a WHILE clause, which can be followed by either TO PRINT or
TO FILE Kfile name>. For all the options used with this command,
see your Commands and Functions book.

LA YING OUT LABELS


As you have seen, the label layout window starts you off with the
default layout of 3 V2" x 15/i6" x 1. If you look back at Figure 6.21
again, you will see that these standard labels allow 5 lines of text per
label and have one blank line between labels.
You can select Layout from the Label menu popup to choose
among these other standard layouts:

• 3 V2" X 15/l6" X 1

• 3 V2" X 15/l6" X 2

• 3 V2" X 15/i6" X 3

• 4" X 1 7/l6" X 1

• 3 2/io" x 1 Vi2" x 3 (Cheshire)


• 6 V2" x 3 5/s" envelope

• 9 Vs" x 7 Vs" envelope

• 3" x 5" Rolodex

• 4" x 2 V4" Rolodex

As you can see, not all of these layouts are restricted to labels. If
your printer is capable of it, they also let you print directly on the two
standard sizes of envelope, on 3-by-5-inch index cards (or that size
Rolodex cards), and on the other standard size of Rolodex cards.
If none of these standard layouts is adequate, you can start with the
one that is closest to what you need and customize it by simply chang¬
ing the settings in the layout window. For example, you can see that
the left margin back in Figure 6.21 is 0; if you want to add a
1-inch left margin, just change that number to 10 (assuming that you
are using a standard printer with ten characters per inch). Likewise,
you can edit the width, height, lines between, spaces between, and
GENERATING REPOR TS AND MAILING LABELS 24 7

number across to create any label layout you choose, and edit the
remarks to change the size description.
Notice this other When you have the right layout size, just enter expressions in the
difference from the
report layout window.
sample label on the window. You can use the expression builder to do
When you are designing this by selecting Expression from the Label menu popup, or you can
reports, you must use the just type in the expressions.
menu to add expressions,
Remember that any text enclosed in quotation marks (or in the
since anything you just
type is treated as text. On other delimiters that FoxPro allows for character literals) is a valid
the other hand, there are FoxPro expression. If, for example, you run a membership organiza¬
only expressions on label
tion and you are using a FOR clause to print labels for people who
forms. Thus, you can just
type expressions in as have not paid their dues, you can include the expression “PLEASE
well as using die menu to PAY YOUR DUES” somewhere on the label.
add them. Often, a line of a label must include the contents of two fields with
just a blank space between—for example, the first name field and the
last name field. You can use the expression

TRIM(FNAME) + " " + TRIM(LNAME)

to print this, but since it is so common, FoxPro also gives you a short¬
cut. If you simply separate each field expression with a comma, Fox¬
Pro trims the contents and puts one space between.
If there is a possibility that an expression will evaluate to a blank
space, you should add a semicolon after it so there will not be a
blank line left in the labels. You will do this for the apartment num¬
ber when you are creating sample labels, since that field is blank in
many records.
That’s about all there is to creating label forms. The Label menu
popup, shown in Figure 6.23, is very easy to understand. It has just
five features.

• Page Preview: lets you see on the screen how the labels will
appear in print. It works just like the feature with the same
name on the Report menu.

• Expression: lets you use the expression builder to enter expres¬


sions in the label layout window. Remember, though, that you
can also just type expressions into the layout window.

• Layout: lets you choose among the standard label layouts.


248 MASTERING FOXPRO

CH. 6

• Save Layout: lets you save a customized layout you have


designed, adding it to the list of available layouts you can
choose from when you select Layout. Then, whenever you
are designing labels for the paper or cards that you created
this layout for, you can just select this layout as if it were a
default layout and fill in the fields.
• Delete Layout: lets you delete a label form that you designed
and saved.

System l ilc L d11. Database Record Program Window Labal


UN TITLED.'I BX

Remarks 3 1/2" x 15/16" x 1

Margin Width Number Acros lyout


M — —-35 --► 1 we Layout. ..
»lete Layout.
H
e
i 5
1 Spaces
4—0 —►
g Between
h
t
t
1 Lines Between
i

Figure 6.23: The Label menu popup.

Now, you should have no trouble laying out some sample labels:

1. If necessary, enter CLEAR to clear the screen. If you do not


already have EMPLIST.DBF open, select Open from the
File menu and open it. Assuming that you want the labels in
zip code order, open the Zips index: Select Open again from
the File menu, select Index using the popup control, and
select ZIPS.IDX from the scrollable list of file names.

2. To start designing the labels, select New from the File menu
popup, select the Label radio button in the New dialog box,
and select OK.
GENERATING REPORTS AND MAILING LABELS 249

3. The label layout window appears, with the cursor on the first
line of the label form. Type
PROPER(FNAME),PROPER(LNAME)
and press Enter. On the second line, type

PROPER(ADDRESS)
and press Enter. The third line contains the apartment num¬
ber with ten spaces before it, so it is indented, and a semi¬
colon after it, so there is no blank line for addresses without
an apartment number: type

" <10 spaces >" + APT_NO;


and press Enter. Finally, the fourth line should have the city
name followed by a comma and a blank space, followed by
the capitalized state name, a blank space, and the zip code:
type

PROPER(TRIM(CITY)) + ", " + UPPER(STATE) + " " + ZIP


and press Enter. The final form is shown in Figure 6.24.

B Some early releases


of FoxPro did not
4. To check the form you created, select Page Preview from the
Label menu. When you are finished, select Done.
implement the feature that
suppresses blank lines.
Check your page preview
window to see if blank lines System. File Edit. Database Record Program Window • Label
UN Till. ED. I. BX ■■
are suppressed.
Remarks 3 1/2" x 15/16" x 1

Marqin Width Number Across


\-0 -1-35 -► 1

H PROPERt FNAME).PROPER(LNAME)
e PROPER(ADDRESS) Spaces
i 5 " "+APT NO; i—0 —►
g proper(trim(city7)+", "+UPPER(STATE Between
t
t
1 Lines Between
i

Figure 6.24: The label form, filled out with expressions.


250 MASTERING FOXPRO

CH. 6

You should also try some other layouts. Select Layout from
the Label menu, select other default layouts, and select Page
Preview to see how they look.

6. Now, try customizing the default settings. Select Layout


from the Label menu and select the second standard layout to
get two-across labels. Then change the width from 35 to 42
and change the number of spaces between from 2 to 1.
Change the Remarks line to 4" x 15/i6" x 2. This setting
lets you print on a fairly common type of two-column label
paper. This layout is shown in Figure 6.25.

Figure 6.25: A custom label form.

7. Save this custom layout. Select Save Layout from the Label
menu. When the Save As dialog box appears, select OK to save
it under the suggested name. Select Layout again from the
Label menu to confirm that your custom layout has been added
at the end of the list of layouts, as shown in Figure 6.26.

Save the label form. Select Save As from the File menu. Note
that the Environment check box is checked by default. Enter
the name TWO_COL, since this form prints two column labels,
and select Save. Then close the label layout window as you
would any window.
GENERATING REPORTS AND MAILING LABELS 251

Figure 6.26: The label menu popup with the custom form added.

9. Select Label from the Database menu. The Label dialog box
is the same as the dialog box you used to produce reports.
Select Form, and then, from the Label File dialog box, select
TWO_COL.LBX. Select OK from the label dialog box to
send the labels to the screen.

WHAT NEXT? -
Now you have learned all the basic features of FoxPro that are
needed for most ordinary purposes. You can define the structure of a
database; add, edit and view data; create indexes; query to find data
you want; and create reports and mailing labels. This is all you need
to know for most basic database applications.
At this point, you must choose how to continue your work with
FoxPro.
If you have an application that you can manage with the tech¬
niques that you have learned so far—such as running a mailing list—
you might want to go ahead and get practical experience with that
application without learning any more about FoxPro. Before you do
this, though, you should look at the brief discussion of relational data¬
bases in the next chapter to see if you might need these techniques to
manage your data.
252 MASTERING FOXPRO

CH. 6

If you want to go right ahead with this book, you can either go
ahead to Part II or skip right to Part III, depending on your interests.
Part II covers more advanced FoxPro techniques. It takes you
through the menu options that have not been covered yet and teaches
you to create keyboard macros, to create formatted input screens,
and to use the applications generator to create entire menu-driven
applications that can be used by people with absolutely no experience
with FoxPro. If you want to explore every facet of FoxPro and to
become a power user, go on to Part II.
Part III includes an introduction to computer programming with
FoxPro and then teaches you to create a menu-driven mailing list
application, a program that is as powerful as many commercial appli¬
cations. If you are eager to learn about programming, you can skip
Part II for now and go right to Part III. You should go back to Part II
later, however, when you want to learn advanced techniques to add
more power to your programming.
ART II
Using the View Window
with Relational Databases
To create a View, 263
select View from the Window menu to call up the View win¬
dow. Use the panels of this window to set environment vari¬
ables. Select Save As from the File menu to save these settings
in a .VUE hie.

To create a relational database, 263


first normalize the data: look for one-to-many and many-to-
many relationships, and break the data down into multiple hies
to avoid repetition. Relate them by including a common key
held, such as employee number, in all the hies.

To open multiple files at the same time, 264


open the hies in different work areas. Select the work areas by
moving the highlight in the View window or by using the com¬
mand SELECT < work area >.

To use fields from multiple files, 264


they must be referred to as follows. Fields in the hie in the cur¬
rent work area can be referred to simply by name. Fields in hies
in other work areas are referred to by letter (from A to J) fol¬
lowed by the arrow operator - > and held name, by number
(from 1 to 10) followed by the arrow operator and held name,
or by hie name (or alias) followed by the arrow operator and
held name.

To set a relation between two files, 265


the two hies must have a common key held. The hie on the “one”
side of the relationship must be indexed on its key held. The hie
on the “many” side of the relationship (the controlling hie) must
be in the current work area. Then select the Relations text button
of the View window or enter the command SET RELATION
TO Kfield namey INTO <ftle>. Relations are displayed in the
Relation panel of the View window. Moving the pointer in
the controlling hie automatically moves the pointer to the record
with the corresponding key held in the other hie.

To browse related files, 272


use the command BROWSE FIELDS <field list> with helds
from the two related hies. The controlling hie must be in the cur¬
rent work area to use its held’s names by themselves; include
helds from the other hie by using the arrow operator. When you
enter the key held of the record in the controlling hie, correspond¬
ing helds from the other hie appear automatically.

To use other commands with related files, 277


use the Fields check box of the dialog box you are using to gen¬
erate the command. This calls up the held picker dialog box.
Use the Database popup control of this dialog box to select
helds from the related hies. (Or use the command with a
FIELDS Kfield list> clause, using the arrow operator with any
helds that are not in the controlling hie.)

To create reports using relational databases, 280


select Field from the Report menu to call up the Report Expres¬
sion dialog box, and the Expr text button to call up the expression
builder, as usual. Use the Database popup control to place helds
from more than one database.
260 MASTERING FOXPRO

CH. 7

THE VIEW WINDOW, ACCESSED FROM THE WINDOW


menu popup, is one of the most powerful and advanced features of
FoxPro. This window lets you set up a special view of your data—an
entire working environment. You can then save this environment in
a file so that you can use it whenever you want.
Actually, you created views earlier when you were working with
reports and labels, but these were relatively simple views, saved and
recalled automatically only because the Environment check box was
selected by default. The View window lets you control many features
of the FoxPro environment.
Most obviously, the View window lets you control environment
settings, some of which you have looked at earlier. For example, you
have seen that you can use SET DELETE ON or SET DELETE OFF
to determine whether FoxPro commands act on records that are
marked for deletion. This is one of a large number of environment
settings that you can control using the View window.
In addition, the View window lets you use the same Setup dialog
box that you can access by selecting Setup from the Database menu.
As you remember from earlier chapters, you can use the Setup dialog
box to determine which indexes are open, to set a filter that deter¬
mines which records the user can access (in the same way that a FOR
clause does), or to set fields so that the user can access only certain
fields in the database file.
You can begin to see why this is called a view of the data. If you let
the user see only certain records and certain fields of those records,
and if you also control settings such as whether deleted records are
processed, then you are determining how the user sees the data. You
might take your EMPLIST database and set it up for one user to see
only names and addresses from California, and for another user to
see the names and wages for all employees. The two users’ views of
the data are so different that they would hardly know that they are
using the same database file.
The final feature of the View window is its most powerful: it lets
you set up relational databases. As you will see in a moment, there
are times when you should break up your data so it is stored in several
database files and relate these files to each other. The View window
lets you open more than one database file at a time and to set a rela¬
tion of this sort between two separate hies. Then, when you scroll
USING THE VIEW WINDOW WITH RELATIONAL DATABASES 261

through one file, the pointer automatically moves to the correspond¬


ing record in the other file. If you wish, you can even set up the view
so the user can open a Browse window to scroll through the records of
one file and automatically see the corresponding records of the other
file in the same Browse window—without ever knowing that more
than one database file is in use.

UNDERSTANDING
RELATIONAL DATABASES _

When businesses first computerized, as you learned in the introduc¬


tion to this book, they discovered an unexpected benefit of abandoning
their paper files: they could avoid unnecessary repetition of data.
When records were kept on paper, the payroll department kept
records on a form with each employee’s name, address, and wages;
the benefits department kept records on a form with each employee’s
name, address, and eligibility for benefits; the human resources
development department kept records on a form with each employ¬
ee’s name, address, and training; and so on. In a large business,
basic information such as the name, address, and Social Security
number of each employee might be repeated dozens of times. If the
employee moved, a dozen different forms had to be updated.
Computer scientists developed a number of methods of avoiding
this repetition, and the relational database eventually emerged as the
method of choice.
Before you can set up a relational database, you must normalize the
data—break it down in a way that minimizes repetition. In the
example above, you obviously would want to keep the employee’s
name, address, and other basic data in one file, the records of wages
in a second file, the records of eligibility for benefits in a third file, the
records of courses taken in a fourth file, and so on.
In order to relate these files to each other, you must use some key field
in all of them, such as an employee number or Social Security number.
Imagine that one file has the employee number and basic data such as
name and address. And imagine that, whenever employees are paid,
the employee number, the date, and the wage is entered in a second file.
These two files can be related to each other using the employee number.
262 MASTERING FOXPRO

CH. 7

A view can be set up that lets the payroll department scroll through the
records and look at the name, address, date, and wage just as if they
were in a single database file. This is an example of a one-to-many relation¬
ship: each employee has one name and address, but many weeks of
wages.
Though it is mean¬ Notice that the key field must be unique: it cannot be duplicated in
ingful, the Social
Security number is
more than one record in the file on the “one” side of the relation. If
acceptable as a key field, two employees had the same employee number, for example, there
since it is unique for each would be no way of knowing which one of them corresponded to a
person and never
wage record with that employee number. The key field must also be
changes.
unchanging: if you ever change its value in a record on the “one”
side of the relation, than you will have no way of relating the records
on the “many” side to it. For these reasons, you should use some
arbitrary value, such as an employee number, as the key field, and
you should never use some meaningful value, such as the person’s
name. A meaningful value might be duplicated; and it might change.
For example, two people may have the same name; furthermore,
people sometimes change their names.
Needless to say, the job of normalizing the data, breaking it down
to avoid repetition, .can be very complex if you are computerizing a
large corporation. There is an entire theory of database normaliza¬
tion that you should study if you become interested in advanced data¬
base programming. For most applications on microcomputers,
though, normalization is just a matter of common sense: you simply
have to look for one-to-many relationships.
In the example you looked at above, one employee gets many pay-
checks. In some applications, there are also many-to-many relationships.
One common example is enrollments of students in classes: each stu¬
dent can take many classes, and each class can have many students
enrolled in it. This sort of relationship will not really be covered in
this book, because many-to-many relationships are not common in
applications on microcomputers. It is good for you to know that they
exist, however, just in case you run across one—so that you will not
try to handle it as a one-to-many relationship. The theory of data¬
bases with many-to-many relationships is covered in more advanced
books. Since they are broken down into pairs of one-to-many rela¬
tionships, they can be handled using techniques similar to the ones
you will learn for one-to-many relationships.
USING THE VIEW WINDOW WITH RELATIONAL DATABASES 263

It is also possible to create one-to-one relationships. For example, you


could conceivably keep a person’s name and address in one file and
other data in another file, adding an employee number to both files to
relate them. Of course, this is not something you would normally do:
whenever there is a one-to-one relationship, it is easier to keep all the
data in one file. There might be cases, though, where you would
want to create a one-to-one relation between two files that you had
not anticipated using together, assuming that they have some field,
such as Social Security number, that you can use as the key.
In this chapter, you will use the example of wages for employees and
keep the data in two related files. You will add an employee number to
a file which already has the basic data on the employee (the EMPLIST
file), and you will create a WAGES file with the employee number,
date, and wage.

SETTING UP A RELATIONAL DATABASE


To relate two files using FoxPro, you must open them both at
once. In the past, you have always found that the current file is auto¬
matically closed when you open a new file, but the View window,
shown in Figure 7.1, lets you use several database files in different
work areas. The text buttons on the upper left of the View window let
you use its four different panels. The View panel, shown in the illus¬
tration, is the most powerful and is discussed first. The other three
text buttons let you access the On/Off, Files, and Misc panels, which
are used to make simple environment settings that will be covered
later in this chapter.
As you can see from the illustration, the View window lets you use
ten work areas, each designated with a letter from A to J. You can
move among these work areas and open a different database file in
each of them.
You can always use the database in the current work area in the
same ways that you have used databases in the past. For example,
you can refer to its fields simply by using the field name, as usual.
No matter which work area you are in, though, you can use the
fields of any file that is open in any other work area, by referring to
264 MASTERING FOXPRO

CH. 7

Figure 7.1: The View window.

them in one of the following ways, all of which use the arrow operator
that you have seen before in commands generated by FoxPro:

• the appropriate letter (from A to J), followed by the arrow


operator - > and the field name

• the appropriate number (from 1 to 10), followed by the arrow


operator - > and the field name

• the file name (or alias), followed by the arrow operator - >
Programmers some¬
times open files with and the field name
an alias, to make it easier
to follow the code. You can The arrow operator is made up of two characters, a hyphen followed
do this by using the com¬
by a greater-than sign.
mand USE <.file name>
ALIAS KaliasnameA, You can also move among work areas by using the command
after which you can refer SELECT with any of the preceding methods to refer to the work area.
to the file by its alias rather
For example, if you have the EMPLIST file open in Work Area A,
than its name.
you can move to that work area and use that file in the ordinary way
by entering SELECT A or SELECT 1 or SELECT EMPLIST. Notice
that the arrow operator is not used to move among work areas. In
these situations, it is used only to refer to fields that are not in the cur¬
rent work area.
USING THE VIEW WINDOW WITH RELATIONAL DATABASES 265

If you wanted, you could open different databases in different work


areas in order to make it easy to look at different lists—for example,
when you are working on several. You can then move back and forth
among the work areas and use the database in each one without having
to open it every time. You could still use the arrow operator to access a
database in another work area, even though it is unrelated to the data¬
base in the current work area: you would get the data from the record
where you left the pointer the last time you were working on that data¬
base. (Now you can see why FoxPro often includes the arrow operator
in the field names of the commands it generates. These commands
would be valid regardless of which work area is selected—something
which is particularly convenient if you are reusing an earlier command
after you have selected a new work area.)
You get the most power from the multiple work areas, however,
when you use the View window to set a relation between two data¬
base files, so the pointer in one moves automatically whenever you
move the pointer in the other.
In order to better understand how to set a relation, you should con¬
sider the nature of the one-to-many relationship of the data. Your
EMPLIST.DBF file contains one record for each employee, and
your WAGES.DBF file will contain many records for each
employee—it is obvious that the relation can work only one way. For
instance, you can scroll through the records in the WAGES hie, and
hnd the corresponding data from the EMPLIST hie; as you look at
each week’s wages, you can also look at the name of the person who
has that employee number. But it does not make sense to try to use
the relation the other way around. You cannot scroll through the
EMPLIST hie and also look at the date and wage for each employee,
because there is no single date and wage for each employee. There
are many WAGE records that correspond to one EMPLIST record,
The SET RELA¬ and the pointer in the WAGE hie cannot move to all of them at once.
TION command For this reason, you must be in a work area of the hie that is on the
actually lets you relate
“many” side of the one-to-many relationship when you set the rela¬
files by record number as
well as by key field, but tion and when you use the relational database. The hie on the “one”
this feature is not really side of the one-to-many relationship must be indexed on the key held
useful. To create a genu¬
(in this case, on the employee number held)—FoxPro needs this
ine relational database,
you must set the relation index to look up the name of the person with the same employee
into an indexed key field. number as the current record in the WAGE hie.
266 MASTERING FOXPRO

CH. 7

The file on the many side of the relationship is sometimes called


the controlling file. It must be the current file whenever you work with
fields from the two files. The file on the one side of the relationship
merely fills in the details. Notice, also, that you cannot logically make
an entry in the WAGES file unless there is already an entry with the
same employee number in the EMPLIST file. If you did, you would
be entering wages for someone who is not an employee. This is
always true of a database with a one-to-many relationship: you can¬
not logically enter a record in the file on the “many’ ’ side of the rela¬
tion unless there is already a record with the same key field in the file
on the “one” side.
This should become clear in the exercise. First you will simply set
the relation and see how the pointers move in both files. Bear in mind
that although the key fields in the example will have the same name
in the two files when you set the relation, they do not need to. You
can specify any field in the “many’ ’ file and the relation is set into the
field that the “one” file is indexed on.
In this example, just
the total wage is
1. First you must create the WAGES file. Select New from the
recorded. In a real appli¬
cation, of course, you File menu and select the Database radio button; then select
would probably want to OK. When the Structure dialog box appears, create a data¬
keep more data in the base with the fields shown in Figure 7.2. Select OK. In the
wages hie—for example,
the number of hours
Name the New Database dialog box, type WAGES and
worked. This example is select Save.
simplified to save you
time in data entry and to 2. FoxPro asks if you want to enter records now. Select Yes and
let you concentrate on the
main issue: relating the enter the following sample records, whose use will become clear
two hies. to you in a moment: When the Wages window appears, enter
as the first Empno A01, as the Date, 08/06/90, and as the
Wage, 720.00. As the second record, enter Empno A01, Date,
08/13/90, Wage, 740.00. As the third record, enter Empno
A02, Date 08/06/90, Wage 530. As the fourth record, enter
Empno A02, Date 08/13/90, Wage 590.00. That’s two weeks of
wages for two employees, as shown in Figure 7.3. Close the
Wages Browse window, saving the data.

3. Now, since the View window includes the entire Setup dialog
box, you can use it to modify the structure of the EMPLIST
database to add an employee number. Select View from the
USING THE VIE W WINDOW WITH RELATIONAL DATABASES 267

System File Edit' Structure

Structure: Untitled
Name Type Width Dec
Field
± EMPNO Character 3
X DATE Date 8 < Insert>
X WAGE Numeric 7 2
<Delete>

« OK »

<Cancel>

Fields: 3 Length: 19 Available: 3981

Figure 7.2: The structure of the WAGES file.

System File Edit Database Record Program Window Drowse


WAGES =
Empno A01
Date 08/06/90
Wage 720.00

Empno A01
Date 08/13/90
Wage 740.00

Empno A02
Date 08/06/90
Wage 530.00

Empno Hjj
Date H
Wage
▼ Command

CREATE Untitled

Figure 7.3: Data entered in the WAGES file.


Window menu to call up the View window. Note that the
WAGES file that you have created is already active in Work
Area A, and the other work areas are free. Move the high¬
light to Work Area B and press Enter to select it. The com¬
mand SELECT B is generated in the Command window
and the Select dialog box automatically appears. Select
268 MASTERING FOXPRO

CH. 7

EMPLIST.DBF to open it in Work Area B, generating the


command

USE C:\LEARNFOX\EMPLIST.DBF

Remember that 4. To modify the structure of EMPLIST, select the Setup text
there are two Modi¬ button from the View window. From the Setup dialog box,
fy text buttons in the
select the Modify text button. When the Structure dialog box
Setup dialog box. You
need to use the one next appears, move the highlight to the FNAME field; then select
to the word Structure, not the Insert text button or select Insert Field from the Structure
the one under the word
menu to add a new field. Change the name of the field that is
Index.
added from NEWFIELD to EMPNO, keep its type as Charac¬
ter, and change its width from 10 to 3. The structure should
look like Figure 7.4. Then Select OK and, to make the structure
change permanent, select Yes. When you return to the Setup
dialog box, the new field is added at the beginning of the scrolla¬
ble list of field names. Select OK.

System File Edit Structure


View
Work Areas < Relations >
r
Structure: C:\LEARNF0X\EMPLIST.DBF
Name Type Width Dec
Field
t EMPNO Character 3
X FNAME Character 15 <Insert>
< Setup * LNAME Character 20
X ADDRESS Character 25 <Delete>
X APT NO Character 5
X CITY Character 20
X STATE Character 2
X ZIP Character 5 « OK »
X DATE HIRED Date 8
X WAGE Numeric 5 2 (Cancel>

Fields: 12 Length: 127 Available: 3873

L
USE C:\LEARNF0X\EMPL

Figure 7.4: The modified structure of EMPLIST.

5. Now, you need to add employee numbers to EMPLIST;


and, since this is the file on the “one” end of the one-to-
many relationship, the employee numbers must be unique
and the file must be indexed on employee number. Select the
USING THE VIEW WINDOW WITH RELATIONAL DATABASES 269

Browse text button of the View window (or select Browse


from the Database menu), and simply add the numbers from
A01 to All, as shown in Figure 7.5. Then close the Browse
window, saving the changes, to return to the View window.

System File Edit Database Record Program Window Browse


EMPLIST
Empno Fname Lname Address

A01 Audrey Levy 318 B. 31 St.


A02 JACK LOVE 3642 TANACH WA
A03 EDNA CHANG 2701 ADDISON W
A04 CHARLOTTE SAGORIN 2203 SHADY LAN
A05 WILLIAM JOHNSON 523 EAST 21 ST
A06 WILLIAM B. JOHNSON 1701 ALBEMARLE
A07 NANCY NIXON 1124 GRANT AVE
A08 JAMES SKINNER 1206 FRANCISCO
A09 MICHELLE PERLOW 224-1423 RESEA
A1 0 JOSEPH CRUZ 1450 VALENCIA
■AH HENRIETTA JOHNSON 2204 GRAND CON

1 a t Command

SELECT B
USE C:\LEARNFOX\EMPLIST.
BROWSE LAST

Figure 7.5: EMPLIST with employee numbers added.

6. To index this file, select the Setup text button. Select the Add
text button in the Index box. When the Open Index File dialog
box appears, select the New text button. When the Index On
dialog box appears, select EMPNO from the scrollable list of
field names and then select OK. When the Index File Name
dialog box appears, type the name EMPNOS and select OK.
When you return to the Setup dialog box, notice that the new
EMPNOS index is active as the main index that sets the order
of the records—exacdy what you need. Select OK.
270 MASTERING FOXPRO

CH. 7

7. Now you are ready to set the relation. Remember that you
must be in the work area of the file on the “many” side of the
relationship and set the relation into the file on the “one’ ’ side of
the relationship, since FoxPro needs to look into the EMPLIST
file to find one record that matches each record in the WAGES
file. Move the View window’s highlight to WAGES and press
Enter to generate the command SELECT A. If FoxPro also
opens a Browse window and generates the command BROWSE
LAST, close the Browse window to return to the View window.
Then select the Relations text button. Notice that WAGES, the
name of the current file, appears in the Relations window, with
an arrow pointing to the space under it for the file that the rela¬
tion is set into.
8. Move the highlight to EMPLIST and press Enter to select it as
the file that the relation is set into. The expression builder
appears to let you choose the expression in WAGES that corres¬
ponds to the indexed expression in EMPLIST. Notice that you
can use any expression from the file on the “many” side of the
relationship, but that you must relate it to the indexed expres¬
sion in the file on the “one” side of the relationship. Type
EMPNO in the text box and then select OK. Now that the rela¬
tion is set, EMPLIST appears under WAGES, with the arrow
pointing into it, as in Figure 7.6. The command SET RELA¬
TION TO EMPNO INTO EMPLIST is generated.

Now that the relation is set, you can browse both files and see that
when you move the pointer in the WAGES file, FoxPro automati¬
cally moves the pointer to the corresponding record in the EMPLIST
file. This exercise will help you understand how the relation affects
the pointers in the two files. (In a later exercise, you will set up the
relational database in more practical ways, for example by including
fields from the two files in the same Browse window.)

1. Select the Browse text button to browse the WAGES file


(which is in the current work area). Move up to the first
record, which has an EMPNO of A01. Now, select View
from the Window menu to bring the View window to the
USING THE VIEW WINDOW WITH RELATIONAL DATABASES 271

System File Edit Database Record Program Win


1 View
►< View > Work Areas < Relations >

<On/Off> □EHsISHK ►WAGES


• emplist^T 1—^EMPLIST
<Files > -c -

-D-
< Misc > -E-
-F-
<Setup > -G-
-H-
<Browse> -I-

<
\ On p n
kj yj ^ i i >/

<Close > WAGES Records: 4

Figure 7.6: The relation of WAGES set into EMPLIST, shown in the View
window.

front. Move the cursor to EMPLIST and press Enter to gen¬


erate the command SELECT B. If FoxPro does not automati¬
cally open a Browse window, select the Browse text button.
Note that the pointer is also in the record in this file that has
the Empno of A01.

2. Remember that any open window is added at the end of the


Window menu popup, with a number before it to let you use
that window quickly. Select 0 WAGES from the Window
menu to bring the WAGES Browse window to the front
again. Move the cursor down to the fourth record, which has
the employee number A02. Then select 1 EMPLIST from
the Window menu to bring the EMPLIST Browse window
to the front again. Note that the pointer has automatically
moved to the second record, which has the EMPNO of A02,
corresponding to the EMPNO of the record where the cursor
was moved in the WAGES file.
3. Now test the fact that the relation works only one way. Move
the pointer back up to the first record of the EMPLIST
Browse window, which has the Empno of A01. Then select
0 WAGES from the Window menu to move back to the
272 MASTERING FOXPRO

CH. 7

WAGES Browse window. The pointer is still where you left it,
on the fourth record, which has the Empno of A02. Select 1
EMPLIST from the Window menu to return to the EMPLIST
Browse window. The pointer is not where you left it: it moves
back to the second record, so that its Empno corresponds with
the current Empno in the WAGES file. Now close both Browse
windows to return to the View window.

Of course, it would take too much time to set the relation each time
you wanted to use this relational database. In the next section, you
will save and reuse the view, after you see how to make use of the
related files.

USING A RELA TIONAL DA TABASE


Now that you have set the relation and seen how moving the
pointer in the WAGES file (on the “many’ ’ side of the relation) auto¬
matically moves the pointer to the corresponding record in the
EMPLIST file (on the “one” side of the relation), you can begin to
make use of this relational database. First, you will create a Browse
window of the sort that you could use for entering and viewing data.
Then you will use a command with a Fields check box to include
fields from both files. Finally, you will take a look at reports and labels
for relational databases.

BRO WSING RELA TED FILES


As you remember, many FoxPro commands can be used with field
lists. Once a relation is set up, you can use these commands with a list
that includes fields from both files. You just need to use the arrow
operator to refer to fields in the file not in the current work area.
Remember what you learned in the last section, when you were
browsing through the two files: you should always arrange to have
the file for the “many” side of the relation in the current work area.
This is so that FoxPro can automatically move the pointer in the file
that the relation is set into, finding the one record there that corre¬
sponds to the record in the current file.
One particularly interesting command to use with relational data¬
bases is BROWSE FIELDS Kfield list^>, since the Browse window you
USING THE VIEW WINDOW WITH RELATIONAL DATABASES 273

set up is saved and reused automatically each time you select Browse
from the Database menu, generating the command BROWSE
LAST. If you use BROWSE FIELDS <Lfield list> once to create the
Browse window, the Browse window will be displayed in the same
way whenever you select Browse from the Database menu.
The key field from As an exercise, try creating a Browse window that includes all the
the file on the
“one” side of any one-to-
fields of the WAGES file, and the Empno and name fields of
many relation must be the EMPLIST file, to see how easy this makes data entry. Having the
protected from being Empno fields from both files will let you see clearly that the fields added
changed accidentally,
to the Browse window from the EMPLIST file correspond to the cur¬
otherwise it can cause
irrecoverable loss of data. rent record in the WAGES file. It will also show you an important pitfall
The Empno field from that you must avoid when you are working with relational databases.
the EMPLIST file is
Before you begin, make sure that you closed both Browse windows
included in the Browse
window in this exercise at the end of the last exercise, and that the work area of the WAGE
only for instructional file is the current work area.
purposes.

1. Select Command from the Window menu to bring the Com¬


mand window to the front. Enter
BROWSE FIELDS EMPNO, DATE, WAGE, EMPLIST - >
EMPNO, EMPLIST->LNAME, EMPLIST->FNAME
all on one line to get the Browse window shown in Figure 7.7.
Notice that each record you entered in the WAGE file has the
corresponding employee number, last name, and first name
from the EMPLIST file displayed next to it.

2. Add a new record: Select Append Record from the Browse


menu. In the first Empno field (which you may remember is
the Empno of the HOURS file), type A03. The corresponding
EMPLIST fields Empno, Lname, and Fname are instantly
filled in, as shown in Figure 7.8. To finish filling in the record,
type 08/06/90 and type 498.00.

3. For comparison, see what happens if there is no correspond¬


ing record in the EMPLIST. Select Append Record from the
Browse menu. Type A23 in the Empno field. The fact that no
corresponding empno, lname, and fname appear lets you
know that you have made an error in data entry: you have
begun to enter wages for a worker who does not exist in your
list of employees. Correct the error by editing A23 so it is A03
274 MASTERING FOXPRO

CH. 7

Figure 7. 7: Browsing fields from two related database files.

Figure 7.8: Fields that correspond to the Empno you enter are automatically
filled in.
USING THE VIEW WINDOW WITH RELATIONAL DATABASES 275

instead. The empno and name appear. As the date, enter


08/13/90, and as the wage, enter 480.00.

4. Now, imagine that you make a very dangerous error. Move


the cursor to the next field in the same record, the Empno
field that comes from the EMPLIST file. Change this num¬
ber from A03 to A04. Instantly, this empno and the lname
and fname disappear from this record. Move up to the pre¬
vious record, and they disappear there too, as shown in Fig¬
ure 7.9. You have just edited the EMPLIST file by mistake,
so that there is no longer a record there with the empno of
A03: fields disappeared from two records in the Browse win¬
dow because there is no longer a record in the EMPLIST file
that corresponds to these records of the HOURS file.

System File Edit Database Record Program Window Browse


1 .WAGES -UKM
1 Empno Date Wage Empno Lname Fname

1 A01 08/06/90 720.00 A01 Levy Audrey


1 A01 08/13/90 740.00 A01 Levy Audrey
I A02 08/06/90 530.00 A02 LOVE JACK
| A02 08/13/90 590-00 A02 LOVE JACK
|A 03
A03
08/06/90
08/13/90
498.00
480.00
r

. ■
!
j
▼ Command
_|LAST
SELECT B
BROWSE LAST
BROWSE FIELDS EMPNO, DAT

Figure 7.9: The data vanishes.

5. To fix this mistake, select View from the Window menu. In the
View window, move the cursor to the work area with
EMPLIST in it and press Enter, to generate the command
SELECT B. If FoxPro does not automatically open a Browse
window, select the Browse text button. In the new Browse win¬
dow, you can see that two records have the empno of A04.
276 MASTERING FOXPRO

CH. 7

Hopefully, you remember that Edna Chang is the one that used
to be AOS, since it is no longer in its proper order. Edit the file so
Edna Chang again has number A03 and close this EMPLIST
Browse window, saving the change. Close the View window to
see your WAGES Browse window again. The empno, lname,
and fname reappear in the records where they were missing.

6. Now that you have seen what can go wrong, you will save
this view and then reuse it as an exercise. First, save the view:
Select View from the Window menu to open the View win¬
dow again. Then select Save As from the File menu, and
FoxPro displays the Save View As dialog box, shown in Fig¬
ure 7.10. Type the name WAGEENTR and select Save, gen¬
erating the command

CREATE VIEW C:\LEARNFOX\WAGEENTR.VUE

Figure 7.10: The Save View As dialog box.

7. Now, watch how easy it is to use this view at any time in the
future, even after you have quit FoxPro. Select Quit from
the File menu to end this session; then, at the DOS prompt,
enter FOXPRO to start FoxPro again. (If you want, enter
CLEAR to clear the screen, or start the program using
FOXPRO -T).
USING THE VIEW WINDOW WITH RELATIONAL DATABASES 277

8. Select Open from the File menu. From the Open dialog box,
select the Type popup control. Select View as the type, as in
Figure 7.11. Notice that FoxPro gives you the choices of the
environments that you saved when you created reports and
labels as well as the .VUE file you just created, as illustrated
in Figure 7.12. Select WAGEENTR.VUE from the scroll¬
able list and note that FoxPro generates the command SET
VIEW TO WAGEENTR.VUE. Now, select Browse from the
Database menu, and the Browse window that you set up to
display fields from the two files reappears. Close the Browse
window.

System File Edit Database Record Program Window

Open :

► [..] Drive C

TESTCOPY.DBF
WAGES.DBF
Directory LEARNFOX

« Open »

5 < New

Database
Program I Type < Cancel

L
File
Index
Report
-T-

Figure 7.11: Using the Type popup to open a View file.

You can see that it is almost as easy to open a view-—with up to ten


files, the relations among them, and other environment settings—as
it is to open a single database file. You can imagine how much of a
convenience this is if you have to switch between ten different views
of your data in the course of the day, or if you are writing a program
that constantly switches from one view to another.

USING THE FIELDS CHECK BOX


If a dialog box has a Fields check box you can use it to choose the
fields from the file that the relation is set into, in the same way that
278 MASTERING FOXPRO

CH. 7

Figure 7.12: The list of View files includes environments for reports and
labels.

you used a fields list when you were working from the Command
window. Unfortunately, the Set Fields check box of the Setup win¬
dow cannot be used in this way; it can only exclude fields from the
current file and cannot include fields from related files. Later versions
of FoxPro are expected to let you use this check box to select fields
from multiple files of relational databases. Then you could just SET
FIELDS once and not have to worry about it again. In the meantime,
try using the Fields check box of the Copy To dialog box:

1. Select Copy To from the Database menu popup. When the


Copy To dialog box appears, select the Fields check box. When
the field picker appears, use the Database popup control to
select EMPLIST, as in Figure 7.13; then select LNAME and
FNAME from the Database Fields scrollable list and move
them into the Selected Fields box on the right (using the Move
text button for each field). Then use the Database popup con¬
trol to select WAGES, and select DATE and WAGE from the
Database Fields scrollable list. The field picker should now look
like Figure 7.14. Select OK.
USING THE VIEW WINDOW WITH RELATIONAL DATABASES 279

System File Edit Database Record Program Window

Database Fields: Selected Fields:

EMPNO C 5 0 < Move >


DATE D 8 0
WAGE N 7 2 < 011 •» >

< Remove >

< Clear >

Database:

WAGES
EMPL1ST I <@ancel

«
>

Figure 7.13: Using the Database popup control to work with related database
files.

System File Edit Database Record Program Window

Database Fields: Selected Fields:

EMPNO C 3 0 < Move -> > EMPLIST-


EMPLIST->LNAME
>LNAME
DATE D 8 0 EMPLIST->FNAME
WAGE N 7 2 < 011 -> > WAGES-
WAGES->DATE
>DATE
WAGES->WAGE

< Remove >

< Cflear >

Database:
-—-- <@ancel >
WAGES
« g)K »

L i

Figure 7.14: The field picker with fields from two related database files.

2. You have returned to the Copy To dialog box, and you are
ready to copy the selected fields to a new file. In the Save As
text box, type TESTCOPY, and then select OK.
280 MASTERING FOXPRO

CH. 7

3. To see the result, select View from the Window menu to re¬
open the View window. Move the highlight to Work Area C
and press Enter to generate the command SELECT C. If the
Select Database dialog box does not appear automatically,
select the Open text button of the View window. Select
TESTCOPY.DBF from the scrollable list of file names and
then select the Open text button. If necessary, select the
Browse text button of the View window to browse this file to
see the TESTCOPY file. You will find that it has the fields
from both the EMPLIST and WAGES files, as shown in
Figure 7.15.

System File Edit Database Record Program Window Drowse ;V. '• . '
1 TESTCOPY
I name Fname Date Wage

I
lAudrey 1 720.00
Levy Audrey 08/13/90 740.00
LOVE JACK 08/06/90 530.00
LOVE JACK 08/13/90 590.00
CHANG EDNA 08/06/90 498.00
CHANG EDNA 08/13/90 480.00

S3 TESTCOPY FIELDS
SELECT C
USE C:\LEARNFOX\TESTCOPY
BROWSE LAST

Figure 7.15: Fields from related files copied into a single file.

REPORTS USING RELA TIONAL DA TARASES


You can use data from related files just as easily when you are cre¬
ating reports. You can use the Database popup of the expression
builder to access fields from different database files, much as you did
in the previous section.

1. Move the highlight in the View window back to WAGES


and press Enter. Remember, you are creating a report on the
USING THE VIEW WINDOW WITH RELATIONAL DATABASES 281

controlling file, the file which is on the “many” side of the rela¬
tionship. This file must be in the current work area when you
use the report, as when you use any command with a rela¬
tional database.

2. Select New from the File menu. Select the Report text button
and then select OK to call up the report layout window. Press
the down arrow key four times to move the cursor to the
detail band.

3. Select Field from the Report menu to call up the Report


Expression dialog box. Select the Expr text button to call up
the expression builder. Select the Database popup, which lets
you select fields from any database, just as you did when you
were using the Copy To dialog box above.

4. Select EMPLIST from this popup. Select LNAME from the


scrollable list of field names. Select OK to return to the Report
Expression dialog box, where this field name, complete with the
file name and arrow operator, now appears in the text box to
the right of the Expr text button, as shown in Figure 7.16. Of
course, you could have typed it here if you wanted.

5. Select OK to place this field in the report. In an actual appli¬


cation, of course, you would place other fields from both
related files in the layout window. Since you have learned
what you need from this exercise, though, you should just
close the report layout window. When FoxPro asks, type N to
discard the changes. You should also close any Browse win¬
You can create
dows that are open and return to the View window.
labels using related
files by selecting Expres¬ It is easy to create reports or labels that use related files, but this
sion from the Label menu
popup and using the
exercise does point out one possible pitfall. When you used the Data¬
expression builder or by base popup, TESTCOPY.DBF was on it, because it was open in
simply typing field names Work Area C, even though it is not related to the other two files and
that include the arrow
has nothing to do with this report. Sometimes this popup makes
operator into the label
form. It is unlikely, how¬ things look a bit too easy; the fact that a database file is on it does not
ever, that you will have mean that this file is properly related to the other files. You must have
the name and address
a firm grasp of which files you are using and must set the relation
data that is needed for
most labels in more than between them before you create a report or work with any command
one file. that uses fields from multiple files.
282 MASTERING FOXPRO

CH. 7

Figure 7.16: Adding fields from related files to a report.

WARNING
\

The most important thing you should have learned from all these
exercises is how much damage you can do by modifying the indexed
key field of the database that the relation is set into. If you do this by
mistake, you could end up with a list of wages and employee num¬
bers without having any way of finding out which employee has a
given employee number. Or you could end up with lists of customer
numbers, sale dates, and amounts of money owed to you without
having any way of finding out the names, addresses, or phone num¬
bers of the customers you have to bill.
Never include a key field of this sort in the Browse window in the
way that we did in the exercise. That example was meant to teach you
graphically about a danger you need to avoid. Do not even include this
sort of key field in the Browse window that you use to update the file
itself; instead, use a Browse window with all the other fields. This way,
you can change the name and address but you cannot change the
employee number or customer number even by mistake. Moreover,
do not delete records in this file unless you are archiving all of your old
data and beginning a new cycle of data entry. If you do delete a record
in this file, you will not be able to use the corresponding records in the
USING THE VIEW WINDOW WITH RELATIONAL DATABASES 283

related file. Finally, always keep your database files backed up, in case
the mistake does occur despite your precautions.
In fact, because of this danger, the best way to use a relational
database is by writing a program that adds the key field automatically
and never lets the user change them. It is better yet if the user never
even sees them.

USING ENVIRONMENT SETTINGS __


The View panel that you just used to set a relation is the most com¬
plex and powerful panel of the View window, since setting relations
requires using multiple databases at once, creating or opening the
proper index, and so on.
The View window also has three other panels that let you make
simpler environment settings: the On/Off, Files, and Misc panels.
The text buttons in the upper left of the View window let you access
its four panels. When you use the View panel, there are also four text
buttons in the lower left, which let you do things you might need to do
while working with relational databases: Setup, Browse, Open, and
Close. When you work with any of the other three panels, the lower
left is empty: because they are simpler, there is no need for these
extra features.

THE ON/OFF PANEL


Selecting the On/Off text button lets you use the On/Off panel of the
View window, shown in Figure 7.17 with its default settings. You can
see from the help line at the bottom of the panel that it gives you access to
features equivalent to commands which use SET with ON or OFF.
For example, you learned in Chapter 5 that you can deal with
deleted records by using the commands SET DELETED ON and
SET DELETED OFF. Selecting the Deleted check box in this panel is
equivalent to using these commands. As you see, the check box
is blank by default. You should remember that the default setting of
the Deleted feature is off: the feature does not ordinarily screen out
records marked for deletion. By selecting the check box, you set it on:
the feature does screen out records marked for deletion.
284 MASTERING FOXPRO

CH. 7

System File Edit Database Record Program Window


I V i ew
< View > [ J ALTERNATE [X FULLPATH
IMHMllftMWJ*—■ [ x HEADINGS
►<0n/0ff> [XJ BELL [X' HELP
CARRY [X' INTENSITY
<Files > X] CLEAR NEAR
COMPATIBLE PRINTER
< Misc > CONFIRM [X' RESOURCE
X] DEBUG [X' SAFETY
DELETED SHADOWS
X] DEVELOPMENT [X' SPACE
ECHO [X' STICKY
X] ESCAPE [X' TALK
EXACT [ UNIQUE

SET .., [ ON I OFF ]

Figure 7.17: The On/Off panel of the View window with default settings.

Deleted is one of the very few default environment settings that


you would want to change as a user. You have already looked at a
couple of others in earlier chapters.
Remember that if you set Near on, a SEEK command that cannot
find a match positions the pointer at the record nearest to the value
you were searching for, so that you can browse around and look for
the record you want. You can see from the illustration that Near is off
by default. You might want to select this check box when you are
doing searches where you might not be sure of an exact spelling or
number.
Likewise, you can see from the illustration that Exact is off. With ear¬
lier (1BASE compatible programs, it was common at times to set Exact
on to find only exact matches of character strings that you were search¬
ing for, leaving out words or names that began with the string you were
searching for but which had more letters after it. You will still run across
this command, though it is not as useful now that the = = operator has
been added in FoxPro.
You might also want to set Printer on sometimes, in order to print
whatever scrolls by on the screen (where the talk is). Alternate, which
saves to a text file everything that scrolls by on the screen, is also useful,
USING THE VIEW WINDOW WITH RELATIONAL DATABASES 285

but it must be used in combination with SET ALTERNATE TO (cov¬


ered in the next section), which specifies the name of the text file; Alter¬
nate is therefore dimmed until you have used SET ALTERNATE TO.
Other settings in this panel are useful mainly in programming.
Setting Bell off stops FoxPro from sounding a beep when you reach
the end of a field and automatically move to the next one. You may
be tempted to set Bell off primarily because the beep can be annoy¬
ing, but you will find if you do that the data you are entering in one
field sometimes runs into the next field without your realizing it. Set¬
ting Bell off is really useful, however, in programs where you have
built in some other way of controlling this problem. Likewise, setting
Talk off can be useful when you are programming applications
wherein you don’t want to confuse the user with the FoxPro talk; but
there is no reason to set the talk off when you are using FoxPro itself.
Some commands are dangerous. Setting Safety off, in particular,
lets FoxPro destroy data without warning you.
These are some of the most important and interesting On/Off com¬
mands. Some others are listed in Appendix C, and a comprehensive list¬
ing is provided under SET in your Commands and Functions reference.

THE FILES PANEL


Selecting the Files text button lets you use the Files panel of the
View window, as shown in Figure 7.18. This panel controls environ¬
ment settings that have to do with files. All of its features are equiva¬
lent to SET ... TO commands.

H In the actual com¬


mand, the letter
• Default Drive: lets you use a popup to choose the default
drive used for all file input and output. For example, to use
designating the drive
data that is on a floppy disk in your A: drive, just select A as
must be followed by a
colon—for example, A:— the default drive. This feature is equivalent to the command
despite the fact that the
colon is not included in
SET DEFAULT TO Kletter of drive >
the popup control. • Path: lets you specify a path for FoxPro to search when the
file is not found in the directory. Selecting this check box calls
up a dialog box that lets you enter the drive and directory for
FoxPro to search in. You can eliminate this search path by
286 MASTERING FOXPRO

CH: 7

Figure 7.18: The Files panel of the View window.

selecting the Clear Path text button. This feature is equiva¬


lent to the command
*

SET PATH TO <listof paths>


• Alternate: lets you specify the name of a text file where screen
output will be saved. Selecting this check box displays the
Open dialog box, where you can select an existing file or
enter the name of a new file. This feature is equivalent to

SET ALTERNATE TO <file name>


Remember that it has to be used in combination with the
command SET ALTERNATE ON, or its equivalent, which
you can access from the On/Off panel; using SET ALTER¬
NATE ON or OFF allows you to use or disable the storage of
screen output temporarily. Select the Clear Alternate text
button to eliminate it entirely.

• Procedure: is used in programming to specify a procedure file


for FoxPro to use while executing a program. It is equivalent
to the command SET PROCEDURE TO <file name>, which
will be covered in Chapters 11 and 12. The use of the proce¬
dure file can be ended by selecting Clear Procedure.
USING THE VIEW WINDOW WITH RELATIONAL DATABASES 287

• Help: lets you specify which file is to be used when the user
selects Help from the System menu (or presses FI). You can
create your own help files if you are creating an application
where the user does not need and would only be confused by
all the information in FOXHELP.DBF, the help file that
comes with FoxPro—which, as you can see, is the default
help file. This feature is equivalent to the command

SET HELP TO <file name>


You can also set Help on or off using the On/Off panel; the
default setting for Help is on.

• Set Resource To: lets you specify the resource file that FoxPro
uses. The resource file stores information about the location
and size of your Browse windows, color selections, and other
preferences. By default, FoxPro automatically creates a
resource file named FOXUSER.DBF if, for example, you
change your Browse window; then it uses this file to set up
the Browse window when you use the command BROWSE
LAST in a later session. You can create a variety of resource
files with different names and use them for different pur¬
poses. You can also set Resource on or off using the On/Off
panel; the default, of course, is on.

THE MISC PANEL


Selecting the Misc text button lets you use the Misc panel of the
View window, as shown in Figure 7.19. This panel controls a num¬
ber of miscellaneous environment settings. Its features are listed
below:

• Date: lets you choose among date formats. The default is


AMERICAN (mm/dd/yy). Other date format options are
ANSI (yy.mm.dd), BRITISH or FRENCH (dd/mm/yy),
GERMAN (dd.mm.yy), ITALIAN (dd-mm-yy), and
JAPAN (yy/dd/dd); also USA (mm-dd-yy), MDY (mm/dd/
yy), DMY (dd/mm/yy); and YMD (yy/mm/dd). Any of
these can be used with the command SET DATE TO plus one
of the capitalized format names listed above. Other features of
288 MASTERING FOXPRO

CH. 7

Figure 7.19: The Misc panel of the View window.

the date format are controlled by the check boxes to the right
of this popup.
• Century: lets you display the entire four-digit year, not just
the last two digits. The equivalent command is SET CEN¬
TURY ON or OFF.

• Date Delimiter: lets you change the delimiter used between


the numbers for the year, month, and day. Check the check
box and type the delimiter you want in the sample date dis¬
played below it.

• Currency: lets you specify the way that currency is displayed.


The default is with two decimal places, a dollar sign, a
comma to mark thousands (and millions and so on), a deci¬
mal point to mark cents, and left-alignment on. Edit any of
these specifications and use the Left check box to set left-
alignment on or off.

• Clock: lets you use and adjust the system clock. When the
check box is checked, the system time is displayed on
the screen. The command equivalent is SET CLOCK ON.
The popup lets you display the time in 12- or 24-hour format.
USING THE VIE W WINDOW WITH RELATIONAL DATABASES 289

Edit the Row and Column items to determine where on the


screen the time is to be displayed—or use the command

SET CLOCK TO <row, col>


• Bell: lets you adjust FoxPro’s beep. Enter a frequency from
19 to 10000 to change its pitch and a length from 1 to 19 to
determine how long it lasts. The equivalent command is

SET BELL TO Kfrequency, duration>


Remember that there is also a command SET BELL ON or
OFF, which you can access through the On/Off panel.
• Talk: is used to determine how frequendy certain commands
display information about their status-—for example, the
INDEX command, which displays talk telling you how many
records have been indexed as it executes. As you can see (in
Figure 7.19), the default is 100, but you can enter a number
from 1 to 32,767. This feature is equivalent to the unfortu¬
nate command

SET ODOMETER TO <number>


inherited from earlier versions of dBASE. It is used in combi¬
nation with the Talk check box. Setting Talk off eliminates
these status messages entirely.

• Typeahead: lets you determine how many characters FoxPro


holds in its keyboard buffer. The buffer is a small area of mem¬

B If you are a fast


typist and have a
ory reserved to hold keystrokes until FoxPro is able to display
them; it can hold up to 128 keystrokes. You can use the buffer,
slow computer (such as
for example, when you first start FoxPro, since it takes a while
an XT compatible), SET for the program to display the screen: If your buffer is large
TYPEAHEAD is one of enough, you can type USE EMPLIST, press Enter, type
the most useful of these
BROWSE LAST, and press Enter, all while you are waiting;
environment commands.
The default setting does when the screen finally appears, these commands will be in the
not store enough key¬ Command window and will be executed.
strokes in the buffer, but
increasing it will let you • Mouse Tracking: lets you determine how sensitive your
type more while you are pointer is to the movement of your mouse. The sensitivity
waiting for FoxPro to do
ranges from 1 to 10, with 1 being the least sensitive.
other things.
290 MASTERING FOXPRO

CH. 7

Remember that all the environment settings from all these panels
are saved when you save the view in a .VUE file. They will all be in
effect again whenever you open that .VUE file.
Getting the Most
from the Menu System
To create a keyboard macro, 297
press Shift-F 10 at any time. Then enter the keystroke combina¬
tion that you want to use to activate the macro. Press Shift-FlO
again to stop recording the macro.

To save a set of macros, 303


select Save from the Keyboard Macros dialog box or Macro
from the Macros menu popup. The Save As dialog box ap¬
pears, allowing you to give a name to all the current macros.

To use a set of macros that has been saved, 304


select Restore from the Keyboard Macros dialog box. The
Open dialog box appears, with a scrollable list of macro set
names. Select one and then select Open to use those macros.
%

To make the current set of macros the default set, 304


select the Set Default text button from the Keyboard Macros
dialog box or select Set Default from the Macro menu popup.
The current macros will then be available whenever you start
FoxPro.

To search for text in a document, 309


select Find from the Edit menu to call up the Find dialog box.
Type the text you are searching for in the Look For text box; if
you want to replace it with other text, type that text in the
Replace With text box. From the Edit menu, select Find Again
to repeat the same search, Replace And Find Again to replace
the text and repeat the search, or Replace All to replace every
occurrence of the text.
To add records from another file to the current database file, 314
select Append From from the Database menu. Use the Append
From dialog box to specify the name and type of the hie you are
appending from and, if you want, to add a Scope, For, While,
or Fields clause.

To total numeric fields in a database, 316


select Total from the Database menu to call up the Total On
dialog box. Enter the held or expression to total on and the
name of the hie to save the result in.

To store the results of calculations in memory variables, 318


select Average, Count, Sum, or Calculate from the Database
menu.

To replace the current value in a field with a new value, 325


select Replace from the Record menu to call up the Replace
dialog box. Use the scrollable list to select the name of the held
whose value you want changed, and the With text button or the
text box to enter the expression that it should be replaced with.
Use the Scope, For, or While check boxes to change the values
in many records with one command.
296 MASTERING FOXPRO

CH. 8

IN THE FIRST PART OF THIS BOOK, YOU LEARNED ALL


the features of the menu system that are essential to using FoxPro to
manage simple databases. You learned to create and modify the struc¬
ture of a database, to add, view, and edit data, to make queries, and to
produce reports and mailing labels—the basic things you need to know
to manage any simple application. In Chapter 7, you learned to use
the View window: in combination with the commands you learned
in the first section, this gives you all the essential skills you need to
manage more complex applications that require relational databases.
This chapter takes you beyond the essentials and introduces you to
the features of the menu system that give you extra power. It includes
three main sections.
In the first, you learn to use keyboard macros, which you access
through the System menu popup, to save keystrokes. Macros can
make your work with FoxPro easier, by saving you repetitive data
entry. As you become more advanced, you can also use them to auto¬
mate commands and give yourself extra power. (The other features
of the System menu are covered in Appendix B; they are not directly
related to using FoxPro to manage data.)
In the second section, you learn to use more advanced editing and
word-processing techniques. You learn the remaining features of the
File menu, which let you create text and program files and print
them—essentially, using FoxPro as a word processor or programmers’
text editor. And you learn the features of the Edit menu popup which
were not covered in Chapter 1. All these things will be handy if you
write programs or use long memo fields, though they are not needed
for routine data entry and editing.
In the third section, you learn techniques that let you manipulate
data more powerfully. This includes the remaining features of the
Database and Record popups.
Finally, there is a brief fourth section that describes how to change
the colors of your screen—something that is not often needed but is
included in case you have one of the odd color displays that does not
work well with the default colors of FoxPro.
GETTING THE MOST FROM THE MENU SYSTEM 297

KEYBOARD MACROS _
Many programs let you create keyboard macros. A macro simply
records a series of keystrokes and assigns them to some special key or
key combination, so that you can press one key or key combination
each time you need to use the series of keystrokes you have recorded.
Macros are a convenience to save you time in entering keystrokes
that you use frequently. Though you can save any sequence of key¬
strokes in a macro, generally you will use them to save data-entry
time. For example, if you have to enter a large number of records
with addresses in San Francisco, you can create a macro that stores
the keystrokes needed to type SAN FRANCISCO, to move to the
State field, and to type CA. Macros are also useful for customizing
the editor, for example, to make it work like an editor that you are
more familiar with.
FoxPro lets you assign a macro to any of the function keys—the keys
on the left or top of your keyboard, labeled with F and a number—and
to a large number of key combinations that use Ctrl, Alt, or Shift with
function keys or letter keys: remember that only letter keys and func¬
tion keys can be used in macros, not numbers, special characters, or

a FoxPro does let


you use Alt-FlO
editing keys. The permissible combinations of keys are

• any function key except FI and F10


(and Shift-Alt-FlO, Ctrl-
Alt-FlO, and Ctrl-Shift-Alt- • Shift plus any function key except F10
FlO), but only when
followed by a letter. This • Ctrl plus any letter or function key
gives you even more
combinations of key¬ • Shift-Ctrl plus any letter or function key
strokes that can be
assigned macro values.
• Alt plus any single letter or function key except F10
• Shift-Alt plus any single letter or function key except F10

• Ctrl-Alt plus any single letter or function key except F10

• Ctrl-Shift-Alt plus any single letter or function key except F10

This gives you a possible total of 255 different keyboard macros,


probably more than you will ever need—and probably more than
you could ever remember. The maximum number of keystrokes
that you can store in any macro is 1,024—again, probably more than
you will ever need.
298 MASTERING FOXPRO

CH. 8

Default macros The function keys by themselves are assigned default macro values
that you create are
saved in a file named
if you have never created macros for them. FI is help, and because
DEFAULT.FKY in this is very useful, it cannot be assigned another value. The other
either your FoxPro home function keys’ default values are left over from the days when dBASE
directory or in the cur¬
did not have a menu interface; they let you enter the most common
rent directory. Until you
create new defaults, this commands at the command line. These default macros are no longer
file does not exist, and useful now that it is easier to use the menus. As you will see, you can
FoxPro simply generates
save new default values for these function keys so that they will be set
the standard defaults
when the program is automatically whenever you start FoxPro.
started. If default macros Selecting Macros from the System menu calls up the Keyboard
that you have saved are Macros dialog box, shown in Figure 8.1. When this dialog box is dis¬
not available when you
start FoxPro, search for
played, a Macros menu pad is added to the menu bar; the Macros
the DEFAULT.FKY file. popup is shown in Figure 8.2. As you can see, the menu popup sim¬
ply duplicates the choices that you can make by using the text buttons
of the dialog box—the menu is added so that you can use the Control-
key combinations as an alternate way of making these choices, if you
find it more convenient.

CREATING AND USING A NEW MACRO


You can create a new macro either by selecting the New text but¬
ton of the Keyboard Macros dialog box or by selecting New Macro
from the Macros menu popup. In addition, you can create a new
macro at any time by pressing Shift-FlO (which is why Shift-FlO is
one of the combinations that you cannot assign your own macro to).
Though it is not necessary, it generally makes it easier to under¬
stand what you are doing if you create the macro at the same point in
FoxPro where you will use it. For example, to create a macro that fills
in a city and state name, first open the Browse window and move the
cursor to the City field. Then select New Macro from the Macro
menu or press Shift-FlO to create the macro. Of course, you will
often realize that it is handy to create a macro when you are already
in the situation where it is used.
When you make any of these choices, FoxPro displays the Macro
Key Definition dialog box, shown in Figure 8.3. Enter the key com¬
bination that you want to use to activate the macro—for example,
press F2 or press Ctrl-Alt-A. FoxPro will not let you enter illegal
combinations. If you enter a keystroke combination that you have
GETTING THE MOST FROM THE MENU SYSTEM 299

System File Etlit. Macros

Keyboard Macros

< Save >

< Restore >

<Set Default>

Figure 8.1: The Keyboard Macros dialog box.

Macros

jlear
Clear 011
Save Macros
Restore Macros acros
Set jjefault

Figure 8.2: The Macros menu popup.

already defined as a macro, it will display the Overwrite dialog box,


shown in figure 8.4, which gives you the following choices:

• Overwrite: Replace the existing macro with the new macro


that you are defining.
300 MASTERING FOXPRO

CH. 8

System File Edit Database Record Program Window

Macro Key Definition

Defined Key: l(press the key)

Macro Name:

« OK » < Cancel >

Figure 8.3: The Macro Key Definition dialog box.

System File Edit Database Record Program Window

Key ALT+J is already assigned


as Macro ALT J.

« Overwrite » Qppend keystrokes > < gjancel >

Figure 8.4: The Overwrite dialog box.


GETTING THE MOST FROM THE MENU SYSTEM 301

• Append Keystrokes: Add the new keystrokes at the end of the


existing macro.

• Cancel: Do not replace the existing macro.

Once you come up with an acceptable key combination, it appears


in the Macro Key definition dialog box, along with a suggested name
for the macro (based on the key combination), as you can see in Fig¬
ure 8.3. You can change this name if you wish and enter any name
up to 20 characters long. When the keystrokes and name are right,
choose OK to begin creating the macro.
Then enter any combination of keystrokes that you want saved in
the macro. These might be just text—for example, type SAN FRAN¬
CISCO, press Tab, and type CA to save yourself time entering that
city and state in each record in a database file.
The keystrokes might involve commands—including editor com¬
mands or even the keystroke versions of menu choices. If you are
accustomed to an editor that lets you delete a line by pressing Ctrl-Y,
for example, you can create a Ctrl-Y macro that does just that.
When you are finished entering the keystrokes you want recorded,
press Shift-F 10 to stop recording. The Stop Recording dialog box
appears, as shown in Figure 8.5. The choices that this dialog box gives
you are easy to understand:

• Insert Literal: Record the literal value of the next keystroke


instead of the value assigned to it by an existing macro.

• Insert Pause: Stop execution of the macro temporarily and let


the user type in text.

• OK: Save the macro as it has been entered.

• Discard: Do not save the macro.

• Continue: Return to the point where you were when you left
off and continue to create and record the macro.

Insert Pause is the most interesting of these. It lets the user interrupt
the macro in order to type text of any length; then, when the user presses
Shift-FlO, the macro continues. For example, you can create a macro
302 MASTERING FOXPRO

CH. 8

Stop recording ALT_J?

< Insert [literal >

< Insert [|ause > Continue


(•) Key to Resume
( ) Seconds discard

Figure 8.5: The Stop recording dialog box.

that enters your return address at the top of a letter, pauses, and then
enters the salutation. To use the macro, you let it enter the return
address, then you take advantage of the pause to enter the address of the
person you are writing to, and then you press Shift-FlO to let the macro
continue, which it does by skipping a line, typing the word Dear, and
leaving the cursor where you need it to type the rest of the name.
The Insert Pause text button has two radio buttons associated with
it, which let you control how the pause is ended:

• Key to Resume: When the macro pauses, FoxPro prompts


you to press the same key that you used to start the macro in
order to resume execution of the macro.

• Seconds: The pause lasts a certain time before the execution


of the macro resumes. The default value is one second, but
you can enter a different number.

In general, Key To Resume is the better choice, since it lets you take
as much time as you need to make the entry. Seconds is useful pri¬
marily if you want the macro to continue executing after a pause even
if no value is entered.
GETTING THE MOST FROM THE MENU SYSTEM 303

That’s all there is to creating a macro. To summarize the basic


steps:

1. To start recording, select Macro from the System menu and


either select the New text button of the Keyboard Macros
dialog box or select New Macro from the Macros menu
popup. Or you can just press Shift-FlO.

2. When the Macro Key Definition dialog box appears, press


the key combination you want to assign to the macro, and
select OK.

3. Enter the keystrokes that you want to record in the macro.

4. Press Shift-FlO to stop recording, and select OK from the


Stop Recording dialog box.

Once the macro has been recorded, use it by pressing the key com¬
bination that you entered in the Macro Key Definition dialog box.
If a macro does not work properly, the problem probably results
from your being in the wrong place when you used it. To give an
obvious example, if you saved the keystrokes needed to type San
Francisco, you must be in the City field of your database when you
use the macro.

WORKING WITH
CURRENT AND SA VED MACROS
Once you have created a macro using the methods outlined above,
it is a current macro, which appears in the scrollable list in the Keyboard
Macros dialog box. Current macros exist only temporarily, unless
they are saved.
Macros that you have saved in past sessions are kept in a disk file
with the extension .FKY. They do not appear in the scrollable list in
the Keyboard Macros dialog box, and thus are not usable until you
restore them and add them to the list of active macros.
Dividing macros into sets lets you group macros for different appli¬
cations. For example, there might be one group that you use when
you are editing programs, and others that you use when are you
304 MASTERING FOXPRO

CH. 8

doing data entry in different files. All of the macros that are being
used at a given time appear in the scrollable list, and you can save
them all as a set with a single name. Then you can recall and use that
set whenever you need it.
To save the current set of macros, select Save from the Keyboard
Macros dialog box or choose Save Macros from the Macros menu
popup. The familiar Save As dialog box appears, with all of the sets
of macros in the current directory in its scrollable list. Select one of
these names to overwrite an existing macro set, or enter a new name
to create a new macro set.
To use a set of macros that has been saved, select Restore from the
Keyboard Macros dialog box. The familiar Open dialog box
appears, with the heading Restore Macros From File above a scroll¬
able list of macro set names. Select any one and select Open to use
those macros.
Remember that the macros you restore are added to the macros
that are already open, which are in the scrollable list of the dialog
box. At some point you might want to get rid of some or all of the cur¬
rent macros before adding new ones. To get rid of a macro, select it
from the scrollable list, and then select the Clear text button or select
Clear from the Macros menu. To get rid of all the current macros,
select the Clear All text button or select Clear All from the Macros
menu. These options only clear the macros from current memory—
they do not erase the file where they are saved on disk.
Finally, to make the current set of macros the default set, the set that
is automatically used whenever you start FoxPro, just select the Set
Default text button or select Set Default from the Macros menu
popup. FoxPro asks you to confirm this selection, then it stores the
current macros in a file named DEFAULT.FKY, which it automati¬
cally uses to set the default whenever it is started. You can begin by
saving one or two macros that you always find useful as the default,
and add more default macros as you invent more.

ADVANCED EDITOR TECHNIQUES _

All the features of the File menu that you have not yet learned are
connected with creating and printing text files. When you use these
features, you are moving in the direction of using the FoxPro editor
GETTING THE MOST FROM THE MENU SYSTEM 305

as a word processor or programmer’s text editor—something more


than just using it for the routine tasks of entering data or entering
commands in the Command window. Since these features are useful
in combination with the Edit menu, learning the remaining features
of these two menu popups together will make you into an advanced
user of the FoxPro editor.

a The Form radio


button is not yet
CREA TING A TEXT OR PROGRAM FILE
You have used New from the File menu to create database, index,
report, and label files just by selecting the respective options from the
activated. In later ver¬
sions of FoxPro, it will let
radio buttons in the New dialog box. You can also use this dialog box
you create data entry (shown in Figure 8.6) to create ordinary text files and to create pro¬
forms. Currently, you gram files by selecting the File and Program radio buttons. Simply
can create data entry
type the text or the program into the window that is opened; select
forms using FoxView,
and you will learn how to Save As from the File menu when you are done.
do so in the next chapter.

System File Edit Qatabase Record Program Window

New:

(' ) Batabase
( ) arogram
( ) Jile |« OK
( ) Index
( ) Report < Cancel >
( ) Label
( ) Form

a Unlike most files


that you create
selecting New from the
Figure 8.6: The New dialog box.
File menu, text and
program files are not
created using a com¬
You can also create text or program hies from the Command win¬
mand that begins with dow by entering MODIFY FILE *Cfile name> or MODIFY COM¬
CREATE. Instead, the MAND Kfile name >.
command beginning with
Both text and program hies are ordinary ASCII hies. Unlike the
MODIFY both creates
and modifies these hies. hies created by many word processors, they do not have special
306 MASTERING FOXPRO

CH. 8

control characters of their own; both have just the standard ASCII
characters.
The difference between them is in the default editor settings that
they use. The major difference is that the default editor setting for
text files includes the word-wrap feature, which automatically moves
the cursor to the next line when you get to the right margin. Since
program files must keep each command on a line of its own, the pro¬
gram editor sets word-wrap off by default.

SETTING UP
THE PRINTER AND PRINTING A FILE
Select Printer Setup from the File menu to display the Printer
Setup dialog box, shown in Figure 8.7.

System Hie Edit Database Record Program Window

Printer Setup:

Print to:

<File... >

( ) Print On Left margin: 0


( • ) Print Off Right margin: 80

« OK » < Cancel > ommand

Figure 8. 7: The Printer Setup dialog box.

The popup control here lets you choose the device to print to. The
default is PRN, which represents your printer. You can also use this
control to print to a file. To do this, you must specify the name of the
file that the output goes to, either by selecting the File text button and
entering the file name in the Print To dialog box or simply by typing
the file name next to the File text button. The Print On and Print Off
GETTING THE MOST FROM THE MENU SYSTEM 307

radio buttons determine whether or not output goes to the printer.


Adjust the margins by typing values next to the Left Margin and
Right Margin items. When you have filled in the values you want,
select the OK text button to use these settings, and then go on to print
the file using the Print dialog box; or choose Cancel at any time to
remove the Printer Setup dialog box without activating the settings
you entered.
The Print dialog box, shown in Figure 8.8, is displayed by select¬
ing Print from the File menu.

Figure 8.8: The Print dialog box.

Use the Windows popup control of this dialog box to choose the
source of the text that will be printed. You can choose to print any of
the following:

• the text in the clipboard (that is, text that you have used the
Edit menu to copy)

• the text in the Command window

• the text in any open editing window (that is, the text of a pro¬
gram or text file)
• the text in any file that is not open
308 MASTERING FOXPRO

CH. 8

You can select the first three of these from the Window popup con¬
trol. For the fourth, printing the text in a file that is not open, select
the File text button to choose the file you want from a scrollable list
in the Print File dialog box, or just enter the name of the file you want
to print next to the File text button.
If you select the Line Numbers check box, FoxPro numbers
the lines of the file that it prints. This feature is meant primarily for
programmers.

THE EDIT MENU


In Chapter 1, you learned the basics of using the editor, such as
moving the cursor and marking text. You also learned a few features
of the Edit menu popup: Undo, Redo, Cut, Copy, and Paste.
The two next features on this popup are very simple:

• Clear: deletes (or clears) text that is marked. Since you can
also delete marked text simply by pressing Del or Backspace,
there is little need to use Clear.

• Select All: marks (or selects) all the text in the document. This
is sometimes a handy shortcut.

After these two simple features, there is a group of very useful fea¬
tures that let you move around the document, search for specific
words, and even do search-and-replace. There is also a feature that
lets you change the default settings of the editor. With the addition of
these features, the FoxPro editor is as powerful as many commercial
word processors. They are covered in detail here.

GOTO LINE

Selecting Goto Line from the Edit menu calls up the Goto dialog
box, shown in Figure 8.9, which lets you move the cursor to any line
in the document, if you know its line number. (Of course, if the word¬
wrap feature is on, the line numbers will change whenever the
text is rejustified.) Just enter the number of the line you want to move
to and then select Goto to execute the command.
GETTING THE MOST FROM THE MENU SYSTEM 309

System File Edit Database Record Program Window


. _. UNTITLED.PRG ._"_ ■

Line Number:

« Goto » < Cancel >

Figure 8.9: The Goto dialog box.

FIND

Find can also be Selecting Find from the Edit menu calls up the Find dialog box,
used to search for
shown in Figure 8.10. The items in this dialog box let you search
text in the Browse
window—for example, as
for text—a word, several words, or just a few letters—in the current
a quick way to search for document.
a person’s name. Note Just type the text you are searching for in the Look For text box.
that when you are in the
You can search for control characters by using \r to stand for carriage
Browse window, the Find
dialog box does not return, \t to stand for tab, \n to search for the new line character, and
include the Replace With \\ to search for the backslash. Just type these codes in the Look For
text box.
text box, along with any other text. For example, type \tThe to find
the word The at the beginning of a paragraph.
As you can see, this dialog box includes three check boxes:

• Ignore Case: This feature tells the search to disregard


differences in capitalization. For example, if you search for
HELLO, it will find not only HELLO but also Hello, hello,
and so on.

• Match Words: If you check this, the search looks for an exact
match only, and will not find a word that has the word you
are looking for embedded in it. For example, if you search for
top, it will not find stop or estoppel.
310 MASTERING FOXPRO

CH. 8

System File Edit Database Record Program Window


UNTITLED. PRG_ ■

Replace With:

[x] Ignore case


[ Match words « Fi nd » <Cancel>
[ Wrap around

Figure 8.10: The Find dialog box.

• Wrap Around: If you check this, the search will look from the
location of the cursor to the end of the file, and then will
“wrap around” and continue the search at the beginning of
the file. This option lets you search through the entire file
without first moving to the beginning of the file.

If you want to replace the text you are searching for with some
other text, type the new text in the Replace With text box. This
replacement is not made automatically, however; you must also
select one of the following options from the Edit menu in order to
make the replacement.

FIND AGAIN

Selecting Find Again from the Edit menu repeats a search you just
made without your having to fill out the dialog box again. This comes
in quite handy since files usually have the word you are looking for
more than once, and the first one you find is not necessarily the one
you want.
GETTING THE MOST FROM THE MENU SYSTEM 311

REPLACE AND FIND AGAIN


Selecting Replace And Find Again from the Edit menu replaces
the text you just located (which matches the text in the Look For text
box of the Find dialog box) with the text you entered in the Replace
With text box, and then continues the search for the next occurrence
of the text in the Look For box.

REPLACE ALL
Selecting Replace All from the Edit menu replaces every occur¬
rence of the text in the Look For text box with the text in the Replace
With text box.

PREFERENCES
Selecting Preferences from the Edit menu calls up the Preferences
dialog box, which lets you change the default settings of the editor. As
you can see from Figure 8.11, the default settings are different for
text, program, and memo windows. When you read the descriptions
of this dialog box’s features, look at these illustrations and note that
some of them are not available for all types of windows.
The default settings are usually the settings you need for the type of
file you have chosen. For example, if you are creating a text file, you
ordinarily want to have a word-wrap feature, so that the right margin
automatically determines where to break a line without you having to
keep track of where the margin is. If you are creating a program file,
though, you need to keep each command on its own line and press
Enter at the end of each command, so that FoxPro knows when the
command is complete, even if that means going beyond the visible
right margin for some commands.
FoxPro’s word-wrap defaults are set accordingly. If you create a
new text file, the Wrap Words check box of the Preferences dialog
box is automatically checked. If you create a new program file, it is
automatically not checked. You do not even have to look at the dialog
box; just type and you will find that these defaults are in effect.
312 MASTERING FOXPRO

CH. 8

System File Edit. Database Record Program Window


UNTITLED

I
[X] Wrap words Tab size: K
[X] Auto indent
[X] Make backup [ 3 Use these preferences
[X] Add line feeds as default for files
with no extension
[ ] Ctrl-Z sensitive [ 3 Save preference

(•) Left justify


( ) Right justify
( ) Center justify « OK » <Cancel)

System File Edit Database Record Program Window


UNTITLED.PRG

1
[ Wrap words Tab size: K1
[x; Auto indent
[X] Make backup [ 3 Use these preferences
[X] Add line feeds as default for .PRG
[ : Compile when saved files
[ Ctrl-Z sensitive [ 3 Save preference

(• ) Left justify
( ) Right justify
( ) Center justify « OK » <Cancel>

System l-ile Edit Database Record Program Window


EMPLIST->NOTES

H
[X ] Wrap words Tab
[X Auto indent
[ 3
as default for Memos

[ 3 Ctrl- Z sensitive [ ]3 Save preference

(• ) Left j ustify
( ) Right justify
( ) Cente:r justify « OK » <Cancel>

Figure 8.11: The Preferences dialog box with the default settings for text,
program, and memo files.
GE TTING THE MOST FROM THE MENU SYSTEM 313

If you do want to change default editor settings, for some reason,


you can use the following check boxes of the Preferences dialog box to
do so:

• Wrap Words: determines whether the word-wrap feature is


used, as you have just seen.

• Auto Indent: automatically indents each line the same


amount as the previous line. This is usual in programming,
where you want to line up commands one below the other to
make the program easier to read.

• Make Backup: automatically makes backup files. When you


save a new version of a file, the previous version is saved in a
file with the extension .BAK.

H Because the FoxPro


editor does not add
• Add Line Feeds: saves files with a carriage return and line
feed at the end of each line. If this is not checked, files are
line feeds to text files by saved with a carriage return and line feed only where you
default, its text files are pressed Enter, making it possible to rejustify the text the next
very' easy to use in any
word processor that can
time you edit it.
import plain ASCII files.
• Ctrl-Z Sensitive: allows DOS to use the control character
Text is automatically
justified to whatever Ctrl-Z (ASCII character 26) to mark the end of a file. If this
margins your word pro¬ box is checked, the editor treats the first Ctrl-Z in the file as
cessor uses. There is thus the end of file, even if there is text after it. It will not let you
no worry about getting
rid of unnecessary car¬
edit beyond the Ctrl-Z and will not save any text beyond the
riage returns, as there Ctrl-Z.
often is when you transfer
hies between one word In addition, if you are editing a program file, this dialog box has
processor and another.
one other check box, Compile When Saved. If you select this, the
program will automatically be compiled each time you save the file.
The radio buttons under this list of check boxes control how the
text is justified. Most text, of course, is left-justified, but these radio
buttons also let you right-justify or center every line of a file.
The Tab Size box lets you choose how many spaces are skipped
each time you press the Tab key.
The check box marked Use These Preferences for all new files
should be used with caution. If you select it, the conditions specified
in this dialog box will be the default conditions for all text, program,
and memo windows. You are very unlikely to want the same defaults
314 MASTERING FOXPRO

CH. 8

for these three types of file: this check box is useful for people who do
not use more than one or two of these file types.
The check box marked Save Preference can be used more freely. If
you check it, these preferences will be used every time you edit this
file. The size and location of the window and location of the cursor
will also be the same as you left them the last time you closed the file.

ADVANCED TECHNIQUES
FOR MANIPULATING DATA -

Continuing to move across the menu bar, we come to the Data¬


base and Record menu pads.
There are a number of very useful features of the Database menu
popup that you have not learned about yet. These fall into two cate¬
gories on the popup: those involving two database files, and the
arithmetic commands. You have already learned half of the com¬
mands that involve two database files (Copy To, which copies
records from one file to another, and Sort, which sorts the records of
one file into another); there are two other commands in this group
that you have not yet learned about. Append From appends records
to the current file from another file, and Total adds numeric values
from one file and puts the results in another file. The other category
on this popup includes a number of arithmetic commands, none of
which you have yet learned: Average, Count, Sum, and Calculate.
There is also one command on the Record menu popup that you
have not yet learned: Replace lets you change the contents of a single
record or a whole group of records.
Though these commands are not essential to the basic work of
maintaining your database, there are times when they are very
handy.

APPEND FROM
Selecting Append From from the Database menu calls up the
Append From dialog box, shown in Figure 8.12. This dialog box lets
you add records to the currendy open database from another file.
GETTING THE MOST FROM THE MENU SYSTEM 315

Figure 8.12: The Append From dialog box.

To choose the hie to append records from, type its name to the
right of the From text button—or, if you do not know its name, select
the From text button to select it from a list of hies.
As you can see, this dialog box has Scope, For, While, and Fields
check boxes, which you are very familiar with from Chapter 5 of this
book. You can use these check boxes in the ways you have learned, to
determine which records to append from the selected hie to the cur¬
rently open hie. For example, to append only those with addresses in
California, you would check For and enter the logical expression
STATE = “CA”.
The Type popup of this dialog box is particularly useful, since it
lets you append records from other types of hies besides database
hies. Select this popup control and you will be given these choices:

• Database: to append from a standard FoxPro database hie (or


any other dBASE compatible database hie with a .DBF
extension)

• Delimited With Tabs: to append from a text hie with tabs


between the data in each held
• Delimited With Commas: to append from a text hie with com¬
mas between the data in each held
316 MASTERING FOXPRO

CH. 8

• Delimited With Spaces: to append from a text file with a


single space separating each field
• SDF: to append from a text file where the records all have the
same length and all end with a carriage return and line feed
Apart from Database, the most common type you will run into is
Delimited With Commas. Many database programs allow you to
export data from their own file type to comma-delimited files. These
files normally have character fields in quotation marks as well as hav¬
ing commas between fields. If you have this type of text file, exported
from some other database, you can simply use Append From from
the Database menu with the Delimited With Commas type to import
it into FoxPro.
The Copy To dialog box also has a Type popup control, which lets
you select Delimited With Commas in order to copy a FoxPro file
into this sort of comma-delimited text file, which then can be
imported by other, noncompatible database-management programs.
Working from the Command window, you can use the command
APPEND FROM Kfile name'> to add records from another file to the
current database file.
For more information, see the commands APPEND FROM and
COPY TO in Appendix C.

TOTAL
Selecting Total from the Database menu calls up the Total On dia¬
log box, shown in Figure 8.13. This dialog box lets you compute
totals for the numeric fields in the current database and create a new
database file with corresponding fields to store the answers.
The key to understanding how Total works depends on the fact
that you must enter a field name or expression to the right of the Expr
text button. You can do this by selecting a field name from the scroll¬
able list, by selecting the Expr text button to call up the expression
builder, or simply by typing the field name or expression to the right
of this text button. The command then finds numeric totals based on
this expression. For example, if you select STATE, the new database
that is created will include totals for each state.
For Total to work, the database must be sorted on this same key
field or expression, or it must be in use with an index based on this
same key field or expression as the major index that determines the
order of its records.
GETTING THE MOST FROM THE MENU SYSTEM 317

Figure 8.13: The Total On dialog box.

The check boxes in the Total On dialog box are optional. The
Scope, For, and While check boxes let you limit the records that are
included in the total, in the ways that you learned in Chapter 5; and
the Fields check box lets you limit which fields are totaled. If you do
not use the Fields check box, all the numeric fields in the database will
be totaled.
The Save As text button displays the familiar Save As dialog box,
so you can type in a name for the new file. Of course, you can also

H As before, these
commands are
simply enter the name next to this text button.
Because of the preparation it requires, it is often more convenient
to perform this operation from the Command window. Use the fol¬
written using the usual
conventions: the parts of lowing command:
the command that are in
square brackets are TOTAL ON < field expression > TO <file name> [FIELDS
optional.
<fieldlist>] [FOR <logical expr>] [WHILE <logical expr>]

(all on one line, of course). You can prepare to use the command by
indexing first, for example:

USE EMPLIST
INDEX ON STATE TO STATES
TOTAL ON STATE TO EMPTOTAL
318 MASTERING FOXPRO

CH. 8

It is probably easier to create the index and then total from the com¬
mand line than it is to use the menu system for the same task.

CALCULATIONS USING MEMORY VARIABLES


As you can imagine, it is often inconvenient to create an entire new
database file just to hold the totals from your current file. Though the
TOTAL ON command creates the new file automatically, you have
to go through the trouble of opening and browsing it to see the totals,
and then you probably will have to delete it when you are done with
the totals.
The next four commands that you will look at let you perform cal¬
culations without creating a new file to hold the results. Instead, the
results go into memory variables. Memory variables are very important
to computer programming, and you will learn more about using
them in Chapter 10, but it is very easy to learn enough to use them
now to hold the results of these commands.
The names of the fields in a database are variables, because their
value can change as you move from record to record. If you enter the
command ? STATE, for example, the letters that FoxPro prints can
change depending on which record the pointer is on.
The values of the fields in your databases are stored permanendy
when you quit FoxPro. But FoxPro also lets you create temporary vari¬
ables which are lost when you quit the program. These variables are not
stored on disk like database files. They are just kept in your computer’s
memory, and so they are called memory variables. It is conventional to
give memory variables names beginning with the letter M.
You can create a memory variable from the Command line and
assign it a value by using the command STORE <valued TO <vari¬
able name > or the command < variable name > = < value >. The equals
sign in the second version of the command should not be confused
with the = operator that is used for comparison in logical expres¬
sions: in this case it actually creates the variable and assigns the value
to it, and it should be read as “let <variable name^ equal <value. >”
You can use either of these commands to change the value of an exist¬
ing memory variable as well as to create a new one.
GETTING THE MOST FROM THE MENU SYSTEM 319

In the following short exercise you will create and print a couple of
different variables. You will notice that, when you assign a value to a
variable, the value is displayed as FoxPro talk (unless you have set
Talk off). When you print the variable, the number includes leading
blanks. As you learned in Chapter 4, you can control its width and
number of decimal places by using the STR() function.

1 • In the Command window, enter STORE 20 TO MYAR1.


2. Enter ? MYAR1 and FoxPro prints 20.

3. Enter MVAR2 = 10. Then enter ? MVAR2 and FoxPro


prints 10.

4. Try changing the value of an existing variable. Enter


MVAR1 = 25. Then enter ? MVAR1 and FoxPro prints 25.
5. You can also perform calculations using memory variables.
Enter ? MVAR1 - MVAR2 and FoxPro prints 15. Enter

? (MVAR1 * 2) - (MVAR2/2)

and FoxPro prints 45.00, as shown in Figure 8.14.

Syr, torn Database Record Program Window


20
20
10
10
25
25
15
45.00

Figure 8.14: Using memory variables.


320 MASTERING FOXPRO

CH. 8

It is possible to create memory variables of any FoxPro data type—


except, of course, Memo. (At this point, you only need to use
numeric memory variables.) The data type depends on the delimiters
you use when you create the variable. For example, the command
MVAR3 = “HELLO” would create a memory variable of the
character type with the word HELLO stored in it. Just remember
that any value that you store in a memory variable is temporary and
will be lost when you quit FoxPro or turn off your computer.
With this background, you should have no trouble using the fol¬
lowing options on the Database menu popup that involve memory
variables.

AVERAGE

Both this Average Selecting Average from the Database menu calls up the Average
command and the dialog box, shown in Figure 8.15. This dialog box lets you find the
AVG() function give you
the arithmetic mean, which
average value for numeric fields or expressions in your database and
is calculated by adding a store the answer in memory variables.
list of numbers and divid¬
ing the sum by the num¬
ber of numbers in the list.
This is the most common System File Edit Database Record Program Window_
use of the word average,
which is sometimes used
in other senses.
Average: Memory Variables:

« OK »

< Cancel >

To Variable:

Figure 8.15: The Average dialog box.


GETTING THE MOST FROM THE MENU SYSTEM 321

If you select the Expr check box in this dialog box, you can enter a
field name or field expression for the command to average: for
example, enter WAGE to find the average wage. You can use only a
numeric expression with this command. If you do not enter an
expression, the command will average every numeric field in the cur¬
rent database.
The averages are displayed on the screen, as part of the FoxPro
talk (unless, of course, you have set Talk off).
If you enter an expression to average on, then you can also enter
the name of a memory variable to hold the result. You can create a
new memory variable by entering its name in the To Variable text
box. Or you can store the result in an existing memory variable,
replacing its current value, by selecting its name from the Memory
Variables list.
Ordinarily, you will get the average of all the records in the current
database file. You can restrict the records that are averaged, though,
by selecting the Scope, For, or While check box—for example, if you
want the average wage for one state.
You can use similar options from the Command window using the
AVERAGE command. The basic syntax is AVERAGE Knum expr>
[TO Kmemvar>]. The <memvar> in the optional TO clause of
course indicates the name of the memory variable. You can also add
a Scope or a FOR or WHILE clause before TO <.memvar>. For
Remember that, as
more details, see Appendix C.
you learned before,
all of these commands
include records that are
COUNT
marked for deletion
unless you use the com¬ Selecting Count from the Database menu calls up the Count dia¬
mand SET DELETE
log box, shown in Figure 8.16. This dialog box lets you count how
OFF before you execute
them, or use one of the many records there are in the current database.
other methods of dealing As you can see by comparing the illustrations, Count is very simi¬
with deleted records that
lar to Average, except that it does not have an Expr check box. This is
you learned in Chapter 5.
This is not only impor¬ because you do not need an expression to count on: FoxPro simply
tant when you are count¬ counts each record once.
ing records but also when
Like the Average, the Count of records is displayed as part of the
you are summing, aver¬
aging, and performing
FoxPro talk. You can store it to either a new or an existing memory
other calculations. variable in the same way, and you can restrict the number of records
322 MASTERING FOXPRO

CH. 8

System Hie Edit Database Record Program Window

Count: Memory Variables:

« OK »

< Cancel >

To Variable:

Figure 8.16: The Count dialog box.

in the same way by using the Scope, For, or While check box. (The
usual check boxes are included even though you obviously would
never want to use Count with a Scope.)
You can use similar options from the Command window using the
COUNT command. The basic syntax is COUNT [TO Kmemvar^].
You can also add a Scope or a FOR or WHILE clause before TO
<memvar>. For more details, see Appendix C.

SUM
Selecting Sum from the Database menu calls up the Sum dialog
box, shown in Figure 8.17. This lets you find the sum of numeric
fields or expressions in your database and store the answer in mem¬
ory variables.
As you can see by comparing the illustrations, Sum works in a way
that is identical to Average. By default, it sums all numeric expres¬
sions and displays the result as talk. You can check the Expr check
box to enter a numeric expression to be summed (such as WAGE),
and you can store the result in a new or existing memory variable.
Select the Scope, For, or While check box to restrict the records that
are summed. From the Command window the basic syntax is SUM
GETTING THE MOST FROM THE MENU SYSTEM 323

System File Edit Database Record Program Window

Sum: Memory Variables:

« OK »

< Cancel >

To Variable:

Figure 8.17: The Sum dialog box.

Knum expr> [TO <memvar>\ with a Scope or a FOR or WHILE


clause.

CALCULATE
Selecting Calculate from the Database menu calls up the Calculate
dialog box, shown in Figure 8.18. This dialog box lets you perform a
number of different calculations.
This dialog box works just like the others you have looked at, with
one exception: to use it, you must select the Expr text button. This
calls up a special version of the expression builder dialog box, which
has only the Math popup control and only a limited number of
options available, as shown in Figure 8.19.
Note that some of these calculation functions are used with no expres¬
sions, some require numeric expressions, and some (indicated by just
<exp>) can be used with numeric, character, or date expressions.

• AVG(<num exp>) finds the average (arithmetic mean) for


the expression

• CNT() counts the number of records in the database

• MAX( <£*/?>) finds the largest value of the expression


324 MASTERING FOXPRO

CH. 8

System File Edit Database Record Program Window

Calculate: Memory Variables:

« OK »

< Cancel >

To Variable:

Figure 8.18: The Calculate dialog box.

System File_Edit Expression

Math

Field Names: Database: Variables:

►EMPNO EMPLIST ►^ALIGNMENT


FNAME BOX
LNAME _INDENT
ADDRESS < Verify > _LMARGIN
APT_NO _PADVANCE
CITY « OK » _PAGENO
STATE _PBPAGE
ZIP < Cancel > PCOLNO

Figure 8.19: The special expression builder used with Calculate.

• MIN( <ex/?>) finds the smallest value of the expression

• NPV(<mzra exp>,<exp> ,<num exp>) finds net present


value of periodic future cash payments, discounted at some
interest rate
GETTING THE MOST FROM THE MENU SYSTEM 325

• STY>(<num exp>) finds standard deviation, the degree to


which the field values vary from the average

• SUM(<nwm exp >) finds the sum


• VAR(<num exp>) finds the variance from the average,
which is the square root of the standard deviation.

The use of most of these functions is obvious. For more informa¬


tion look under CALCULATE in Appendix C.
You can see that some of these functions—SUM( ), CNT( ) and
AVG( )—duplicate other menu choices. One advantage of Calculate,
though, is that you can perform several calculations at once. If you use
the expression builder to create a list of functions, separated by commas,
all the calculations will be performed and displayed as talk. If you want
to store them to memory variables, simply create a list of an equal num¬
ber of memory variables, also separated by commas.
From the Command window, the basic form of this command is
CALCULATE Kexplist'y [TO Kmemvar list>].

REPLACE
There is one very useful option on the Record menu popup that
you have not yet learned. Selecting Replace from the Record menu
lets you replace the value in a field of the current database with some
new value.
This option is very useful when it is used with the scope of ALL: it
lets you change or fill in a given field in every record in the database.
For example, say that you modify the structure of your database to
add a new logical field, and that the field should start off by being true
for every record: instead of using the keyboard to type the entry in
each record, you can use Replace with the All check box.
The default scope for Replace is NEXT 1; so if you do not specify a
scope it only replaces the value of the current record.
The Replace dialog box, shown in Figure 8.20, is easy to use. Just
select the field whose value you want to change (from the scrollable
list of field names), and type the new value to the right of the With
text button.
326 MASTERING FOXPRO

CH. 8

Figure 8.20: The Replace dialog box.

To create an expression that you want to replace the current value


with, you can select the With text button to call up the expression
builder. You might want to use an expression as the new value, for
example, if every employee got a cost-of-living raise of 10 percent:
since the new wage would be 1.10 times as great as the current wage,
you would select WAGE as the field whose value should be changed,
and use the expression WAGE * 1.1 as its new value.
Use the For or While check boxes in the usual way to restrict the
records that the command affects—for example, if only employees
from California get a cost-of-living raise. Remember, though, that
the default scope is NEXT 1. If you want FoxPro to look through the
entire database for employees from California (rather than just
checking the next record to see if it is from California), then you must
use the Scope check box and enter the scope of ALL in addition to
using a FOR or WHILE clause.
Working from the Command window, the basic form of this com¬
mand is REPLACE [ < scope > ] Kfield name> WITH < expr > .
Remember, again, that if the optional <scope> is omitted, the de¬
fault is NEXT 1. For example,

REPLACE PROBATION WITH .T.


GETTING THE MOST FROM THE MENU SYSTEM 327

only acts on the current record;

REPLACE ALL PROBATION WITH .T.

acts on the entire database. A FOR or WHILE clause can be added


at the end of the command, for example,

REPLACE ALL PROBATION WITH .T. FOR STATE = "NJ"

SETTING COLORS
There is one remaining command that you should look at briefly.
Selecting Color from the Window menu calls up the color picker dia¬
log box, shown in Figure 8.21. This dialog box lets you control the
colors of your FoxPro display—or, if you are using a monochrome
monitor, the intensity of your display. This command is not often
needed; it is useful mainly if you have an unusual color monitor that
is hard to read when FoxPro’s default colors are used.
ftmmi r* foVI'luh
s tA/ a<c *rr*A*
-t

System File Edit 4-


-( ) 7 Clock
-( ) 2 GET field Usr Winds

Command -( ) 5 Title, idle


DO myprogl Trace = -( ) 4 Title, active « OK
@ 1,16 GET customer -( • ) 1 ? & SAY field
READ -( ) 6 Selected item < Cancel
Ge <@ancel> <[j]esume> -( ) 9
Load..
-( ) 8 Shadow
«Topics» <Next> <Previous> -( ) 10 Save..
-( ) 3 Border
Help

X X X X X X X X X
X X X X X X X X X
X X X X X X X X X «
X X X X X X X X X [X] Shadow
X X X X X X X X X
X X X X X X X X Ej [ ] Blink
X X X X X X X X E
X X X X X X X X E

Figure 8.21: The color picker dialog box.


328 MASTERING FOXPRO

CH. 8
<’/>£€/Ff £ C&tof CP/WfitNAf'/ off
*Pb vjfW
F: &A fi,
foil fat
You can change the colors of many different features of your dis¬
*9
VPf f //[ £ play. The popup control in the upper right of this dialog box gives
you these choices:
r &M hi

Usr Winds: user windows


4/ w+/tf WN) W
Usr Menus: user menus
Menu Bar: the main menu bar and menu pads
Menu Pops: menu popups
Dialogs: dialog boxes and system messages
• Dlog Pops: popup controls and scrollable lists within dialog
boxes

Alerts: alerts (error messages)


Windows: system windows
Wind Pops: popup controls and scrollable lists within
windows

Browse: the Browse/Edit window


Report: the report layout window

The list also includes numbered Schemes. Schemes 12 through 16


are reserved for use in later versions of FoxPro and Schemes 17
through 24 may be used by advanced programmers.
Once you have selected the feature whose color you want to
change, choose Load to select from a scrollable list of available color
sets, and select one that is suited to your computer. The Shadow
check box is used to add a shadow behind the selected feature, and
the Bright check box is used to intensify the background color of the
feature associated with the current radio button; use the Blink check
box to make this feature blink.
Once you have the color combinations you want, select Save. Fox¬
Pro prompts you to enter a name for this new color set. To use the
color set during the current session, select OK.
It is very unusual to need to change the default colors of FoxPro,
but this summary of the basics of using the color picker gives you an
idea of what you can do. If you do need to use the color picker, see
your User's Guide for more details.
*
Creating Custom
Data-Entry Screens and Applications

' ■'

..
iiiisitis
To use the Fox View Shell, 337
press the Scroll Lock key to call up the Shell any time you are
using Fox View. The Shell has a prompt similar to the DOS
prompt, where you enter commands.

To use the Fox View menu system, 345


press Esc to pop up a menu. Use the right and left arrow keys to
move among menu popups, and the up and down arrow keys
to move among menu options. The most important menu options
let you quit Fox View, load a database hie or table into Fox View,
save a Fox View table, and select a compiled template.

To use File View, 351


press F9 to toggle between Database File View and Alias File
View. Both these features give you basic information about the
hies you are working with.

To use Forms View and Table View, 353


press F10 to toggle between Forms View and Table View.
Forms View displays the helds of the current database hie and
lets you move them around the screen and add text and graph¬
ics. Table View displays a table that describes the screen you
create in Forms View and lets you add features to validate data
entry.

To design a screen, 356


hrst toggle to Forms View, which begins by displaying the helds
of the current database hie one above another. Use the arrow
keys to move among helds and other objects. Press F3 to drag
an object, F4 to resize an object, Ctrl-C to center an object,
Ctrl-U to delete an object, Ctrl-B to add a Box object, Ctrl-N to
add a text object, or the space bar to edit a text object.
To validate data, 363
first toggle to Table View, which has a tabular description of the
objects displayed in Forms View. Enter a picture template in
the Picture column to determine the type of data that can be
entered in that field. Enter two values in the Range column to
determine the maximum and minimum value that can be
entered in the field.

To create a custom data-entry screen, 364


first design the screen and add any necessary data validation.
Then use the Gen menu popup to select compiled templates:
select FORMS 1 Template from the template list, and enter a
name for the .FMT program you are creating.

To use a custom data-entry screen, 365


return to FoxPro and check the Format check box of the Setup
window, then select the name of the entry screen from the scrol¬
lable list. (Or enter the command SET FORMAT TO Kfile
name>.) When you append or edit data after this, the validity
checks you created will be operative.

To generate an application, 367


first use Fox View to design the screen you want and add valida¬
tion if needed. Then select APPS1 Template from the template
list, and enter the name you want to give to the application.

To use a generated application, 369


return to FoxPro, select Do from the Program menu, and, from
the scrollable list, select the program you created. (Or enter
DO <program name> in the Command window.)
334 MASTERING FOXPRO

CH. 9

NOW THAT YOU HAVE LEARNED OF THE FEATURES


of FoxPro that you need as a user managing your own data, you can
begin to move to features that are useful primarily for setting up Fox¬
Pro for other users, so it can be used more easily by novices.
No doubt, you have realized in the course of using this book that peo¬
ple have to do some learning before they can use FoxPro: it is not so
intuitive that someone who has never seen it before can just sit down and

a As you have seen,


the Forms radio
begin using the menu system. No really powerful program is.
Often, businesses hire data-entry people who know nothing about
FoxPro, and their applications must be set up so that these people can
button of the New hie
dialog box, which will let use them with little or no training. If they do not want to do program¬
you create data-entry ming to accomplish this, they can use the Fox View code generator to
forms directly from Fox¬
create custom data-entry forms that make it easier to enter data; Fox-
Pro, is not yet imple¬
mented; it will be added View will even generate the program to run an entire menu-driven
in a later version of the application so simple that even a novice can use it to maintain a data¬
program.
base, and produce reports and labels.

THE FOXVIEW/FOXCODE SYSTEM _

FoxView and FoxCode, two applications that come with FoxPro,


work together. FoxView generates programs by using templates that
are created with FoxCode.
FoxCode includes what is called a template language—a complete
programming language totally different from the FoxPro/dBASE
language, designed to create the templates that FoxView uses to gen¬
erate programs.
FoxCode is not covered in this book. Needless to say, it is a very
advanced feature of your FoxPro package, meant for programmers
who have created the same sort of database management system over
and over again and have seen the similarities between the various indi¬
vidual systems, programmers who want to create a sort of generic sys¬
tem to generate all of these individual systems. When you create the
typical menu-driven system at the end of this chapter, you will see that
the same menu options are needed to maintain many different data¬
bases; so you can imagine what is involved in creating a template.
CREATING CUSTOM DATA-ENTRY SCREENS AND APPLICATIONS 335

If you find that you Fortunately, you do not need to know anything about FoxCode in
do not have any order to use FoxView. Several templates have already been created
templates available when
and compiled and were automatically put in a subdirectory named
you use FoxView, see
Appendix A on installing \FOXPRO\TEMPLCOD when you installed FoxPro. You can
FoxPro, which includes simply use them to generate applications. You should have these
installation of these tem¬
templates:
plates. If necessary,
reinstall FoxPro following
the instructions from the • ADVANCED: An advanced database-maintenance applica¬
beginning. tion, including popup menus. Though it is much simpler
than FoxPro itself, this application is complex enough that it
requires a bit of learning before it can be used.

• APPS1: A basic database-maintenance application, with


menu choices simple enough that it can be used with virtually
no learning.

• FORMS 1: Creates a data-entry form that is primarily meant


to be incorporated into programs, but which can also be
used, at least for testing, using the menu system.

• FORMS2: Creates a data-entry form that stores data in mem¬


ory variables before they go into the database file itself. This
can be used only within a program.
• REPOl: A report generator. The advantage of using this,
rather than the ordinary report forms, is that it generates
a program written in the FoxPro language, which an ad¬
vanced programmer can then modify.
• SIMPLE: A simple database-maintenance application. This
application is not much easier for the user than the one gener¬
ated by APPS1, but the code it creates is easier to understand
and modify. If you want to do programming based on
FoxView-generated code, begin with this application

If you have a later release of FoxView, you may have more tem¬
plates available. We can expect developers to come up with more
templates in the future, and many will probably be public-domain
software or shareware. In this way FoxView will become more and
more powerful.
336 MASTERING FOXPRO

CH. 9

In this chapter, you will use FORMS 1 to create a data-entry form.


Then you will find that it takes very little extra effort to generate an
entire menu-driven application using APPS1. The data-entry and
menu screens you generate with these two templates will be very sim¬
ilar to those you write yourself when you learn programming in
Part III of this book.

THE BASICS OF FOXVIEW _

You can use FoxView from within FoxPro by selecting FoxView


from the Program menu or by entering FOXVIEW in the Command
window. You can also use FoxView as a stand-alone application, by
entering FOXVIEW at the DOS prompt.
Because it is a separate application that has been integrated into
FoxPro, FoxView has its own interface that is entirely different from
the FoxPro interface. Many of the things it can do duplicate the capa¬
bilities of DOS or FoxPro. For example, you can use FoxView instead
of FoxPro to create a database file. If you use it very frequently, you
will find it worthwhile to learn all these capabilities of FoxView. This
book will emphasize the necessary features of FoxView, because it is
easier for a beginner to use FoxPro to create a database file and do
other necessary work, and to use FoxView purely to generate custom
screens and applications.
The FoxView interface has four essential features, which are listed
below along with the key you press to use each one:

• Shell: Press Scroll Lock to use the FoxView Shell, which


resembles DOS and lets you enter interactive commands.
The Shell is essentially a convenience for more advanced
users; you can use the most important of its commands in
other ways.

• menu system: Press Esc to use the FoxView menu system to


use database files, select templates, compile applications, and
perform other necessary FoxView functions.

• File View: Press F9 to use File View, which gives you sum¬
mary information about the files you are using.
CREATING CUSTOM DATA-ENTRY SCREENS AND APPLICATIONS 337

• Forms View and Table View: Press F10 to toggle between


these two views, which work together and let you design cus¬
tom data-entry forms.

In addition, you can press FI at any time to get help with Fox View
(as with FoxPro). Help is context-sensitive: the help screen that
appears describes the feature that you were using when you pressed
FI. You can then use PgUp and PgDn to scroll through all the help
screens. Press Esc to exit from the help system.

THE FOXVIEW SHELL


When you start FoxView, you begin at the FoxView Shell, shown
in Figure 9.1. You can also call up the Shell at any time by pressing
the Scroll Lock key.
The Shell is essentially a convenience for advanced users of
FoxView—-just as more advanced users of FoxPro often find it easier
to work from the Command window than from the menu system. As
you will see, most of FoxView’s Shell commands duplicate things
that you can do from DOS, from FoxPro, or from the FoxView
menu system.
Though it does have a few extra utilities that are sometimes handy,
the FoxView Shell is not necessary for using FoxView, and it is better
for beginners to use methods that require less learning. However, if
you use FoxView often, you will find that it is worth learning Shell

n Some of the descrip¬


tions of these com¬
commands because they save time.
At this point, though, you should just skim this section and glance
at the Shell commands to get a general idea of what they can do.
mands will be easier to
understand when you Remember that any commands that are necessary are also accessible
come back to this section through the FoxView menu system and will be covered in the next
after learning other fea¬
section.
tures of FoxView.
If you find that you are using FoxView frequently, you should
definitely come back to this section and study the Shell commands
more thoroughly. When you use the FoxView Shell as a beginner,
you will probably find the help screens convenient to remind you of
the commands. The help screens on the Shell are also useful because
they organize the commands in a way that makes them easier to
338 MASTERING FOXPRO

CH. 9

Figure 9.1: The FoxView Shell.

understand, dividing them into DOS commands, Database com¬


mands, and special Shell commands. You should glance at how the
commands are organized in the help windows as you skim over
the descriptions of them, so you can find the help on a command eas¬

a In some early
releases of FoxPro,
ily if do you want to use it.

1. If necessary, enter CD\LEARNFOX and then enter FoxPro. To


the FoxView option of the
Program menu is not use FoxView, select FoxView from the Program menu, or
activated. FoxView can enter FOXVIEW in the Command window. When the Fox¬
still be used, however, by View title screen appears, press Enter to continue to the Shell.
entering FOXVIEW in
the Command window. -
As you can see, the Shell includes a status line on top with the
current DOS directory, date, and time; it also includes a
prompt that looks very much like the ordinary DOS prompt,
where you can enter commands.

2. Press FI, the help key, and glance at the first help screen for
the Shell, shown in Figure 9.2, with the headings Navigation
Keys and DOS Commands.

3. Press PgDn to see the second help screen for the Shell, shown
in Figure 9.3, with the heading Database Commands.
CREATING CUSTOM DATA-ENTR YSCREENS AND APPLICATIONS 339

FoxView HELP SHELL ENVIRONMENT (l) 12 of 14

NAVIGATION KEYS;
1 <Uparrow>-<Downarrow> ft
Scroll to previous/next command
2 <PgUp>-<PgDn> ft
Scroll to previous/next page
3 . cCursor keys> ft
Command line navigation
4 . LIST HIST[ORY] ft
List command-line history

DOS iCOMMANDS:
1 . <d : > ft
Change disk drive
2 . CD <pathname> ft Change directory
3 . CLS ft
Clear screen
4 . COPY (source) <dest> * Copy file from source to dest
5 . DIR <filespec> [/W] * Directory listing
6 . ERASE <filespec> ft
Erase file
7 . MD <pathname> ft
Make directory
8 . PATH ft
Display current PATH
9 . RD <pathname> ft
Remove directory
10 REN (source) <dest> ft
Rename source to dest
1 1 . TYPE <filespec> ft
Display file contents

Select previous or next screen with PgUp or PgDn


Press FI for Table of Contents; press ESC to exit

Figure 9.2: The first help screen of Shell commands.

FoxView HELP SHELL ENVIRONMENT (2) 13 of 14

DATABASE COMMANDS:
1 . APPEND < fn > [ALIAS < C >] * Append DATABASE or text file
2 . CREATE < fn > [alias <c>] * Create database file
3. IMPORT < fn > [ALIAS <c>] * Import @/SAY/GET/PICTURE/RANGE
4 . LIST [ALIAS <c >] * Display current structure
LIST * . dbf * Display database structures
LIST *. idx * Display index keys

5. LOAD < filenamei * Load FoxView Table


6 . MAP <fn> [ALIAS <c>] * Map from database or table
7. NEW < fi1ename > * New FoxView Table
8 SAVE [< n ew f ile>] * Save current FoxView Table
9. SELECT <c > * Select alias workarea
10 . USE <fn > [A LIAS <c>] * Load FoxPro database file

11 , VIEW FILE (or F9) * Display File View


VIEW FORMS (or F10) * Display Forms View
VIEW TABLE (or F10) " Display Table View

Select previous or next screen with PgUp or PgDn


Press FI for Table of Contents; press ESC to exit

Figure 9.3: The second help screen of Shell commands.


340 MASTERING FOXPRO

CH. 9

4. Press PgDn to see the third help screen for the Shell, shown in
Figure 9.4, with the heading Shell Commands.

Fox View stores the last commands that you have entered, up to a
maximum of 36 commands, and these are sometimes called the com¬
mand history. The navigation keys on the first help screen are meant to
let you scroll through these commands so you can reuse them. Just press
the up and down arrow keys or PgUp and PgDn to move through the
command history. Then you can reenter previous commands.

FoxView HELP SHELL ENVIRONMENT (3) 14 of 14

SHELL COMMANDS:
1 . <filename> [<parms>] * Run .COM, EXE, or ,0A1 file
2 . CONFIG <filename> * Load new CFG file
3. EJECT * Elect printer page
4 . EXIT * Exit to DOS
5. LIST ST AT[US] * Display flags and system status
6 . QUIT * QUIT FoxView
7. RUN <filename> [<parms>] if Run .COM, .EXE, or .BAT file
8. SAVCAP <filename> * Save 4000-byte screen image
SAVTXT < filename> * Save only text portion

9. SET ALTE[RNATE] TO [<fn>] * Create/close output file


SET ALTE[RNATE] on/OFF * Send output to file
10 . SET PAUSE ON/off * Pause on DIR or LIST
1 1 . SET PRINT on /CfFF * Send output to printer
12 . SET SAFETY ON/off * Check file before overwrite

Select previous or next screen with PgUp or PgDn


Press FI for Table of Contents; press ESC to exit

Figure 9.4: The third help screen of Shell commands.

The command LIST HISTORY lists all of the previous com¬


mands, up to the 36-command maximum.
The rest of the Shell commands in the first help screen are identical
to DOS commands—you save time by using them directly from the
FoxView Shell rather than exiting temporarily to DOS. As usual,
words in angle brackets indicate places where you must fill in the
actual value you want to use.

<drive letter:> changes the current drive. For example,


entering A: makes your floppy drive A the current drive,
CREATING CUSTOM DATA-ENTRY SCREENS AND APPLICATIONS 341

and entering C: makes your hard drive C the current


drive. Note that the letter must be followed by a colon.

• CD <path name> changes the current directory. For ex¬


ample, CD \LEARNFOX makes the LEARNFOX directory
the current directory.

• CLS clears the screen.


COPY does not give • COPY <file name> <file name> copies one file to another.
you any notice For example, COPY EMPLIST.DBF EMPLIST.BAK copies
before overwriting an
existing file. To be sure
your EMPLIST database file to a backup file named
that you do not overwrite EMPLIST.BAK. If a file with the name EMPLIST.BAK
an existing file, you can already exists, it is overwritten; if not, a new file with that
use DIR with that file
name is created.
name first: for example,
use the command DIR
• DIR [<file specification>] [/W] displays a directory listing of
EMPLIST.BAK to see if
that file exists before
files in the current subdirectory. If no file specification is
using COPY included, all files are listed. If a specification is included, only
EMPLIST.DBF matching files are listed. The specification may be a file
EMPLIST.BAK
name, to check if a single file exists, or it may include wild
cards to check for a category of files. The wild cards are *,
which matches any word, and ?, which matches any letter.
For example, DIR *.DBF will give a listing of all FoxPro
database files (which have the extension .DBF). You can add
/W at the end of this command to list the files across the
screen, instead of one above the other, and with less informa¬
tion, so you can see more file names.

• ERASE [<file specification>] deletes a file. The specification


may be a file name or may include the same wildcard charac¬
ters as DIR. For example, ERASE *.BAK will delete all files
that have the extension .BAK.

• MD <path name> makes a new subdirectory. For example,


MD \LEARNFOX creates the LEARNFOX directory under
the root directory (assuming there is not already a directory
with that name).

• PATH displays the current search path, the list of all the sub¬
directories that DOS looks in for commands that you enter.
342 MASTERING FOXPRO

CH. 9

• RD <path name> removes a subdirectory. A subdirectory


must be empty before you can use this command, and you
may not be in the subdirectory you are removing.

• REN <file name> <file name> renames a file. For example,


REN EMPLIST.DBF EMPLOYES.DBF changes the name of
the EMPLIST database file to EMPLOYES. Rename does
not work if there is an existing file with the same name; unlike
COPY, it will not overwrite a file.

• TYPE <file name> displays the contents of a file on the


screen. This command is meant to be used with text files,
which you can read when they are “TYPEd” to the screen.
It can be used with any file, though, even a program file:
though most of the content will be incomprehensible, any
text in the file will still be readable.

The second help screen of Shell commands includes database com¬


mands, some of which duplicate FoxPro commands and some of
which let you use FoxPro files in FoxView. This screen also includes
the commands that let you use the FoxView interface.
Commands that include an optional ALIAS clause can be used on
files that are not in the current work area: just add the letter repre¬
senting the work area they are in.

• APPEND <jxle name> [ALIAS <letter>] adds fields from a


database file into the currently selected database or adds text
from a text file. If no extension is given, FoxView assumes
the .DBF extension; if any extension except .DBF is given,
FoxView assumes that it is a text file. Database files are
added in the form of new fields; text files are added in the
form of text object.

• CREATE <file name> [ALIAS <letter>] creates a new data¬


base file with a .DBF extension.

• IMPORT <file name> [ALIAS <letter>] translates an exist¬


ing format file into a FoxView table. This command is used if
you created the screen format file by programming but now
want to change it using FoxView. Before using it, you must
CREATING CUSTOM DATA-ENTRY SCREENS AND APPLICATIONS 343

USE the appropriate database file or LOAD the correspond¬


ing FoxView table; then, if necessary, MAP the database file
being used to the screen design; finally, IMPORT the screen
format file. As a FoxPro program, the screen format file must
be an ASCII text file with the extension .FMT or .PRG.

• LIST [ALIAS <letter>] or LIST *.DBF displays a database


file’s structure.

• LIST *.NDX displays the key expressions of index files.

• LOAD <file name> lets you use a FoxView table that you
created and saved at an earlier time.

• MAP <Jile name> [ALIAS <letter>] is similar to APPEND,


described above, which lets you add fields from another data¬
base file or FoxView table to the table you are currently work¬
ing on. The difference is that MAP adds only the fields that
are different, while APPEND adds all the fields from another
database file even if they are duplicative.

• NEW <file name > clears FoxView of the screen you are cur¬
rently using and lets you begin work on a new screen. After it
is used, a dummy field called Noname is created, which can
be modified or deleted.

• SAVE <file name> saves the FoxView table that you are cur¬
rently working on.

• SELECT <letter> changes the current work area, like the


SELECT command in FoxPro.
• USE <file name> [ALIAS <letter>] loads an existing data¬
base file into FoxView.

• VIEW FILE lets you use the File View feature of FoxView,
which you can also access by pressing F9.

• VIEW FORMS lets you use the Forms View feature of Fox¬
View, which you can also toggle by pressing F10.

• VIEW TABLE lets you use the Table View feature of Fox¬
View, which you can also toggle to by pressing F10.
344 MASTERING FOXPRO

CH. 9

The third help screen includes utilities that sometimes make it eas¬
ier to use FoxView.

• <file name> [parameters] lets you run any .EXE, .COM, or


.BAT file from the FoxView Shell, just as you can from
DOS, simply by entering the file name.

• CONFIG <jile name> loads a new .CFG file. By default,


FoxView loads a file named FOXVIEW.CFG when you
start it, but you can change this file with a text editor and
create multiple .CFG files. See your FoxView manual for
more information on this advanced option.

• EJECT causes your printer to eject the current page. This


command is equivalent to pressing the Form Feed button on
your printer, except that you can do it from the computer
keyboard.

• EXIT lets you temporarily use the operating system. Because


FoxView remains in memory and simply adds a DOS shell
for you to use, you have less memory available than when
you are ordinarily using DOS, and some of your programs
may not work for that reason. When you are done working
from DOS, type EXIT again to return to FoxView.

• LIST STATUS displays technical information, including


FoxView flags, system memory, memory available to store
field values, and disk space.

• QUIT quits FoxView and returns you to FoxPro (if you ran
FoxView from FoxPro) or to DOS (if you ran FoxView as a
stand-alone program).

• RUN <file name> [<parameters>] lets you run a .COM,


.EXE, or .BAT file, like the RUN utility of FoxPro which
you have used.

• SAVCAP <file name> and SAVTXT <file name 3 let you


save an entire screen image or just the text on the screen. To
use these commands, press Ctrl-S while the screen that you
want is being displayed; then return to the FoxView Shell
and enter one of these commands with the name that you
want to give to the saved screen.
CREATING CUSTOM DATA-ENTRYSCREENS AND APPLICATIONS 345

• SET ALTERNATE TO <file name> and SET ALTERNATE


ON or OFF save all screen output from the Fox View shell in a
text file, like the same commands in FoxPro. First you must
use SET ALTERNATE TO to specify the name of the file that
output should be saved in. Then, use SET ALTERNATE ON
or OFF to activate or deactivate the feature. As in FoxView,
the default is off, so you must enter SET ALTERNATE ON
before the feature begins working.

• SET PRINT ON or OFF sends all Shell output to the printer,


like the same command in FoxPro.
• SET SAFETY ON or OFF can eliminate the warning message
that FoxView gives you before overwriting an existing file,
like the same command in FoxPro. The default for Safety is
on, and it is best to leave it on.

THE MENU SYSTEM


The most important Shell commands that are not DOS or FoxPro
commands can be accessed from the menu system, which can be
quite helpful for beginning users.

1. Press Esc to leave the help system and return to the Shell.

2. Press Esc to access the menu system. There are only four
choices on the menu bar, which you can move among by
using the left and right arrow keys. Use the arrow keys to
move to the Disk popup of the menu. Then press the right
arrow key to move among the other popups as you read the
descriptions of them below.

Not all the features of the menu system are essential: the most impor¬
tant are summarized at the end of this section.
The Disk popup, shown in Figure 9.5, includes the following
options:

• Directory: returns you to the Shell and lists the files in the cur¬
rent subdirectory. You may use a file name or a file name with
346 mastering foxpro

CH. 9

Caps-Ins

Directory listing using a filemask

It is possible to use Figure 9.5: The Disk popup.


other programs
from the DOS prompt, if
you have enough free
wild-card characters to list only some of these files, as in DOS;
memory for them, but these wild-card characters are described above, in the descrip¬
there is a danger of get¬ tion of the DIR command of the Shell. The advantage of this
ting lost. In fact, it is
command over DOS is that you can use the PgUp and PgDn
even conceivable that you
could enter FOXVIEW keys to scroll through the directory listing that it produces.
and start Fox View again
from the temporary DOS
• Shell Commands: returns you to the FoxView Shell.
shell that you are using
• Exit to DOS: lets you use DOS temporarily. After using the
from within Fox View.
You can get so lost that DOS commands that you need, enter EXIT at the DOS
you simply have to turn prompt to return to FoxView. Because FoxView remains
off your computer and in memory, this temporary DOS shell will not have as much
start again: for this rea¬
son, you should save your
memory available as your system ordinarily has, so it might
work before doing any¬ not be able to run all programs that you ordinarily run.
thing substantial from
DOS. • Run Program: lets you run any DOS program from within
FoxView, like the RUN utility that you have used in FoxPro.

• QUIT FoxView: returns you to FoxPro if you have started


FoxView from within FoxPro, or returns you to DOS if you
are using FoxView as a stand-alone application.
CREATING CUSTOM DATA-ENTRY SCREENS AND APPLICATIONS 347

Press the right arrow key to see the Load popup, shown in Fig¬
ure 9.6, which includes the following options:

5 Though FoxView
has such features as
• Current Alias: like the SELECT command that you have
used in FoxPro, changes the current work area. As you will
Current Alias to let you
see, you can also do this by moving the highlight in File
work with related files, it
is not really suitable for View, which lists all the work areas and open files.
working with relational
databases—as you will
see when you read the
next section, on Field Disk I Load Gen Fields JE : 16 a
R5
View. FoxVi Current Alias “TT
Load Table { . fV }
Save Table NONAME

MAP Datafile {■dbf}


USE Datafile (NONAME}

Append File { .dbf }


Import Format {.fmt}
New Config

Caps-Ins

Save current FoxView Table to disk

Figure 9.6: The Load popup.

• Load Table and Save Table: are used to work with the tables
that you create with FoxView. You will see in the section on
Forms View and Table View that these tables record the fea¬
tures of the custom screen that you design. Save Table lets you
save the features of the custom screen; Load Table lets
you work with a custom screen that you have designed at an
earlier time.

• MAP Datafile: an advanced feature that lets you add fields


from another existing database file to the current database
file. Note that it is better for beginners to set up the file struc¬
ture in FoxPro before going into FoxView. This feature was
348 MASTERING FOXPRO

CH. 9

described under the command MAP in the section on the


Shell commands above.

• USE Datafile: is used to work with FoxPro database files. By


default, Fox View starts you out with a table and database file
called Noname, which you can modify to create new hies.
For beginners, though, it is much easier to create and modify
hies in FoxPro before entering FoxView, and then to use
them by selecting Use Datable. As you will see, when you
load a database hie, FoxView creates a standard form for it,
which simply looks like the FoxPro Append or Change win¬
dow; FoxView also creates a table to describe this standard
form. You may rearrange it to create a custom form.

• Append File: like MAP Datable, an advanced feature that


lets you add helds from another existing database hie to the
current database hie. It is described under the command
APPEND in the section on the Shell commands above.

• Import Format: lets you import format programs that you


have written the code for, so you can modify them using Fox-
View’s form and table views. This is an advanced feature for
programmers, and it is described under the command
IMPORT in the section on the Shell commands above.

• New Config: an advanced feature that lets you change the


default conhguration of FoxView. It is described under
the command CONFIG in the section of the Shell commands
above.

Now press the right arrow key to move to the Gen popup, shown
in Figure 9.7. This is the working popup that you use to generate
programs.

• Template Directory: lets you specify which subdirectory Fox¬


View should look in for compiled templates.

• Specify Template: stores the name of the last template used so


you can reuse it easily.

• Select From Template List: lets you choose the template to use
from a menu of all the templates in the specihed directory.
CREATING CUSTOM DATA-ENTRYSCREENS AND APPLICATIONS 349

Disk Load | Gen , I Fields 10:16 am

FoxView C:> Template Directory {C:\FOXPRO\TE}


Specify Template {)
Select From Template List

Author {Charles Nava)


Copyright {SYBEX }
Memory Variables

► SET COLOR TO
► Products

Caps-Ins

Select from templates in the template directory

Figure 9. 7: The Gen popup.

• Author and Copyright: let you enter the name of the program
author and copyright holder of the programs you generate
using FoxView, which are included in the programs before
the code begins (though they do not appear on the screen). If
you entered your name and company name when you
installed FoxView, they are entered as the default values
here, and you can use these options to change them.

• —Memory Variables: if this option is on, the generated pro¬


grams will place data in memory variables, like FORMS2,
which was discussed at the beginning of the chapter.

• SET COLOR TO and Products: are not generally necessary.


For more information on these options, see pages 4-15
through 4-19 of your FoxView-FoxCode-FoxDoc user’s manual.

Press the right arrow key to move to the Fields popup, which is
shown in Figure 9.8. This popup controls relatively minor features of
the screen display and is not essential to using FoxView:

Fill Char: lets you fill the spaces between the field labels and the
fields themselves with some character, for example, with dots.
m
Disk Load Gen 10 16 a!u

FoxView C:>

Caps-Ins

Video attribute used on SELECTed fields

Figure 9.8: The Fields popup.

• Prompt Lines: lets you remove the FoxView prompt line


from Forms View.

• Select Attribute: controls video attributes of fields.

• Height of Box and Width of Box: control the default size used
for drawing boxes. As you will see, boxes are easy to resize,
and there is not much need to worry about their default size.

• Box String: three choices that control which ASCII charac¬


ters are used to draw boxes. For more information on these
options, see pages 7-4 to 7-6 of your FoxView-FoxCode-FoxDoc
user’s manual.

If you look back over all the features of the menu system, you will
see that only a few are needed to start working with FoxView. To
make it easier for you to get underway, the essential features are
listed below:

• from the Disk menu: Quit to leave FoxView

• from the Load menu: Use Datafile, Load Table, and Save Table
to create, use, and save FoxView custom screens
CREATING CUSTOM DATA-ENTRY SCREENS AND APPLICATIONS JJ 7

• from the Gen menu: Select From Template List to select the tem¬
plate that you want to use to generate the program

If you go back and review these features in the lists above, it will be
easy for you to find your way around the menu system while you are
working.

FILE VIEW
Before looking at File View—and before looking at Forms View
and Table View in the next section, you should use your EMPLIST
database:

1. Use the arrow keys to move to the Load popup. Select USE
Datafile. A prompt will appear on the bottom of the screen
with the name of the current directory followed by the file
name NONAME.DBF. Press End; then press Backspace to
delete this file name, but be careful not to delete the directory
name or the backslash immediately preceding the file name.
Then type EMPLIST. as the file to use; its name will appear
on the menu popup as you type. Press Enter to use the file.

2. Press F9 to toggle to Database File View, shown in Fig¬


ure 9.9. As you can see, this gives you summary information
about the file that you are using.

3 Press F9 again to toggle to Alias File View, shown in Fig¬


ure 9.10. Press F9 again to toggle back to Database File
View.

The Database and Alias screens of File View look very impressive,
since they let you keep track of multiple database files and set relations
between them. Unfortunately, FoxView supports only one-to-one rela¬
tions and not one-to-many relations; so it cannot be used to generate
code for true relational databases. As you learned in Chapter 7, if data
has a one-to-one relation, it is best to put it into a single file.
In practice, in most applications, FoxView’s File View feature just
serves as a simple reminder of basic facts about the file you are using.
352 MASTERING FOXPRO

CH. 9

I:; EMPLIST . DBF 10 17 a

- ~r ~ “T
l _ TTTTTJ
r
ITTT TT UA1ADMol FILES n TT n
TT V It 1 TT n
-
Als Datafile Allas User DBT Fids Recsiz Ndxs Reis Updated _

- A EMPLIST j [ ] yes 12 120 0 0 02/02/91 —


- B [ ] [ 3 —
0 0 0 0 -
- C [ ] [ 3 —
0 0 0 0 -
_
D [ ] [ 3 — 0 0 0 0 -
“ E [ i [ 3 —
0 0 0 0 -
- F [ i [ 3 — 0 0 0 0 -
- G [ j [ 3 — 0 0 0 0 -
- H [ ] [ 3 — 0 0 0 0 -
I [ ] [ 3 — 0 0 0 0 -
~ J [ ] [ 3 —
0 0 0 0 -
MEM [ i [ 3 0 0 0 0
- -

_ niTiiii rrn m j nil n mi rim i itttm t iiii i i iiii in..i 11111 n n m m biiill
Caps-Ins
C:\LEARNFOX\EMPLIST.DBF
FoxPro database file

Figure 9.9: Database File View.

C : EMPL1ST.DBF 10:17

■ j';
M L _L M o M
- 1

SET INDEX TO SET RELATION TO


#. INDEX Key Expression Typ Data User RelExp Alias Lnk
1 . ■3 [ 3 c - [ 3 t 31 ] -
2. [ ][ 3 c - [ 3 [ 3[ ] -
3 . [ ][ 3 c - [ 3 t 3C ] -
4 . [ 3 [ 3 c - [ 3 [ 3[ ] -
5. [ ][ 3 c - [ 3 [ 3[ 3 —
6 . [ 3 [ 3 c - C 3 [ 3C ] -
7. t 3 [ 3 c - [ 3 [ 3[ ] -
8. [ 3 [ 3 c - [ 3 [ 3C 3 —
9 . [ ][ 1 c — [ 3 [ 3[ ] --
10. [ ][ ] c - [ 3 [ 3[ ] -

inn u ii ii 11 i rTTTTTTTTi'~rnTT rrrn n 11 n 11 iTTTTmTrrrnTTi i m 11111 n 111111


Caps-Ins

FoxPro index file

Figure 9.10: Alias File View.


CREATING CUSTOM DATA-ENTRY SCREENS AND APPLICATIONS 353

FORMS VIEW AND TABLE VIEW


Forms View and Table View are the essence of Fox View. They
are the features you actually use to set up data-entry screens.
Forms View is a screen painter. It lets you rearrange the fields in
your database file and add text and graphics, in order to create a
screen which is attractive and easy to use. When you are using Forms
View, the fields, text, and boxes are all objects, and you can move
them easily. The object that is selected is underlined or highlighted,
and the arrow keys are used to move from one to another. The most
important keys for manipulating objects are

• F3: lets you drag (move) the selected object by using the
arrow keys

• F4: lets you resize the selected object by using the arrow keys
(which is useful primarily for boxes)

• Ctrl-C: centers the selected object

• Ctrl-U: deletes the selected object (after asking the user for
confirmation)

• Ctrl-B: adds a box object, which you may then drag and
resize

• Ctrl-N: adds a text object

• the space bar: lets you edit a text object

You use these keys to change the screen in Forms View, to “paint” it
with the data-entry form you want.
Table View is a tabular description of the screen shown in Forms
View: the data in the table changes as you change the form. In addi¬
tion, Table View has columns that let you validate data, as you will
see. Before quitting FoxView, you can save the table.
When you start work with FoxView, you can either use a database
file or load a table that you have previously saved; both of these can be
done with the menu system. If you use a database file, FoxView auto¬
matically creates a standard form for it (which looks like the usual
Change or Append window) and a table that summarizes this standard
form; you begin designing your custom screen from this point. If you
354 MASTERING FOXPRO

CH. 9

load a table that you saved, of course, Fox View displays the correspond¬
ing screen and lets you begin your design work from this point.

1. Press F10 to toggle to Forms View, shown in Figure 9.11.


Since you made the menu choice to Use EMPLIST.DBF
earlier, you begin with the standard data-entry form—
similar to the Change or Append window of FoxPro except
that you can rearrange it.

2. Press F10 again to toggle to Table View, shown in Fig¬


ure 9.12. Keep pressing F10 to toggle between Form and
Table View: compare the two screens to see that Table View
describes the form shown in Forms View. For example, in
Table View the Empno field has 2 under Row and 0 under
Col; correspondingly, in Forms View the Empno field is in
Row 2, Column 0 of the screen.

3. To see the features that you use to validate data, toggle to


Table View. Press the right arrow key until you can see the
columns named Picture and Range.

C:EMPLI ST.DBF @2,0 Page: 1 10 18 ad

Empno
Fname
l name
Address
Apt_no
City
State
Zip
Date_hired
Wage
Probation
Notes

Caps-Ins

Figure 9.11: Forms View.


CREATING CUSTOM DATA-ENTR YSCREENS AND APPLICATIONS 355

C:EMPLIST.DBF

#. Als Field Typ Wid Dec Label Hue Row Col Pag (Fid)
BPf
(Atr) Place
1 . A Empno | C 3 [Empno A 2 0 1 GET 112 SIDE
2. A Fname c 13 [Fname 4 3 0 1 GET 112 SIDE
3. A Lname c 20 [Lname 4 4 0 1 GET 112 SIDE
4 . A Address c 25 [Address 4 5 0 1 GET 112 SIDE
5. A Apt no c 5 [Apt no 4 6 0 1 GET 112 SIDE
6 . A Ci ty w 20 [City 4 7 0 1 GET 112 SIDE
7. A State c 2 [State 4 8 0 1 GET 112 SIDE
8. A Zip c 5 [Zip 4 9 0 1 GET 112 SIDE
9. A Date hired D 8 [Date hired 4 10 0 1 GET 112 SIDE
10. A Wage N 5 2 [Wage 4 11 0 1 GET 112 SIDE
1 1 . A Probation L 1 [Probation 4 12 0 1 GET 112 SIDE
12 . A Notes M 10 [Notes 4 13 0 1 GET 112 SIDE

pan
Uapo Tno
XII q

FIELD: can be up to 10 alphanumeric characters and underscore

Figure 9.12: Table View.

Advanced FoxView users can edit the Table View screen. The
only features of Table View that are useful for beginners, though, are
those concerning the validation of data. For example, if the user
enters data that does not match the criterion, you can have FoxPro
beep and refuse to accept the entry.
Rather than memo¬ The Picture column lets you enter a picture template, similar to
rizing these picture
those you used to format report fields in Chapter 6 (and summarized
templates, use the Fox-
View help facility: just in Table 6.2). Figure 9.13 shows the FoxView help screen for entries
press FI when the cursor that you can make in the Picture column.
is in the Picture column.
Most picture templates screen out invalid data: for example, 9
At this point, all you need
is a general idea of what accepts only digits. Some convert data: for example, ! converts a char¬
picture templates can do; acter to uppercase. You can also use literals in picture templates—for
you do not need to learn
example 999-99-9999 for the entry of Social Security numbers. Repeat
the exact symbols and
syntax.
the symbol as many times as you want the character to be entered (for
example, X99 lets the user enter an employee number comprising a
letter followed by two digits) or use the symbol @ before the symbol to
indicate that it is repeated an indefinite number of times (for example,
@! capitalizes any number of characters entered in the field). Tem¬
plates that begin with @ are sometimes called function templates. Pic¬
ture templates and function templates will be discussed in more detail
in Chapter 10. ,
356 MASTERING FOXPRO

CH. 9

110 18 a rti

Picture Range Valid Init Calc User


][ If If If ]
][ ][ ][ ][ 1
][ ][ ][ ][ ]
J[ ][ ][ ][ 1
If Jf ][ 3E ]
][ ]f ][ H ]
][ ][ ][ ][ 1
Jf. ][ ][ ][ ]
][ ][ ][ ][ ]
n ][ ][ ][ ]
][ ][ If If ]
][ If ][ ][ ]

—-r--- -Caps-Ins

PICTURE: <clause> of functions and templates: press FI for Help

Figure 9.13: Picture templates.

To use the Range column, just enter two values separated by a


comma: the user will only be able to enter values between these two.
There are a few additional features which are not as important but
which you might find useful on occasion. The Calc column lets you
create a calculated field. The Valid column lets you enter a list of
values (separated by commas) which the entry must match. The Init
column makes an initial value appear in the field for the user to
confirm or change.

GENERA TING
A CUSTOM DATA-ENTRY FORM _
After this introduction to FoxView, it should be easy for you to
become accustomed to using this program by doing a couple of
exercises.
First, you will learn to create custom data-entry forms. You will
begin with the standard form, which looks like the FoxPro Append
window. Then you will rearrange the fields of the database file so that
they are easier for the user to understand, change the field names to
more descriptive names, add instructions that tell the user exactly
CREATING CUSTOM DATA-ENTRY SCREENS AND APPLICATIONS 357

what to do, and include graphic characters such as boxes to make the

D To return to the
usual Append or
screen easier to grasp.
The format screens that FoxView generates are meant primarily to

Change window, enter


be used in programs. Most FoxView programs have a .PRG exten¬
the command SET FOR¬ sion; but format files may include only certain commands that are
MAT TO without any used to describe the screen, and they have an .FMT extension. Once
file name following it.
you have created an .FMT file, you can use the command SET FOR¬
MAT TO <fmtfile name>. Then, any time that you use the command
APPEND or CHANGE, FoxPro will display the custom screen

D Since a format file


is used through the
instead of the standard Append or Change window.
These format hies are very convenient for programmers. You can

setup dialog box, it can


imagine that, rather than writing programming code to describe the
also be used through the different screens that you need, it is easier to have a collection of a few
View window. Thus, it .FMT hies so that you can just set the format to one or another as you
can also be saved as one
write your program. They can also be used from FoxPro’s Setup dia¬
of the settings in a
.VUE file. ' log box or the Command window, though, and after you are done
generating this .FMT hie, you will test it in this way.

LAYING OUT THE DATA-ENTRY FORM


To begin with, you must lay out the data-entry form. You work in
Forms View, using the techniques that were summarized earlier to
rearrange helds, draw boxes, and add help text, until you have a
screen that is easy to use.

1. Press F10 until you have toggled into Forms View.

2. If you have not yet loaded the EMPLIST database hie, the
screen will have only one held, called NONAME. To load the
database hie, press Esc to use the menu. From the Load popup,
select USE Datafile. FoxView displays the current name of the
hie at the lower left of the screen: the full path name, ending
with NONAME.DBF. To edit it, press the End key, then press
Backspace until you have erased the current hie name, NO¬
NAME. DBF, but not the backslash before it; then type
EMPLIST and press Enter. (FoxView assumes the .DBF
extension.) The screen now looks like Figure 9.14, with the
helds arranged in much the same way they are in FoxPro’s
Change window.
358 MASTERING FOXPRO

CH. 9

Figure 9.14: The initial data-entry form.

3. Edit the labels of the fields to make them more explicit. The
word Empno has a flashing cursor under it to indicate that it
is selected. Press the space bar to edit this label: the cursor
appears on the edit line at the bottom of the screen. Press the
right arrow key three times to move the cursor to the n in
Empno, and type loyee followed by a blank space. Notice
that, as you type, the label changes on the screen above.
Then press the right arrow key to move the cursor to the o of
no, and press the Ins key to toggle to typeover mode. Type
umber, and press Ins again to toggle back to insert mode.
Press Enter to stop editing and return the cursor to the label
on the screen above.

4. Press the down arrow key to move the cursor to the next field
name, Fname, and press the space bar to edit it. Change it to
First name. Notice that there are a number of blank spaces
between the label and the field in the screen above: press End to
move to the end of the edit line, and you will see that the blanks
are there too. Press Backspace to remove all these blank spaces
except one, and then press Enter.

5. Go through all the field names in the same way. Edit them to
remove unnecessary blank spaces, so there is just one space
CREATING CUSTOM DATA-ENTRY SCREENS AND APPLICATIONS 359

between the label and the held name. In addition, change


Lname to Last name, change Apt no to Apartment, change Date
hired to Date hired, and change Probation to Probation? (t/f).
The screen should now look like Figure 9.15.

C:EMPLIST.DBF 13,0 Page: 1 10:23 PIT


Employee number
First name
Last name
Address
Apartment
City
State
Zip
Date hired
Wage
Probation? (t/f) [j
Notes JJJjsJiE

Ins

Figure 9.15: The screen with labels edited.

6. Assume that you do not want the data-entry person adding


notes to your memo hie, but you still want to retain it for your
own use. Delete the Notes held from Forms View by moving
the cursor to Notes, pressing Ctrl-U to delete the held, and
pressing Y to conhrm the deletion. The held will disappear
from Forms View (and from Table View as well, as you will
see shortly), but remains untouched in your actual database
hie, as does everything else you are modifying for Forms and
Table View.

7. The screen still looks more cluttered than it was before, but
now you are ready to rearrange the helds to make it easier to
read. Move the cursor to Last name and press F3 to drag it:
notice the help line at the bottom of the screen, shown in Fig¬
ure 9.16. Follow its instructions to rearrange the helds to look
like the screen shown in Figure 9.17. For example, press the
right arrow key to drag the held until it is at the right edge of
360 MASTERING FOXPRO

CH. 9

C:EMPLIST.DBF 4,0 Page: 1 10 40 am

Employee number
First name
Last name
Address
Apartment
City
State
Zip
Date hired
Wage
Probation? (t/f)

Ins

DRAG: move selection with the cursor keys; RETURN finishes

Figure 9.16: The help line tells you how to drag a field.

C:EMPLIST.DBF 11,50 Page: 1 10 28 a

Employee number

First name Last name

Address Apartment

City State ■■I

Date hired Wage Probation? (t/f) Q

Ins

Figure 9.17: The new arrangement of the fields in Forms View.


CREATING CUSTOM DATA-ENTRY SCREENS AND APPLICATIONS 361

the screen: line up its right edge with the right edge of the
time display, which is in the upper right corner of the screen.
Press Enter to stop dragging and to keep it there. Use the
same method to rearrange the other fields as shown.

8. Press F10 to toggle to Table View. Note that the Row and Col
numbers in the table have changed to reflect the new positions
of the fields, and that the labels have changed, even though the
field names remain the same, as shown in Figure 9.18. Notice
also that the Notes field has been removed from this view as
well. Press F10 to toggle back to Forms View.

C:EMPLIST.DBF

#. Als Field Typ Wid Dec Picture Range Valid Inlt Calc User
1 A Fmpno C 3 [ [ H [ ][
2. A Fnamo C 15 [ L ][ [ ][
3. A L name C 20 [ t JL [ ][
4. A Address C 25 [ [ JL [ ][
5. A Apt_no C 5 r t ][ [ ][
6. A City C 20 i: [ H [ ][
7. A State C 2 r [ J[ [ ][
8. A Zip C 5 f [ ][ [ ][
9. A Date_hired D 8 [ [ ][ [ ][
10. A Wage N 5 [ [ ][ [ ][
11 . HI Probation L 1 c [ ][ [ JL _

Ins

ALIAS: character in the range A..j (Field) or M (Memvar)

Figure 9.18: The new arrangement of the fields in Table View.

You now have a fairly clear and easy-to-read data-entry screen. In


a more complex application, you might want to group fields by put¬
ting boxes around them. But for a typical database like this, skipping
an extra line to separate the name and address from the information
on employment, as you have done, is sufficient.
Now, all you need to do is add some instructions for the data-entry
person. In the next exercise you will add very brief and simple
362 MASTERING FOXPRO

CH. 9

instructions, because you will use this same data-entry screen later in
this chapter for the menu-driven application, which has instructions
built in. In an actual application, of course, you could give more
elaborate help to the data-entry person.
The on-screen help that you add will consist of a few text objects
surrounded by a box:

1. Before adding help for the data-entry person, draw a box for
the help lines. Press Ctrl-B to call up the Select Box menu
popup. Press the down arrow key three times to select Box-
Stringl, and press Enter. The box is placed and is high¬
lighted to show that you can now drag it into place. Press the
down arrow key a few times, until it is below all the field
names, and the left arrow key until it is near the left margin,
and then press Enter.

2. Now, resize the box so it can hold the information. Press F4


to resize. Press the right arrow key to make the box large
enough to fill almost the entire width of the screen. Press the
up arrow key once to make it the right height. Now that it is
the size you want, you can center it precisely: press Ctrl-C to
center the box.

3. Press Ctrl-N to add a text object. Drag it right slightly so it is


no longer overlapping with the box. Press Enter. Press the
space bar to edit the text object. Type the first help line:

<- - > : Move Cursor Within Field


then press Enter. Press Ctrl-N to add another text object,
and press the space bar to edit it. Type

Tab Shift-Tab : Move Cursor To Next Or Preceding Field


and press Enter.

4. Now, double-space these text objects. You should still be on


the last one. Press F3 to drag it; press the down arrow key
once; press Enter.

5. Finally, center the help lines. Press Ctrl-C to center the cur¬
rent one. Press the up arrow key and then press Ctrl-C
to center the upper one. The screen should now look like
Figure 9.19.
CREATING CUSTOM DATA-ENTRY SCREENS AND APPLICATIONS 363

C:EMP L1ST.DBF @ 15,24 Page: 1 10 50


Employee number

First name Last name

Address Apartment H9HH

City State Zip —i

Date hired Wage Probation? (t/f) Q

<- -> : Move cursor within field

Tab Shift-Tab : Move from field to next or preceding field

-Ins

Figure 9.19: The data-entry screen with help.

VALIDA TING DA TA
That finishes the design of the data-entry screen. Now you can use
Table View to add picture templates to a couple of fields. As an exercise,
you will add picture templates to capitalize the first and last names as
they are entered and to make sure that only numbers are entered in the
zip code field. Remember that, in the early parts of this book, you
always had to worry about names that were added in small letters.
Though users were supposed to enter all the names in capital let¬
ters, there were inevitable errors, and you had to write your queries
using the UPPER() function to correct for them. In a program, it
makes sense to use the picture function to capitalize all the names auto¬
matically as they are entered, so that you do not need to allow for pos¬
sible errors in all the rest of your code.
You will also validate the amount of the wage. Assuming that the
wage must be between $4.00 and $50.00, you can add these figures
in the Range column of the Wage field, to make sure that the data-
entry person cannot enter wages that are outrageously incorrect.
You would probably do more validation in an actual application—
for example, you would probably want to capitalize more fields, to
give a range for the date hired, and to validate the employee number
364 MASTERING FOXPRO

CH. 9

by using the template X99—but a few examples are enough in an


exercise.

1. Press F10 to scroll to Table View. Press the up arrow key to


move the highlight to field number 2, Fname. Press the right
arrow key to move to the Picture column. Type @! and press
Enter. Press the down arrow key once to move to the Lname
field; type @! again, and press Enter. Press the down arrow
key until you move to the Zip field. Type 99999 and press
Enter.

2. Press the right arrow key, and then the down arrow key twice
to move to the Range column for the Wage field. Type 4,50
and press Enter. Figure 9.20 shows the Table View with
these entries. Now you can press F10 to toggle back to Forms
View: notice that there is no indication of the templates or
range you entered.

10 51 ai

u. Als Field Typ Wid Dec Picture Range Valid Init Calc User
1. A Empno C 3 [ ][ ][ ][ ][ ][ ]
2. A Fname c 15 [®! ][ ][ ][ ][ H ]
3. A Lname c 20 [#! ][ ][ ][ ][ ][ ]
4. A Address c 25 [ ][ ][ ][ ][ ][ ]
5. A Apt no c 5 [ ][ ][ ][ ][ ][ ]
6 . A City c 20 [ ][ ][ ][ ][ ][ ]
7. A State c 2 [ ][ ][ ][ ][ ][ ]
8. A Zip c 5 [99999 ][ ][ ][ ][ ][ ]
9 . A Date_hired D 8 [ ][ ][ ][ ][ ][ ]
10. A Wage N 5 2 [ ■114,50 |][ ][ ][ ][ ]
11 . A Probation L 1 [ ][ ][ ][ ][ ][ ]
12 . A BOXOBJECT B 72 4 [ ][ ][ ][ ][ ][ ]
13 . A TEXTOBJECT T 32 [ ][ ][ ][ ][ ][ ]
14 . A TEXTOBJECT 1 58 [ ][ ][ ][ ][ ][ ]

Ins
4.50
RANGE: (lower exp>,(upper exp>; press FI for Help

Figure 9.20: Entries in the Picture and Range columns to validate data.

GENERA TING AND TESTING THE PROGRAM


Assuming that you now have all the features that you want in your
data-entry screen, you can generate the programming code needed
CREATING CUSTOM DATA-ENTRYSCREENS AND APPLICATIONS 365

to create the format screen. Then you can quit FoxView and use Fox¬
Pro to test the screen.

1. Press Esc to access the menu. From the Gen popup, select
Select From Template List. The template list appears, as in
Figure 9.21. (Of course, yours may have added templates.)
Move the highlight to FORMS 1: Format File Generator and
press Enter. The program asks for the name of the file that
will be generated. Type DATAENTR and press Enter. The
program file scrolls by as it is created, and then the message
Program File(s) Created appears at the bottom of the screen.

C:EMP LI ST.DBF 11,34 Page: 1 10:44 a

ADVANCED | FoxPro Advanced Application V ___I


APPS1 File-Maintenance Application
F0RM1 Format File Generator
F0RM2 Driver with FORM/SAYS/GETS/STOR/REPL procedure file
REP01 Report Format File Generator
SIMPLE Simple Database Application

Ins

Select Template Program with the cursor keys; RETURN accepts

B ln an actual applica¬
tion, you might
have more than one table Figure 9.21: The list of available templates.
for the same database file.
If so, you should choose
2. Before exiting, save the table in case you want to reuse and
descriptive names for
them all, rather than modify it at some later time. From the Load popup, select
accepting FoxView’s Save Table. FoxView will suggest the name EMPLIST.FV;
suggestion of using the press Enter to accept that name. Now, from the Disk popup,
file name for the name of
select QUIT FoxView and press Enter. Type y to confirm
the first table. When you
enter a new name, it is that you want to quit and to return to FoxPro.
not necessary to add the
.FV extension: FoxView
3. Use the EMPLIST file by selecting Open from the File
assumes it. menu, and then when the Open dialog box appears, select
366 MASTERING FOXPRO

CH. 9

EMPLIST.DBF from the scrollable list of database files (or


use USE EMPLIST if you want to work from the Command
window). Then select Setup from the Database menu to use
the Setup dialog box, and check the Format check box. The
Set Format dialog box will appear: it looks just like the Open
dialog box. Select DATAENTR.FMT from the scrollable
list. FoxPro automatically compiles this DATAENTR pro¬
gram before using it the first time, and its name appears to
the right of the Format check box of the Setup dialog box
to indicate that it is active. Select OK. (Working from the
Command window, you would simply enter SET FORMAT
TO DATAENTR.) Now, to get the Command window out of
the way, select Hide from the Window menu. Finally, select
Append from the Record menu. The new data-entry screen,
as shown in Figure 9.22, is ready for use.

4. If you want, you can try paging through the database or adding
records using the custom screen. As a test, move the cursor to
Zip and try entering the letter g. FoxPro will beep, as the tem¬
plate you have implemented allows only numbers. Move the
cursor to Wage. Type 60 and press Enter. FoxPro beeps and
displays an error message saying you are out of Range.

Employee number

First name Last name mHIH

Address Apartment

City State ^ Zip BHII

Date- hired Wage Ht'/W'/To] Probation? (t/f) Q

<- -> : Move cursor within field

Tab Shift-Tab Move from field to next or preceding field

Figure 9.22: Using the custom screen for data entry.


CREATING CUSTOM DATA-ENTRY SCREENS AND APPLICATIONS 367

5. Press Esc to end data entry. Select Window Command to call


up the Command window, and enter CLEAR to get rid of the
custom data-entry screen. Enter DISPLAY (or DISP) to see if
a new blank record has been added. If so, enter DELETE to
get rid of it. You should then enter SKIP - 1 and enter DISP
again to see if you added more than one blank record; if so,
delete it too. When you finally find a record that is not blank,
enter PACK to finalize the deletions.

6. To get rid of the format setting so you can return to normal


data entry, enter the command SET FORMAT TO. As a test,
enter the command APPEND to ensure that you are back to
the usual Append window, not the custom screen. Close the
Append window without appending a new record.

As you can see, once you have done the work of designing the
screen, generating the program is easy.

GENERA TING ANAPPLICA TION _

It is not much more trouble to create an entire menu-driven appli¬


cation with FoxView than it is to create a data-entry form. In this sec¬
tion, you will use the APPS1 template to generate a menu-driven
system that lets the user do all the basics of maintaining the data, such
as adding and editing data and producing reports and mailing labels.
Before you use APPS1, you must create the data-entry screen and
also create report and label forms. FoxView will tie all of these
together with a menu. If you were starting from scratch, you would
first have to analyze your requirements. Then you would use your
analysis to create a new database file, data-entry screen, report form,
and label form.
In this example, you will simply use the data-entry form that you
just created. FoxView will automatically use the report and label
forms that you created in Chapter 6, since they are still in the current
(\LEARNFOX) directory. Thus, this application will do most of the
things that you would ordinarily do yourself with this database file:
even a data-entry person who knows nothing about FoxPro can
368 MASTERING FOXPRO

CH. 9

maintain the database and produce reports and mailing labels simply
by making the appropriate menu choices.

1. Select Program FoxView or enter FOXVIEW in the Com¬


mand window. Press Enter to proceed to the FoxView Shell.

2. First, you must use the table you created earlier. Press Esc to
use the menu system. From the Load popup, select Load
Table. The prompt appears at the bottom of the screen: enter
the name EMPLIST. (FoxView assumes the .FV extension.)

3. Now, you can generate the application. From the Gen popup,
select Select From Template List. When the list appears, se¬
lect APPS1: File-Maintenance Application. FoxView will ask
for the name of the program it should generate. Enter EM¬
PLOYEE. When FoxView asks if you want Special Features,
type n. When it asks about modules, type n. When it asks for
menu style, select Simple. When it asks for submenu style,
select Bracketed. The code scrolls by as it is generated. Notice
that a number of programs are created, each with the same
heading at the top (including your name, if you entered it when
you installed FoxView). Finally, FoxView displays a message
saying Program Files Created.

4. If necessary, press Esc to call up the menu. From the Disk


popup, select QUIT FoxView. Type y to confirm that you
want to quit and to return to FoxPro. In the FoxPro Com¬
mand window, enter DO EMPLOYEE. FoxPro automati¬
cally compiles the code the first time you use it: the bar
indicates how much of it has been compiled. Notice that it is
actually a number of different program files that work
together, all of which must be compiled.

5. Finally, FoxPro displays the menu screen shown in Fig¬


ure 9.23, which makes the regular functions of editing, creat¬
ing labels and reports, and so on, so obvious that anyone can
do it. To test the program, type 3 to select Edit. It uses the
screen-format file you created earlier (which is the table you
loaded before generating this program) as the editing screen,
with the extra help lines that are built into this application, as
CREATING CUSTOM DATA-ENTRY SCREENS AND APPLICATIONS 369

EMPLOYEE MAIN MENU

0. Quit
1 . Append
2. Browse
3. Edit/View
4. Help
5. Labels
6. Pack
7. Report

U=- select : : -

a Like most complex


programs, this one
is broken up into several
modules. Each module is
in a separate program
file, and FoxPro automat¬
ically compiles each of
Figure 9.23: The menu of the application you have generated.
these the first time you
use it. Thus, while you
are testing, the program
will be interrupted several
in Figure 9.24. (Note that the help line’s Return button
times while different means that you should press Enter—in other words, carriage
modules are compiled. return—when you have finished editing this record.)
Once you have tested
every feature of the menu 6. Try testing other features of the menu if you want. Then type
system, it will be com¬ 0 at the Employee Main Menu to return to FoxPro when you
pletely compiled, and
there will be no more
are done.
interruptions of this sort.
There might be one or two features of this menu system that
require a couple of minutes of training. For example, you know what
the Pack option does, but a data-entry person probably would not.
Beyond that, you would have to tell the data-entry person either to
enter DO EMPLOYEE to call up the main menu or to select Do from
the Program menu and select EMPLOYEE.PRG from the list of
program names. As you will see in the next chapter, DO is the Fox¬
Pro command that runs a program. Nevertheless, the program is
simple enough that a data-entry person with only minimal training
could now do the basic work of maintaining your database.
In these exercises, you did the relatively simple job of generating a
menu system to tie together the database file, the report, and the label
370 MASTERING FOXPRO

CH. 9

Record: 000001 02/07/91

Employee number an

First name AUDREY Last name

Address 318 B. 31 St. Apartment

City Far Rockaway State [EH Zip 11600

Date hired 07/16/81 Probation? (t/f) [§

<- -> : Move cursor within field

Tab Shift-Tab : Move from field to next or preceding field

EDIT/VIEW: (E)dit <F)ind {G}oto (L)ocate <Del>


{N)ext-record {P)rev-record <Return>

Figure 9.24: Editing with the application.

that you created earlier. You could also use the application genera¬
tor, though, if you were called in as a developer to create a database
system from scratch. Then you would have to do the more difficult
job of analyzing the user’s needs, and of designing the database file,
data-entry screen, and report and label forms accordingly. When
you do this sort of thing, you are almost a programmer, since analyz¬
ing the system’s requirements in this way is often the most difficult
part of programming.
Many modules that
In the next chapter, you will begin doing actual programming. If
FoxView generates
begin with the first three
you want to get more experience with the application generator first,
letters of the application ■ try selecting the ADVANCED template (just as you selected the
name, as in EMP_EDIT APPS1 template in this section) to generate an application with pop¬
and EMP_PACK. So
these files are not over¬
up menus. But give the program a different name, so the files it
written, make sure the creates do not overwrite the files in the EMPLOYEE application you
name of the new applica¬ just created. You will see that the data-entry screen you have
tion begins with different
designed looks awkward in combination with pop-up menus, and
letters than EMP.
you might want to design a new one.
hapter 10
Expanding Your Capabilities
through Programming
To write a structured program, 378
break down the program into separate modules (or procedures)
and use only three types of control flow: sequence, selection,
and iteration (or looping).

To create a FoxPro program file, 382


write the code in a plain ASCII text file (sometimes called a
DOS file), with a carriage return at the end of each line of code.

To add comments to the program, 383


use * or NOTE at the beginning of a line or && anywhere in a
line. Anything to the right will be ignored by FoxPro: it is a com¬
ment to make the program more comprehensible to people who
read it.

To do formatted input/output, 394


use one or more commands in the form @ < row >, < col-
umn> [SAY <exp>] [GET <variable>] followed by the com¬
mand READ. The expression following SAY is displayed at the
row and column specified; the variable following GET is dis¬
played to its right, in enhanced display. This variable must be
defined before you execute this command. When FoxPro
reaches the command READ, it lets the user edit all the vari¬
ables in preceding GET clauses that have not yet been edited.

To format the input/output in an @ . . . SAY . . . GET command, 396


use a PICTURE clause including a picture template or func¬
tion. To determine the range of entries that will be permitted,
use the word RANGE followed by two values separated by a
comma.
To execute the same code repeatedly, 401
use the command DO WHILE <logical exp> followed by the
code, followed by the command ENDDO. When the program
reaches ENDDO, it returns to DO WHILE and evaluates the
logical expression again: this is known as looping. The code will
be repeated as long as the logical expression is true.

To loop through a database file, 406


use a loop based on the expression DO WHILE .NOT. EOF().
This loop must have the command SKIP in it, so that after you
have gone through all the records, EOF() becomes true and the
loop is not executed again.

To select between two blocks of code, 407


use the command IF < logical exp>, followed by one block of code,
followed by ELSE, followed by the second block of code, followed
by ENDIF. If the logical expression is true, the first block of code
will be executed; if not, the second will be executed. (You can also
use IF <logical exp>, followed by a block of code, followed by
ENDIF. If the logical expression is true, the code will be executed;
if not, nothing will be done.)

To select among many blocks of code, 411


use the DO CASE . . . ENDCASE command. Between these
two, you can use the command CASE <logical exp> followed
by a block of code any number of times. FoxPro will execute the
code of the first CASE whose logical expression is true. You can
also add the command OTHERWISE followed by a block of
code after the final CASE, and this code will be executed if
none of the CASE statements are true.
378 MASTERING FOXPRO

CH. 10

THIS CHAPTER IS A GENERAL INTRODUCTION TO


computer programming using FoxPro as an example. It will teach
you the basic commands that FoxPro programmers use to interact
with the user and to organize the flow of their programs. At the same
time, it will use these commands to teach you the basic principles that
apply to any programming language.
Many people believe that the FoxPro/dBASE language is the best
introduction to computer programming. It has the usual features of
most programming languages, but it also has special features that will
let you set up genuinely useful database-management systems not
long after you begin learning.
When you learn most programming languages, you have to work
on trivial exercises until you have mastered the language. You gener¬
ally must read an entire book or take an entire course on the language
without creating any real programs; you don’t begin to write pro¬
grams that anyone would actually want to use until you get to an
advanced level.
Early versions of dBASE, which could be used only by entering
interactive commands at the dot prompt, were difficult enough to
learn that programmers were in great demand. They were asked to
create menu-driven systems that would let users do what they needed
for their own applications without having to know anything about
dBASE itself. The programmer would define the structure of database
files, create reports and labels, and write a program to tie them
together—something like the application you generated in Chapter 9.
It is possible for a relative beginner at FoxPro programming to
create this sort of system without much trouble. After spending just
this one chapter on learning the basics, you will learn in Chapter 11
to program a general purpose, menu-driven, mailing list application
for users who want to keep track of names and addresses and produce
mailing labels.

STRUCTURED PROGRAMMING -
Apart from the ease with which it can be used to create useful
applications, FoxPro is a good introduction to computer program¬
ming because it is a structured programming language.
EXPANDING YOUR CAPABILITIES THROUGH PROGRAMMING 379

In this respect, FoxPro is greatly superior to most versions of BASIC.


The usual practice of teaching students BASIC as their first program¬
ming language has probably made many students abandon pro¬
gramming as too difficult. BASIC is one of the older programming lan¬
guages, which means for one thing that many BASIC programs are
extremely difficult to understand, since it was invented before computer
scientists knew how to create languages that could make it easy for pro¬
grammers to follow the logic of their programs.
The central processing unit of every computer has a built-in instruc¬
tion set. For example, there are circuits designed to add numbers and
to move data from one location in the computer’s memory to
another. Each of these circuits is activated by a binary code made up
of ones and zeros, and the earliest programmers actually had to learn
all these codes and what they did in the computer they were working
with in order to write programs. Programs written in this binary code
are said to be written in machine language.
Before long, computer scientists devised the idea of using an
English-like word to symbolize each of these codes. You could write
programs made up of these words and use a special program to trans¬
late them into machine code. This sort of translation is something
that a computer can do very easily: when it sees the word ADD or
MOV, for example, it replaces the word with the binary code that
tells the central processing unit to add two numbers or to move data.
Assembly language, which is still commonly used, is this sort of lan¬
guage. The program used to translate each word into binary code is
called an assembler.
Assembly language represented such an advance over machine lan¬
guages that it came to be known as the second generation of computer
languages. However, although assembly language is a tremendous
advance over lists of binary numbers, it is still very difficult to use. It is a
language that is based on how the hardware works—not on how people
think—and using it requires rigorous technical training.
During the 1950s and 1960s, as businesses began to computerize,
it became apparent that it would be impossible to get enough pro¬
grammers with the technical knowledge needed to write programs in
assembly language. Computer scientists began to develop what were
known as high-level languages, which were designed to be easy to learn
and understand. The best known of the early ones were COBOL and
380 MASTERING FOXPRO

CH. 10

BASIC. There were claims that such third-generation languages


would make programming so easy that computer programmers would
not be needed anymore: the managers of businesses would just write
programs for themselves. Of course, these claims were much too opti¬
mistic, but it was possible for businesses to hire people who had never
used computers, train them for a few months, and then start them
working as programmers.
The earliest of these third-generation languages had a major flaw,
though, which made programs much more difficult to understand
and maintain. This flaw had to do with the way that they redirected
the flow of program control.
The simplest program is just a list of instructions, which are exe¬
cuted one after another. Most programs, though, redirect the
sequence of execution, in order to use some instructions more than
once. For example, a program to write a report might have a series of
instructions that write a page’s footer, skip a number of lines, and
then write the header of the next page. Of course, these instructions
have to be executed many times when a report is produced, but the
programmer only needs to write them once: the program can contain
instructions that direct the flow of control to those lines every time the
footer and header are needed.
Even today, the
The earliest third-generation languages, imitating control flow in
most popular ver¬
sions of BASIC—GW-
assembly language, used the command GOTO in this sort of situa¬
BASIC and BASICA, tion. BASIC, for example, gives each line of programming code a
which are distributed number. If the code for producing a footer and header is at line
with IBM-PC compatible
10200, the program uses the command GOTO 10200 or perhaps the
computers—use GOTO
and GOSUB, and so are command GOSUB 10200 each time that it uses that code.
not structured. Some Needless to say, a program written this way is very difficult to fol¬
more recent versions
low. You need to flip through pages of code to find line 10200 in
of BASIC, such as
QuickBASIC and Turbo order to understand what that command actually does. And it is
BASIC, do allow you to likely that the code you find there will contain another GOTO that
do structured program¬
sends you flipping though the pages again. Programs written in this
ming, but they also con¬
tain the commands used
way get so twisted up that programmers began referring to them as
by older, unstructured “spaghetti code.” It is possible (though just barely) to keep the logic
programs; learning them in your mind when you are writing the program, but it is much more
as your first language
tends to teach bad pro¬
difficult to follow the logic when you are debugging the program or
gramming habits. when you go back to the program a year later to modify it; it is almost
impossible to unravel the code if you have to modify a program that
someone else wrote.
EXPANDING YOUR CAPABILITIES THROUGH PROGRAMMING 381

Structured programming was developed to make it easier to


understand and maintain programs. Computer scientists proved that
the command GOTO was not necessary. Any program could be writ¬
ten using only three types of control flow:

• sequence: the most basic type of control flow. Sequence sim¬


ply means that commands are executed one after another, as
they appear in the code.

• selection: the use of IF and ELSE to select one out of a group


of alternatives. If a condition is true, the program does one
thing; otherwise (ELSE), it does something else.

• iteration (or looping): the use of repetition. The same com¬


mands are repeated again and again as long as some condi¬
tion is true.

Structured programming also involved breaking down a program


into modules or procedures. Rather than a single long listing, with
GOTO twisted all through it, structured programs are broken down
into parts that are easier to understand. In the example above, there
might be one procedure to print the footer and header, which might
be named PAGEBRAK, since it occurs between pages; then, when¬
ever you needed it, you would use a command like DO PAGEBRAK
or PERFORM PROCEDURE PAGEBRAK (depending on the lan¬
guage you are using).
You can imagine how much easier it is to understand a program
with commands like DO PAGEBRAK than one with commands like
GOTO 10200. Breaking down the program into separate procedures
also makes it easier to maintain, since a procedure can be changed
without there being unexpected changes elsewhere in the program.
As you will see when you write a program in the next chapter, it is
much easier to test and debug programs one procedure at a time than
it is to test an entire program.
In summary, then, structured programming is marked by two fea¬
tures: first, control flow is based on sequence, selection, and itera¬
tion, and does not use GOTO; and, second, long programs are
broken down into smaller modules. Though they are not referred to
as a separate generation, structured programming languages make
programs so much easier to understand, test, and maintain that they
382 MASTERING FOXPRO

CH. 10

are as important an advance in programming technique as a new


generation. Later in this chapter, you will learn the basic techniques
of structured programming, all of which have been adopted by Fox¬
Pro and other dBASE compatible languages. You will see how to do
structured programming in the next two chapters.
Languages designed The next major advance over structured programming was the
for artificial intelli¬
gence are generally known
development of fourth-generation languages, which make it easy to
as fifth-generation lan¬ perform special tasks. The way that FoxPro lets you create files is typ¬
guages, but they have ical of fourth-generation languages. Many third-generation lan¬
not yet become as popu¬
guages make you save data on disk one line or one character at a
lar as people predicted
when they were first time. FoxPro’s low-level file handling functions do much the same
introduced. thing. If you wanted to find a record in a database file, you might
have to write a program that figures out how many characters after
the beginning of the file that record begins. If you wanted to index the
database, you would have to create an index file with pointers that let
your program find the address of each record in the database file. Of
course, FoxPro does all that for you automatically: you just need to
know the command GOTO or INDEX ON.
Many FoxPro commands, such as LOCATE, SEEK, and SET
RELATION TO do things that would take extra programming time
and work if you were using a general purpose third-generation lan¬
guage. But they are easy to do using a fourth-generation language
that is designed for the special purpose of managing a database.

SOME PRELIMINAR Y DE TAILS _

There are a few preliminary details that you should know before
you write your first sample programs in the next section.
Programs are plain ASCII text files, which can be created with
most text editors or with word processors that create plain ASCII files
(which some word processors call DOS files).
FoxPro and other dBASE compatible languages require you to
start a new line for each line of programming code: the new line is the
delimiter that lets FoxPro know where a single command begins and
ends. For this reason, you cannot use an editor with a word-wrap fea¬
ture that breaks up a line simply because it reaches the right margin.
Without word-wrap, you can simply keep typing the code beyond the
EXPANDING YOUR CAPABILITIES THROUGH PROGRAMMING 383

right margin. (If you select New from the File menu and then select
the Program radio button, or if you enter the command MODIFY
COMMAND <file namey, the FoxPro editor will have its word-wrap

a A semicolon within
a character string
feature turned off.)
If you want to be able to read your code more easily, you can keep
it from going beyond the right margin; you can break a long line in
will not break the string.
If you need to break a two by adding a semicolon (;) at the place you want it to break. This
line at a point where you will make FoxPro ignore the indication that the next line is a new
are in a character string,
line, and read the two lines as a single command. Of course, the list¬
you can break the string
into two strings at that ings in this book will use ; to fit the command in the width of the page.
point and use the semi¬ When you see this character, you can either type the code as it is in
colon followed by the plus
the printed listing, or you can leave out the ; and continue typing the
(+) sign. Don’t forget
that each string must be code on a single line.
enclosed in quotation The FoxPro interpreter ignores extra blank spaces. You can skip
marks. lines, and add extra blank spaces or tabs whenever you think that will
make the program easier to read. When you break a line in two using
the ; character, for example, it is good to indent the second line to
make it clear that it is a continuation of the same command. Like¬
wise, as you will see, indentation is very important in making it easier
to understand a program’s control flow.
Programs should also contain comments, which are used solely to
make it easier for people to understand the program. The program
itself does not use the comments.
FoxPro includes three commands that let you add comments. An
asterisk * or the word NOTE at the beginning of a line signals FoxPro to
ignore everything on that line. Using an asterisk at the beginning of the
line is the most common way of adding comments. It is also a good idea
to add a few hyphens after the asterisk: though they are not required,
they make the comments stand out so they are easier to follow.
The symbol && is used to add comments to the right of your pro¬
gramming code (rather than on a separate line). This double amper¬
sand may be used anywhere in the line. FoxPro executes the
command to its left, and ignores only the text to its right.
Programs are often difficult to follow when you come back to them
after not working with them for a year. The logic that seemed so obvi¬
ous to you when you were writing the program suddenly seems mys¬
terious: it is hard to figure out what you were doing. For this reason,
384 MASTERING FOXPRO

CH. 10

it is good to write a comment before each major activity that the pro¬
gram performs, identifying what the program is about to do.
The command SET You can run a program by entering DO <program name"> or by
ESCAPE OFF
selecting Do from the Program menu and selecting the name from
disables the Esc key so
that you cannot use it to the scrollable list. You can stop a program from running by pressing
stop a program. You can Esc. When you do this, FoxPro displays an alert that gives you three
add this command to the
choices:
beginning of a program
you have created, to keep
the user under your • Cancel: stops execution of the program permanently. This is
control at all times, but the default choice.
you should not add it
until after you have • Suspend: stops execution of the program temporarily and
finished your program¬ returns you to the Command window. You can start the pro¬
ming and debugging
gram again from the point where you left off by selecting
work, so you can use the
Esc key yourself. Resume from the Program menu or by entering the com¬
mand RESUME.

• Ignore: ignores the fact that you pressed Esc, and continues
execution of the program.

If there is an error in your program, FoxPro displays an alert with the


same choices plus an error message: it also displays the line in the code
that contains the error and lets you edit it, as you will see when you test
the first program.

TALKING TO
THE USER: INPUT/OUTPUT _

One basic element of any programming language is input/output:


the commands that the program uses to communicate with the user.
The FoxPro/dBASE standard includes two different sets of input/
output commands.
Unformatted input/output prints a message for the user or gets
information from the user at the location on the screen where the cur¬
sor happens to be. You have seen one of these commands, ?, which
simply moves the cursor to the new line and prints a line of text there.
If there is no room for a new line, this command makes everything on
the screen scroll up to make room for it.
EXPANDING YOUR CAPABILITIES THROUGH PROGRAMMING 385

Formatted input/output, on the other hand, lets you control where


on the screen messages appear. This is the sort of input/output that
was used in the program that you generated to create a custom data-
entry screen in Chapter 9. Every message to the user and every space
for the user to fill in text is in a specific place on the screen and cannot
move; the screen does not scroll up as it does when you use the ?
command.
In this section, you will learn both of these types of input/output.
Both of these are commonly used in connection with variables. As you
learned in Chapter 8, FoxPro lets you create two types of variables:

• fields: Each field in a database file is a variable and can be


used in input/output. For example, if you enter the com¬
mand USE EMPLIST followed by the command ? FNAME,
FoxPro will print the first name of the first record in the
EMPLIST file. If you then enter the command SKIP fol¬
lowed by the command ? FNAME, FoxPro will print the first
name of the second record in the file. FNAME is a variable
because its value changes. The values in fields are stored per¬
manently on your disk.

• memory variables: It is also possible to create temporary vari¬


ables that exist only in the memory (RAM) of your computer
and that are lost when you quit FoxPro. In Chapter 8, you
learned two equivalent commands to create memory vari¬
ables: STORE < value > TO < Tnemvar > and <memvar> =
<value>. In this section, you will also learn how to create a
memory variable that the user assigns a value to. It is conven¬
tional to give memory variables names that begin with the
letter M.

The programs that you write to test input/output will use both of
these types of variable. You will begin by learning unformatted
input/output and then go on to learn formatted input/output.

UNFORMA TTED INPUT/OUTPUT


You have already used the most important of the unformatted output
commands: CLEAR to clear the screen and ? to print a line of text to the
386 MASTERING FOXPRO

CH. 10

screen. In programming, ? is sometimes used without any character


expression following it, to print a blank line in order to skip a line. There
are a couple of other variations on this command. ?? prints a line of text
without printing a carriage return first, and ??? prints a line of text to the
printer. Like ?, these commands are used with FoxPro expressions, and
can include literals, functions, and variables.
You can also send text to the printer, as you know, by adding TO
PRINT at the end of certain commands. For example, you can use
LIST TO PRINT. If you want to send text to the printer and the com¬
mand you are using does not work with the clause TO PRINT, you
can use the command SET PRINT ON before entering the desired
command.
One other use of ? that is very important in programming is to
make the computer beep in case the user makes an invalid entry or
some other error. The command ? can be used to print any ASCII
character, and the beep happens to be ASCII character number 7.
Thus, the command ? CHR(7) will make the computer beep.
Another output command that is used only in programs is TEXT
. . . ENDTEXT. You can add a block of text of any length as a sub¬
stitute for the three dots in this command.. All of the text will be
displayed on the screen and, if you use SET PRINT ON first, it will
also be sent to the printer.
Finally, there are times in programs when you do not want output
displayed on the screen. To suppress the screen display, you can use
the command SET CONSOLE OFF. For example, you can use this in
combination with SET PRINT ON if you want something sent to the
printer but not displayed on the screen. Then, when you are done,
use the commands SET CONSOLE ON and SET PRINT OFF to
return to normal.
Notice that, as a fourth-generation language, FoxPro often gives
you many ways to do the same thing, so that you can choose the one
that is most convenient for you. For example, the program

? "Hello, "
?? "FNAME"

does the same thing as the program

? "Hello, " + FNAME


EXPANDING YOUR CAPABILITIES THROUGH PROGRAMMING 387

Likewise, the program

SET PRINT ON
? 'This line is going to the printer."
SET PRINT OFF

produces the same result as

??? "This line is going to the printer."

These output commands do things that are similar to things you


have done earlier in this book working from the command line. You
are doing something completely new, though, when you use the Fox¬
Pro commands that get input from the user.
The most basic unformatted input command is

INPUT [<char exp>] TO <memvar>

This command gets input from the user and creates a memory vari¬
able to store it in. If the optional character expression is included, that
character expression is used as a prompt. INPUT will keep repeating
the prompt until the user makes a valid entry.
You will have no trouble understanding how this command works
if you write a very simple program to test it. Before running this pro¬
gram, you should enter the command SET TALK OFF in the Com¬
mand window, so that FoxPro does not display talk to the screen and
disrupt the display that your program has set up. In an actual appli¬
cation, you would include the command SET TALK OFF in the pro¬
gram itself.
After running the sample program, you should change the listing
to add an error to it, so you can see how FoxPro helps you with
debugging.

1. Enter CD\LEARNFOX and then FOXPRO if necessary. If


you want, enter CLEAR to clear the screen.

2. To create the program, select New from the File menu.


Select the Program radio button and select OK. Enter the
program shown in Figure 10.1. Then select Save As from
the File menu. Notice that the Save Current Document As
388 MASTERING FOXPRO

CH. 10

The program list¬ dialog box lists all the existing .PRG files in its scrollable list,
ings in this book
including all the files that you generated in Chapter 9 using
follow the common pro¬
gramming convention of
Fox View. Enter TEST1 as the name of the new file, then
writing words of the select the default text button, Save. FoxPro automatically
FoxPro language in adds the .PRG extension. Close the Program window after
capital letters and writing
writing and saving the program.
variables and comments
in small letters. This is
merely meant to make
the program easier to •k-k'k'k-k’k-k'k'k'k-k'k'k'k-k-k-kick-k'k-k-k'k'k'k'k-k-kick-k'k'k-k

read: capitalization does *TEST1.PRG


♦sample program to illustrate the use of INPUT
not matter to the pro¬ •k'k+ck'k'k'k-k'k’k'k'k-kit'k'k-k-k-k-klck-k-k'k'k'k'k'k-k’k'k'k-k-k

gram, except in the case


CLEAR
of literals, such as “How 7
7
old are you?”, which are
INPUT "How old are you? " TO m_age
printed to the screen with ?
the capitalization they ? "Next year you will be " + LTRIM(STR(m_age + 1))
?
have in the program. You ?
can type the program in INPUT "Enter any number to continue " TO dummy

all capitals if you find it


easier.
Figure 10.1: A sample program to test INPUT.

3. Enter SET TALK OFF (or select View from the Window
menu and use the View window to set the talk off).

4. Select Do from the Program menu. The Do Program File


dialog box appears. Use the scrollable list within this box to
select TEST1.PRG. Since the files are in alphabetical order,
it is at the end of the list, as shown in Figure 10.2. Select the
default text button, Do, to run the program. FoxPro auto¬
matically compiles it and runs it, creating the screen shown
in Figure 10.3.

5. If you did not have any errors in the program, try adding one
to get a demonstration of FoxPro’s debugging capabilities.
Edit TEST 1. PRG again and eliminate the final parenthesis
following the function that prints the age, so it now reads as
LTRIM(STR(m_ _age + 1), with unbalanced parentheses.
Save it in this new form and then run it. When you get to the
line with the error, FoxPro displays an error message plus the
program code with a highlight on the line that has the error,
as shown in Figure 10.4.
EXPANDING YOUR CAPABILITIES THROUGH PROGRAMMING 389

System File Edit, Database Record Program Window

H Do Program File:

EMP_HELP.PRG Drive
EMP_LABE.PRG
EMP_MENU.PRG
EMP_OPEN.PRG
EMP_PACK.PRG Directory LEARNFOX
EMP_PHRA.PRG
EMP_PROC.PRG
EMP REPO.PRG « Do »
B1Q1
[ ] All Files

I
< Cancel >

MODIFY COMMAND Untitled


SET TALK OFF

Figure 10.2: Using the menu system to run the sample INPUT program.

How old are you? 39

Next year you will be 40

Enter any number to continue

Figure 10.3: The output of the sample INPUT program.


390 MASTERING FOXPRO

CH. 10

TEST 1 .PRG

■******-*****w****»www*«w*-*w*w**ww-*ww
*TEST1.PRG
^sample program to illustrate the use of INPUT
***■#*■#*■#■*■#■**■*-**•-#*-#*#*#******-**-**•***

CLEAR
?
?
INPUT "How old are you? " TO m_age
7
|? "Next year you will be " + LTRIM(STR(m age + T)|
9
9

Figure 10.4: FoxPro shows you your error.

6. Select the default text button, Cancel. FoxPro automatically


opens an edit window to let you edit the program, with the
cursor in the line where the error is. Add the closing paren¬
thesis at the end of the line. Save the file, then close the edit¬
ing window and run the program again to make sure it is
correct.

As you can see when you run the program, the character expres¬
sion “How old are you? ” appears as a prompt for the user; when
the user makes an entry, it is stored as a variable and then used by the
program as part of the next message to the user. A second INPUT
command is used to make the program pause so that the user has
time to read this message; because INPUT must save the user’s
response in a variable, this second occurrence of the command saves
the user’s choice in a memory variable named dummy because it is
never actually used. Notice that this program used ? to skip lines so
that this prompt would not be right at the top edge of the screen.
The major limitation of the INPUT command is that the data type
of the memory variable it creates is determined by the data type of the
user’s input. What this means is that, in order to use this command
EXPANDING YOUR CAPABILITIES THROUGH PROGRAMMING 391

to get a date or a character string, you would have to tell the user to
enter the data with the proper delimiters. To get the user’s name, for
example, you would have to use a command like:

INPUT "Enter your name surrounded by quotation marks" TO mname

Likewise, in TEST1, you had to have the user enter another number
to continue at the end of the program. INPUT does not cause any
trouble when you actually want to get a number, but it is not at all
user-friendly when you are working with other data types.
Because it is common to use an unformatted input/output com¬
mand to get text, there is another command that is like INPUT but
that reads any input as a character expression. The command

ACCEPT [<char exp>] TO <memvar>

works very much like INPUT except that it reads whatever the user
enters as a character string. Unlike INPUT, which creates a memory
variable whose data type depends on what the user enters, ACCEPT
always creates a memory variable of the character type. If necessary,
you can then use the functions that you learned in Chapter 4 to use
this input as if it were another data type—VAL( ) for the numeric
type and CTOD( ) for the date type.
As with INPUT, the optional character expression that you use with
ACCEPT appears as a prompt for the user. Try a sample program to
test ACCEPT. The easiest way to create this program is by editing the
program you created earlier, then saving it under a new name:

1. In the Command window, enter MODI COMM TEST1.

2. When the edit window appears, edit the program so it looks


like Figure 10.5.

3. Select Save As from the File menu. Save this program under
the name of TEST2. FoxPro adds the .PRG extension.

4. To run the program, enter DO TEST2 in the Command win¬


dow (or edit the command line that FoxPro generated when
you ran TEST1).

The output of the program is shown in Figure 10.6.


392 MASTERING FOXPRO

CH. 10

***********************************
*TEST2.PRG
*sample program to illustrate the use of ACCEPT
***********************************

CLEAR
7
7
ACCEPT "What is your name? " TO mname
7
INPUT "How old are you? " TO m_age
7
7
? "Sorry, " + PROPER(mname)
? "Next year you will be " + LTRIM(STR(m_age + 1))
7
ACCEPT "Press Enter to continue " TO dummy
"Z

Figure 10.5: A sample program to test ACCEPT.

What is your name? CHARLES

How old are you? 39

Sorry, Charles
Next year you will be 40

Press Enter to continue

Figure 10.6: The output of the sample ACCEPT program.

There is one other input command that you will often find useful.
Both INPUT and ACCEPT require the user to type something and
then press Enter before the program continues. Often, there are
times when you want to let the user press just one key, without hav¬
ing to press Enter afterwards. To do this, use the command

WAIT [<char exp>] [TO <memvar>]


EXPANDING YOUR CAPABILITIES THROUGH PROGRAMMING 393

Notice that the clause TO Kmemvary is optional in this command:


often it is just used to stop the program until the user is ready to con¬
tinue, and you do not have to create a dummy variable to do this with
WAIT, as you did with INPUT and ACCEPT.
In addition, if you do not include any character expression as the
prompt, WAIT will display the default prompt,

Press any key to continue . . .

For example, if your program has reached a point where it is ready to


print something, you can use the code

? "Make sure your printer is ready and"


WAIT

This will display the message

Make sure your printer is ready and


Press any key to continue . . .

Just the word WAIT, then, could substitute for the entire last line in
both of the previous programs. It would not only display the correct
prompt automatically but would also have the advantage of letting
the user press any key rather than having to press Enter.
The WAIT command is also useful to get a yes or no from the user.
For example, programs often include code like:
In cases such as
■■ this one, where the
WAIT "Do you want to print the report (y/n) " TO yesorno
memory variable is cre¬
ated, used immediately,
and discarded, program¬ This displays the prompt and creates a memory variable named
mers often do without the yesorno to hold the user’s response; the program can decide whether
initial m in the name of
or not to set the printer on depending on the contents of that variable.
the variable, as it is not
really required when the The advantage of using WAIT in this sort of situation is that it lets the
function of the variable is user make the choice with just one keystroke, without pressing Enter;
so obvious. though this feature might not seem too important when you read
about it, it can change the feel of a program entirely.
394 MASTERING FOXPRO

CH. 10

FORMA TTED INPUT/OUTPUT


The FoxPro/dBASE language also provides a command for for¬
matted input/output which is veiy versatile. In its place, it can per¬
form the functions of virtually all of the unformatted input/output

H Though it is most
common to use
commands, and more.
The basic form of this command is:

numbers, you can also


use numeric expressions
@ <row>,<column> [SAY <exp>] [GET <variable>]
with this command. For READ
example, you can use
variables as the row and The first clause, @ <row>,<column>, places the cursor; that is, it
column numbers so the
determines where on the screen the input/output will appear. The
location of the cursor
changes in the course of screen has 25 rows, numbered from 0 to 24, and 80 columns, num¬
the program. You will bered from 0 to 79. If you want a message on the next-to-the-last line
look at a program that
of the screen indented 20 spaces from the left, for example, you can
does this later in this
chapter. use a command beginning @ 23, 20.
The second clause, SAY <exp>, determines what the prompt will be.
The third clause, GET Kvariable^, creates a field for the user’s
input. Depending on your system, this field is displayed in reverse
video or some other enhanced display.
The important thing to remember about this command is that
the variable used after GET must be defined in advance: unlike the
unformatted input commands, this command does not create a vari¬
able. Though this makes you go through an extra step as a program¬
mer, it also gives you more control. The data type of the variable that
you create determines the data type of the variable that is entered.
In addition, the value you give the variable appears as a default
value. It is common to define the variable as a series of blank spaces,
so that the user has a blank data-entry field of the proper length. Pro¬
grammers often use the function SPACE(<m/m exp>) to do so: this
function returns a number of blank spaces equal to the expression.
Though you can simply use a series of blank spaces in quotation
marks to define the variable, it is often easier to use this function.
You can also give the variable a useful default value: for example,
if California is the input you expect most often, you can give the vari¬
able the value “CA”. The user can then confirm that default by
pressing Enter or they can change it by typing over it.
Finally, after you use the @ . . . SAY . . . GET command, you
must use a separate command, READ, to make the program pause to
EXPANDING YOUR CAPABILITIES THROUGH PROGRAMMING 395

get the user’s input. The advantage of this is that you can write a long
series of @ . . . SAY . . . GET commands and then use READ just
once at the end to get the user’s input for all of them. Thus, rather
than just getting input one line at a time, as you did with unformatted
input/output commands, you can present the user with an entire
data-entry screen before getting any input.
Notice that the SAY and GET clauses in this command are both in
brackets, indicating that they are optional. It is most common to use
both clauses in a command. The variable that you GET will appear
just to the right of the prompt that you SAY. It is common, though,
to leave one of them out and use the command just to print a prompt
or just to get input without a prompt.
In general, the user must press Enter after each input. If the input
fills up the entire width of the field, though, FoxPro will beep (assum¬
ing that you have not set Bell off) and go on to the next field, just as it
does in ordinary data entry.
Try an example to get a feel for the basics of this command. Enter
the program listed in Figure 10.7 in a file named TEST3.PRG, then
compile and run it. Its output is shown in Figure 10.8. Notice the
three steps in this program: define the variables, use the command
@ . . . SAY . . . GET, use the command READ. Notice in particu¬
lar how much control the READ statements give you. You can deter¬
mine exactly how much is displayed on the screen when the user
inputs data. When you run this sample program, for example, the
final line does not appear on the screen until after the user has entered
the data in the earlier lines.

***********************************
*TEST3.PRG
*sample program to illustrate formatted input/output
***********************************

mcity = SPACE(15)
mstate = "CA"
mkey = " "

CLEAR
@ 12,0 SAY "Enter the city: " GET mcity
@ 14,0 SAY "Enter the state: " GET mstate
READ
@ 20,0 SAY "Press any key to continue... " GET mkey
READ

Figure 10. 7: A program to illustrate formatted input/output.


Enter the city: BERKELEY

Enter the state: ^

Press any key to continue...

Figure 10.8: The output of the formatted input/output program.

Perhaps you noticed that the program you just ran looked very
much like the data-input screens that you created in Chapter 9 using
FoxView. Format programs must be made up entirely of @ . . .
SAY . . . GET commands and related commands. Further, they
differ from ordinary programs in having the extension . FMT instead
of .PRG. These same commands could be used in an ordinary .PRG
program file, but putting them in an .FMT file gives you the conven¬
ience of using the program with the command SET FORMAT TO.
How can the format file be used without assigning some value to
each of its variables first? In fact, its variables do have a value
assigned to them: all its variables must be fields in the database file. If
you USE the file, SET the format, and then CHANGE, each variable
has the value of a field in the current record: this appears as the
default on the screen that you can either edit or press Enter to
confirm. If you USE the file, SET the format, and then APPEND, the
variables are all blank, as they have the values of the fields in the new,
blank record that you have added at the end of the file.
Like the format programs you generated with Fox View, @ . . .
SAY . . . GET commands can include RANGE and PICTURE
clauses to restrict the data that can be entered. These are simply
EXPANDING YOUR CAPABILITIES THROUGH PROGRAMMING 397

D Remember that, as
an abbreviation,
added at the end of the command. The word RANGE is followed by
two values (for maximum and minimum) separated by commas, as
you can use the first four
letters of a FoxPro com¬
you saw in the last chapter. The word PICTURE is followed by one
mand. You rarely see of the picture templates or picture functions, which you also learned
PICTURE in an actual about in the last chapter; all of the available symbols are listed in
program (unless the
Tables 10.1 and 10.2.
program is generated by
FoxView). It is almost
always PICT. Table 10.1: Picture Template Symbols

Symbol Effect

A allows only alphabetic characters to be entered

L allows only logical data to be entered

N allows only alphabetic characters or numerals to be


entered

X allows any character to be entered

Y allows only a capital or small Y or N to be entered,


and converts the entry to uppercase

9 allows only numerals to be entered in a character


field, or numerals and signs to be entered in a
numeric field

# allows numerals, signs, and blanks to be entered


J capitalizes lowercase characters that are entered

$ displays the currency symbol defined by SET


CURRENCY
* fills leading blanks of a numeric value, using
asterisks

Picture templates are used to format input/output on a character-


by-character basis. They may include characters that will be used lit¬
erally as well as the symbols which format the corresponding
character in the actual input/output. Function symbols apply to the
entire input/output field. Function symbols may be used in the PIC¬
TURE clause if they are preceded by the symbol @, but they may be
used without the @ if you use the word FUNCTION instead of PIC¬
TURE. Multiple function symbols may be used in a single clause, as
long as they are not separated by spaces.
398 MASTERING FOXPRO

CH. 10

Table 10.2: Picture Function Symbols

Symbol Effect

A allows only alphabetic characters to be entered

B left-aligns numeric output

C displays CR after a positive number (used only with


numeric data in the SAY clause)

D displays dates in the current SET DATE format


(used with date, character, and numeric data)

E displays dates in the European (or British) format


(used with date, character, and numeric data)

I centers text within a held (used only with the SAY


clause)

j right-aligns text within a field (used only with the


SAY clause)
L displays leading zeros instead of blanks to fill
numeric fields (used only with numeric data in the
SAY clause)

M < list > specifies preset choices, which are listed with commas
separating them (if the GET variable is not one of the
choices in the list when READ is executed, it is
replaced by the first choice on the list)
S < number > limits the width of the field displayed to the number
specified (used only with character data)

T trims leading and trailing blanks

X displays DB after a positive number (used only with


numeric data in the SAY clause)

Z displays a field as blank if its value is zero (used only


with numeric data)

( displays negative numbers enclosed in parentheses


(used only with numeric data in the SAY clause)
! converts letters to uppercase, but does not prevent
the entry of other characters (used only with
character data)
EXPANDING YOUR CAPABILITIES THROUGH PROGRAMMING 399

Table 10.2: Picture Function Symbols (continued)

Symbol Effect

/V
displays numeric data using scientific (exponential)
notation (used only with numeric data)

$ displays data in currency format, as defined by the


SET CURRENCY command

To see the types of commands we have been discussing m this section,


you can look at the file DATAENTR.FMT, which you generated
using Fox View. Use the File menu to open this file as a program, so you
can scroll through it. This file is shown in Figure 10.9—though, of
course, the name in the heading is different in your program.

* Program.: DATAENTR.FMT
* Author..: Charles Navasky Siegel
* Date....: 02/07/91
* Notice..: Copyright (c) 1991, SYBEX
* Version.: FoxBASE+, revision 2.10
* Notes...: Format file for EMPLIST.DBF
*

SET COLOR TO R/N


@ 2,0 SAY "Employee number "
@ 4,0 SAY "First name "
@ 4,50 SAY "Last name "
@ 6, 0 SAY "Address "
@ 6,50 SAY "Apartment "
@ 8, 0 SAY "City "
@ 8,35 SAY "State "
@ 8,50 SAY "Zip "
@11, 0 SAY "Date hired "
@ 11,34 SAY "Wage "
@ 11,50 SAY "Probation? (t/f) "
@ 14,3,18,75 BOX " F=1 | J 11 "
@ 15,24 SAY "<- -> : Move cursor within field"
@ 17,10 SAY "Tab Shift-Tab : Move from field to next or preceding field"

SET COLOR TO ,N/W


@ 2,16 GET Empno
@ 4,11 GET Fname PICTURE "@!"
@ 4,60 GET Lname PICTURE "@!"
@ 6, 8 GET Address
@ 6,60 GET Apt_no
@ 8,5 GET City
@ 8,41 GET State
@ 8,55 GET Zip PICTURE "99999"
@ 11,11 GET Date_hired
@ 11,39 GET Wage PICTURE "99.99" RANGE 4,50
@ 11,67 GET Probation
*

* EOF: DATAENTR.FMT

/■

Figure 10.9: The format file generated in Chapter 9.


400 MASTERING FOXPRO

CH. 10

This program has all the @ . . . SAY commands first, and then all
the corresponding @ . . . GET commands, so that it can use the
SET COLOR command to make the labels a different color from
the data-entry fields. It includes the PICTURE and RANGE clauses
that you entered in the FoxView table.
It also includes an interesting variation on the @ . . . SAY . . .
GET command: the line (about halfway down the list) that deter¬
mines how the box is to be drawn. This command includes the row
and column of the upper left corner of the box first, then the row and
column of the lower right corner of the box. (These values will proba¬
bly be a little different from your values, depending on precisely
where you placed your box in the exercise in Chapter 9.) Then, after
the word BOX, it lets you enter up to nine characters to specify the
type of lines used to draw the box. Remember that these line¬
drawing characters are extended ASCII characters, which you may
enter using the CHR() function rather than actually using the box
characters themselves, as FoxView does.
If you are doing the programming yourself for a data-entry screen
that is to have a box, there is an easier way of doing it than using this
command. Simply draw the box and labels using an editor that lets
you draw lines. When you are done, add the command @ <row >, 0
at the beginning of each line on your screen that has anything written
in it, either text or a box, and an additional quotation mark at the end
of each line. FoxPro will read the box-drawing characters and text on
each line as a character string, including any blanks in it, and will
draw the screen as your editor laid it out. You just need to add GET
clauses where you want the data-entry fields (and, if necessary, delete
enough blank spaces to make room for them).
One other useful member of this family of commands is @
<.row~>, Kcoiy CLEAR [TO <row>, <o>/>], which clears just part
of the screen: the area beyond the row and column that you specify at
the beginning. For example, @ 20,40 CLEAR will clear the screen
from the middle (column 40) to the end of line 20 and everything
below that. With the optional TO clause at the end, it will only clear
as far the second row and column that is specified.
For more information on this family of commands, see Appendix C.
EXPANDING YOUR CAPABILITIES THROUGH PROGRAMMING 401

CONTROL FLOW _
The simplest program is just a list of commands, executed from
beginning to end. The thing that really makes computer programs
powerful, though, is the ability to direct the flow of program control.
As you learned earlier in this chapter, the three types of control flow
used in structured programs are sequence, selection, and iteration
(or looping).
Sequence simply means that one command is executed after
another. This is the only form of control flow used in the sample pro¬
grams that you have tried so far. Now that you have learned about
input/output, you are ready to work with more sophisticated forms of
control flow.

LOOPING
The most important command used for iteration in FoxPro/
dBASE compatible languages is the DO WHILE loop, which has the
following form:

DO WHILE <logical exp>

ENDDO

The ellipsis between the first and last line stands for any number of
lines of programming code.
Each time the program reaches this DO WHILE command, it
checks to see if the logical expression evaluates as true. If it is, the pro¬
gram executes the commands that follow. When it gets to ENDDO, it
loops back up to the DO WHILE and checks again to see if the logical
expression evaluates as true; if it is, it executes the same commands.
It will continue repeating this loop until the program discovers that
the logical expression does not evaluate as true, at which point it will
skip all these commands and instead execute the command that fol¬
On the rare occa¬ lows ENDDO.
sions where Esc Of course, the lines of code within the loop must do something that
does not work, remember
ultimately makes the condition untrue, otherwise the program will
that you can always get
out of an infinite loop by
continue executing this series of commands forever. This is a com¬
turning off the computer. mon error in programming, called an infinite loop. If your program
402 MASTERING FOXPRO

CH. 10

seems to die—to stop doing anything at all—what has probably hap¬


pened is that it has come to some infinite loop that does not display
anything on the screen: it is actually performing some group of
instructions over and over again and never getting up to a command
that makes it do something that you would notice. Alternatively, a
program may display the same thing over and over again as the result
of an infinite loop. If either of these things happens, press Esc to inter¬
rupt the program and look through the code to see where and why a
loop is executing indefinitely. (You might also find it helpful to use

S FoxPro runs so
quickly that you
the Trace window, which is discussed in Chapter 12.)
Consider a simple example of looping, which makes your screen look
a bit like a primitive video game. Enter the listing in Figure 10.10
might not be able to see
every location of the > in a file named TEST4.PRG and run it: a bit of the output is shown in
symbol in TEST4.PRG Figure 10.11.
and TEST6.PRG: it
seems to jump across the
screen. You can see it in
every column in
TEST5.PRG, where you ************************************
*TEST4.PRG
add a delaying loop to *a sample program to demonstrate looping
slow its movement.
col_cntr = 0
DO WHILE col_cntr < 80
CLEAR
@ 10,col_cntr SAY ">"
col_cntr = col_cntr + 1
ENDDO
WAIT

Figure 10.10: A sample program to demonstrate looping.

Notice the way this program is indented. Whenever you have a


DO WHILE loop, you should indent the code that is within the loop.
This does not affect the way that FoxPro runs the program, but it
does make it much easier for you to understand.
How exactly does this program work?
First, you create a variable named col_cntr, a counter which will
hold all the column numbers that you use in the program. You must
define this variable before the program comes to the DO WHILE
command: because you gave it a value of zero, the logical expression
that follows DO WHILE is true, and so the code within the DO
WHILE loop is executed. This code clears the screen and then uses
the @ . . . SAY command to display the character > at row 10,
EXPANDING YOUR CAPABILITIES THROUGH PROGRAMMING 403

Press any key to continue

Figure 10.11: Output of the sample looping program, showing the > character
after it has moved to column 79.

column 0 (since the value of 10,col_cntr is 10,0 this time through the
loop).
Then the program increments the value of col_cntr by one. The
line of code that does this, col cntr = col_cntr + 1, looks strange to
many beginning programmers. People are used to the meaning of
the = sign in arithmetic, where it signifies equality: in arithmetic,
of course, the equation col_cntr = col_cntr + 1 would be absurd,
since a number cannot equal one more than itself. In FoxPro,
though, as in most computer languages, the = sign represents assign¬
ment. This line of code should be read as ‘ 'make col_cntr equal to col-
_cntr plus one,” or as “let col_cntr equal col__cntr plus one.” Since
the value of col_cntr was 0 when the program got to this line, it makes
its value equal to 1.
When the program gets to ENDDO, it sends it back up to the top of
the loop, where it checks the condition following DO WHILE once
again. Since col_cntr is now equal to 1, the condition is still true, so
the program again executes the code in the loop. It clears the screen
and then prints the > sign at row 10, column 1, so that it looks as if
the sign has moved one column to the right. Then it makes the value
of col_cntr equal to 2, adding 1 to its current value of 1.
404 MASTERING FOXPRO

CH. 10

Thus, it continues going through the loop and printing the > sign
at column 2, column 3, and so on. When col_cntr is equal to 79,
though, it prints the > sign at row 10, column 79. Then it adds 1 to
col_cntr and makes its value 80. At this point, when it checks the con¬
dition of the DO WHILE loop, it finds that it is no longer true that col-
_cntr < 80 and so it does not execute the code in the loop again.
Instead, it continues with the next line of code after ENDDO.
This program illustrates the basic principle of a DO WHILE loop.
Some variable in the loop must change its value so that the condition
is ultimately untrue.

NESTED DO WHILE LOOPS: A SIMPLE EXAMPLE


It is not uncommon to use one DO WHILE loop within another.
This is known as nesting.
Consider a simple example, where you just use the inner loop as a
delay mechanism. Let’s say you decide that the > sign moved across
the screen too quickly in the previous program, so you slow it down
by adding a loop that simply wastes time by counting to 100 (since it
actually takes the program time to do the counting). If you have a
very fast computer, you might want to use a number larger than 100.
Edit the previous example to add this loop, as shown in Figure
10.12, and save it in the file TEST5.PRG. Then compile and run it
by entering DO TEST5.

***********************************
*TEST5.PRG
*a sample program to demonstrate a delaying loop
***********************************
col_cntr = 0
DO WHILE col_cntr <80
CLEAR
@ 10,col_cntr SAY ">"
col_cntr = col_cntr + 1
tim_cntr = 0
DO WHILE tim_cntr < 100
tim_cntr = tim_cntr + 1
ENDDO
ENDDO
WAIT

Figure 10.12: Adding a delaying loop within the main loop.


EXPANDING YOUR CAPABILITIES THROUGH PROGRAMMING 405

Each time it goes through the main loop, the program makes
tim_cntr equal to zero; then it must add 1 to it 100 times before it can
continue. Notice how much more slowly it runs than it did before you
added this extra loop. This sort of time-killing loop can be useful at
the beginning of a program, if you want the program to display its
title screen for a time and then to begin automatically.

MORE ADVANCED NESTED LOOPS


Nested loops are more complex if both change the value of mean¬
ingful variables. For example, let’s say that you want the > sign not
just to go across the columns of row ten, but to go across the columns
of all the rows, one after another. You can add a loop to count rows
outside of the loop that counts columns. Edit TEST4.PRG to add
this extra outer loop, as shown in Figure 10.13, and then save it
under the name of TEST6.PRG and run it by entering DO TEST6.

***********************************

*TEST6.PRG
*a sample program to demonstrate nested loops
***********************************
row_cntr = 0
DO WHILE row_cntr <25
col_cntr = 0
DO WHILE col_cntr < 80
CLEAR
@ row_cntr,col_cntr SAY ">"
col_cntr = col_cntr + 1
ENDDO
row_cntr = row_cntr + 1
ENDDO

Figure 10.13: A more complex example of nested loops.

The indented lines inside the main loop (the six lines beginning
with col_cntr = 0) are essentially the same as the earlier program,
TEST4.PRG. These lines display the > sign on each column across
the screen. The difference is that they do not just go across row 10, as
the earlier program did: instead, they are nested in a larger loop that
executes them on all the rows, one row after another. To begin with,
the row_cntr is 0. The program displays > at 0,0, at 0,1, at 0,2, and
so on until it has gone through all the columns and displayed it at
406 MASTERING FOXPRO

CH. 10

0,79. Then, it finds that the condition col_cntr < 80 is no longer


true, so it stops executing the inner DO WHILE loop and goes to the
next line of code following the inner ENDDO, which adds 1 to
row_cntr. Then it reaches the final, outer ENDDO, which sends it
back up to the first DO WHILE to see if the condition is true. Because
row_cntr is still less than 25, it executes this outer loop again. First, it
makes col_cntr equal 0. Then it executes the inner loop, displaying
> at 1,0, at 1,1, at 1,2, and so on until it has gotten up to 1,79. Then
it makes row_cntr equal to 2, so that the next time through, the inner
loop displays > in all the columns of the next row. It keeps doing this
until it has displayed > across all the columns of all 25 rows. Then,
finally, when row_cntr equals 25, the condition of the outer loop is no
longer true.
This program shows how important it is to indent code properly.
When one loop is nested in another, it is very difficult to follow unless
it is indented in a way that makes the logic clear.

LOOPING THROUGH A DATABASE FILE


Finally, try one example that uses a DO WHILE loop with a data-
base file. It is common in programs to go through an entire file by
using the function EOF() in the condition of a DO WHILE loop. You
should remember from Chapter 5 that FoxPro makes this function
true after you move the pointer beyond the last record. Thus, you
can use it to display all the records in a file by using the code shown in
Figure 10.14. Try creating and running this program; the screen out¬
put is shown in Figure 10.15.

■A**********************************

*TEST7.PRG
*a sample program that loops through the records of a file
•k-k-k'k-k-k'k'k'k-k-k-k'k'k-k-k'k-k-k-k-k-k'k-k-k-k'k-k'k'klfk'k'kic

USE emplist
CLEAR
7
p
DO WHILE .NOT. EOF()
? PROPER(TRIM(fname)+" »+lname)
SKIP
ENDDO
7
WAIT

Figure 10.14: A program to loop through a database file.


EXPANDING YOUR CAPABILITIES THROUGH PROGRAMMING 407

Audrey Levy
Jack Love
Edna Chang
Charlotte Sagorin
William Johnson
William B. Johnson
Nancy Nixon
James Skinner
Michelle Perlow
Joseph Cruz
Henrietta Johnson

Press any key to continue

Figure 10.15: The output of the program TEST7.PRG.

This little program is essentially equivalent to the command LIST


PROPER(TRIM(fname) + “ ” + lname). It simply reads through the
entire file and prints the first and last name from each record. When
it gets past the last record, the condition of the DO WHILE loop is no
longer true, so the program stops. You can begin to appreciate how
good it is to be using a fourth-generation language, because it has
commands such as LIST, which relieves you of the task of having to
write programs like this.

SELECTION
Selection is the third method of control flow used in structured
programming.
FoxPro includes two basic methods of selection. When there are
just one or two choices, it is most convenient to use the IF . . . ELSE
. . . ENDIF command. When you have a larger number of choices,
it is most convenient to use the DO CASE . . . ENDCASE command.
408 MASTERING FOXPRO

CH. 10

IF .. . ELSE . . . ENDIF
The IF . . . ELSE . . . ENDIF command is fairly straightforward
and easy to understand. It takes the form

IF <logical exp>

ELSE

ENDIF

The ellipses represent any number of lines of code. If the logical expres¬
sion is true, the code following the IF clause is executed. If the ex¬
pression is not true, the code following the ELSE clause is executed.
This command can also be used without any else clause, in the form

IF <logical exp>

ENDIF

The code is executed if the expression is true.


For example, let’s revise the previous program to give the user the
choice of whether or not to get the listing. Edit TEST7.PRG,
the program you just wrote, and nest the loop that prints the names
within an IF statement, as shown in Figure 10.16; save it under the
name of TEST8.PRG and run it. The output (if you enter y to get
the listing) is shown in Figure 10.17.

***********************************
*TEST8.PRG
*a sample of a DO loop nested in an IF statement
***********************************

USE emplist
CLEAR
7

WAIT "Do you want a listing (y/n)? " TO yesno


IF UPPER(yesno) = "Y"
7
DO WHILE .NOT. EOF()
? PROPER(TRIM(fname)+" "+lname)
SKIP
ENDDO
ENDIF
7
WAIT

Figure 10.16: A DO loop nested in an IF statement.


EXPANDING YOUR CAPABILITIES THROUGH PROGRAMMING 409

Do you want a listing (y/n)? Y

Audrey Levy
Jack Love
Edna Chang
Charlotte Sagorin
William Johnson
William B. Johnson
Nancy Nixon
James Skinner
Michelle Perlow
Joseph Cruz
Henrietta Johnson

Press any key to continue ...

Figure 10.17: The output of TEST8.PRG.


If the user does not press y, the program will not execute the DO
WHILE loop at all.
As an example of a program with both an IF and an ELSE clause, try
giving the user the choice of whether or not to capitalize the names. Edit
TEST8.PRG, the program you just wrote, so that it matches the pro¬
gram in Figure 10.18. Save it under the name of TEST9.PRG and run
it: its two possible outputs are shown in Figure 10.19.

***********************************
*TEST9.PRG
*a sample of a DO loop combined with IF/ELSE
***********************************

USE emplist
CLEAR
•?

WAIT "Do you want the names capitalized (y/n) " TO yesno
•?

DO WHILE .NOT. EOF()


IF UPPER(yesno) = "Y"
? UPPER(TRIM(fname)+" "+lname)
ELSE
? PROPER(TRIM(fname)+" "+lname)
ENDIF
SKIP
ENDDO
~>

WAIT

Figure 10.18: Combining a DO loop and an IF/ELSE statement.


410 MASTERING FOXPRO

CH. 10

Do you want the names capitalized (y/n) y

AUDREY LEVY
JACK LOVE
EDNA CHANG
CHARLOTTE SAGORIN
WILLIAM JOHNSON
WILLIAM B. JOHNSON
NANCY NIXON
JAMES SKINNER
MICHELLE PERLOW
JOSEPH CRUZ
HENRIETTA JOHNSON

Press any key to continue ...

Do you want the names capitalized (y/n) n

Audrey Levy
Jack Love
Edna Chang
Charlotte Sagorin
William Johnson
William B. Johnson
Nancy Nixon
James Skinner
Michelle Perlow
Joseph Cruz
Henrietta Johnson

Press any key to continue ...

Figure 10.19: Two possible outputs of TEST9.PRG.

Notice that this program could also be written with two separate
DO WHILE loops—one to print all the names capitalized and the
other to print them with normal capitalization, as shown in Fig¬
ure 10.20. The only difference is that the code is more compact in the
original form.
EXPANDING YOUR CAPABILITIES THROUGH PROGRAMMING 411

***********************************
*TEST10.PRG
*a less elegant method of combining a DO loop with IF/ELSE
***********************************
USE emplist
CLEAR
7

WAIT "Do you want the names capitalized (y/n) " TO yesno
7

IF UPPER(yesno) = "Y"
DO WHILE .NOT. EOF()
? UPPER(TRIM(fname)+" "+lname)
SKIP
ENDDO
ELSE
DO WHILE .NOT. EOF()
? PROPER(TRIM(fname)+" "+lname)
SKIP
ENDDO
ENDIF
7

WAIT

Figure 10.20: A less compact way of combining a DO loop and an IF/ELSE


statement.

DO CASE . . . ENDCASE
The DO CASE . . . ENDCASE command is useful when there are
a larger number of choices.
It is possible to use the IF . . . ELSE . . . ENDIF command to select
among multiple choices, by nesting one IF . . . ELSE . . . ENDIF
within another. Consider the program shown in Figure 10.21, which
simply tells the user what number was entered. Figure 10.22 shows two
possible outputs of this program.
Look carefully at how this program works. All of the other IF . . .
ELSE commands are nested within the first ELSE. Thus, if the user
enters 1, the program executes the command under the first IF, then
it skips all the lines between the first ELSE and the last ENDIF. If the
user does not enter 1, though, the program executes the line under
the first ELSE, and it checks to see if the user entered 2. If the user
entered 2, it skips all the lines nested in the second ELSE, but if the
user did not enter 2, it executes the line under the second ELSE and
checks whether the user entered 3. Likewise, if the user did not enter
3, it checks to see if the user entered 4. Finally, if the user did not
enter 4, it prints an error message.
412 MASTERING FOXPRO

CH. 10

Figure 10.21: An IF/ELSE ladder.

This program is an example of what is called an IF ELSE ladder,


and you do see it in programs on occasion. Needless to say, though, it
is difficult for the programmer to read. Thus, FoxPro gives you
another command, DO CASE, which does the same thing. The pro¬
gram in Figure 10.23 works just like the previous one and produces
identical output.
DO CASE works just like an IF-ELSE ladder. The program looks
through the CASE statements to find if one is correct. If it is, the pro¬
gram executes the code following that CASE statement and, after it is
done with that block of code, goes on to the code following END-
CASE. OTHERWISE works like the final ELSE of the IF-ELSE
ladder: the statements following it are executed if the conditions in all
of the CASE statements are untrue. DO CASE may also be used with¬
out OTHERWISE: if none of the conditions are true, no code is
executed.
EXPANDING YOUR CAPABILITIES THROUGH PROGRAMMING 413

Type a number between 1 and 4 > 3

You typed three.

Press any key to continue ...

Type a number between 1 and 4 > m

Error: entry not between 1 and 4.

Press any key to continue ...

Figure 10.22: Two possible outputs of the preceding IF/ELSE ladder.

EXIT AND LOOP


If you use one of these methods of selection within a DO WHILE
loop, you can create an infinite loop deliberately and use the com¬
mand EXIT to break out of it.
414 MASTERING FOXPRO

CH. 10

‘k-k-kick'k-k-kick’k’k'k'k-k-k-k-k'k-k'k-k'k-k-k-k-k'k'k-k'k'k-k-k-k

*TEST12.PRG
*a sample of DO CASE
***********************************
CLEAR
7
7

WAIT "Type a number between 1 and 4 > "TO usr_nmbr


7
DO CASE
CASE usr_nmbr = "1"
? "You typed one."
CASE usr_nmbr = "2"
? "You typed two."
CASE usr_nmbr = "3"
? "You typed three."
CASE usr__nmbr = "4"
? "You typed four."
OTHERWISE
? "Error: entry not between 1 and 4."
ENDCASE
7
WAIT

Figure 10.23: A DO CASE statement.

EXIT and LOOP are two commands that programmers use when
they want to make loop control explicit. EXIT breaks out of the loop
and directs control to the statement following ENDDO. LOOP
returns control to the DO WHILE statement. This makes it possible
to return to the beginning of the loop without executing some of the
commands that are in it.
It is often clearer to put an EXIT command within an infinite loop
rather than putting the condition after DO WHILE. You can create
an infinite loop by using a condition that is always true, for example,
DO WHILE 1 = 1. You can use a more elegant command, though, if
you remember that FoxPro evaluates any condition of this sort and
executes the loop if it evaluates as .T. To save it the trouble, you can
just use the condition DO WHILE .T.
Try rewriting the TEST12.PRG to add an infinite loop using the
EXIT and LOOP commands, as in Figure 10.24. Save this program
in a hie named TEST13.PRG and run it. Its output is shown in Fig¬
ure 10.25.
Notice that the command LOOP is not actually needed in this case:
the program would loop up when it reached the final ENDDO
EXPANDING YOUR CAPABILITIES THROUGH PROGRAMMING 415

***********************************
*TEST13.PRG
*a sample of EXIT and LOOP
***********************************
DO WHILE .T.
CLEAR
7
7
WAIT "Type a number between 1 and 4 > "TO usr_nmbr
7
DO CASE
CASE usr_nmbr = "1"
? "You typed one."
CASE usr_nmbr = "2"
? "You typed two."
CASE usr_nmbr = "3"
? "You typed three."
CASE usr_nmbr = "4"
? "You typed four."
OTHERWISE
? "Error: entry not between 1 and 4."
ENDCASE
7
WAIT "Do you want to try again? (y/n) " TO yesno
IF UPPER(yesno) = "Y"
LOOP
ELSE
EXIT
ENDIF
ENDDO

Figure 10.24: Using EXIT and LOOP to control a loop.

Type a number between 1 and 4 > 3

You typed three.

Do you want to try again? (y/n)

Figure 10.25: The output of TEST 13.PRG.


416 MASTERING FOXPRO

CH. 10

anyway. The condition at the end of the program could be rewrit¬


ten as: V

WAIT "Do you want to try again? (y/n)" TO yesno


IF UPPER(yesno) < > "Y"
EXIT
ENDIF

and the program would run in exactly the same way. In this case add¬
ing LOOP is merely a stylistic convenience, to make the program eas¬
ier to understand. In other cases, LOOP is used to bypass some of the
commands within a DO WHILE loop.

A NOTE ON PROCEDURES ___

As you learned at the beginning of this chapter, an essential part of


structured programming is dividing the program up into smaller pro¬
cedures or modules, so that each one can be written, tested, and
debugged individually.
In early versions of the dBASE language, each module had to be
kept in a separate .PRG file, and it is still possible to write programs
in this way.
To call a program in another file, you simply use the command
DO <file name^> within a program, just as you have been doing from
the command line. Control of the program passes to the program
that you have called. When that program is done, control returns to
the following line in the calling program.
RETURN TO Control returns to the calling program automatically when it
MASTER is a
variation on the com¬
reaches the end of the called program. You can also use the com¬
mand RETURN, which mand RETURN anywhere in the called program to return control to
returns control to the first the calling program (or, if you used the program directly from the
.PRG file executed,
command window, to return to FoxPro).
rather than to the file that
called the current one. One principle of structured programming, though, is that it is best
for control to flow to the bottom of each procedure, so it is not good
style to use RETURN in the middle of a module. Many programmers
put RETURN at the end of each module, even though it is not
needed, to make the flow of the program explicit.
EXPANDING YOUR CAPABILITIES THROUGH PROGRAMMING 417

Beginning with dBASE III, you were no longer required to keep


each module in a separate .PRG file: you could create a procedures
file that would hold many modules. FoxPro goes further by letting
you keep procedures in the same file as the main program, as you can
in virtually all structured languages.
In the next chapter, though, you will solidify your understanding
of structured programming by writing a program the old-fashioned
way, with each module in a separate .PRG file. Then, in Chapter 12,
you will look at procedures files and at some more advanced pro¬
gramming techniques that go with them.
Write Your Own
Professional Menu Application
To analyze a programming problem, 423
make a list of the data fields required and the indexes that must
be used. Draw a structure diagram that shows all the separate
modules that will comprise the complete program.

To control the FoxPro environment, 430


begin the program with environment commands such as SET
TALK OFF and SET BELL OFF, which set the environment
variables needed during the program. Set Talk and Bell on
again just before the user quits the program, so the ordinary
defaults are back in effect when you return to FoxPro.

To create a typical menu system, 430


use a series of @ . . . SAY statements to display the various
choices, and an @ . . . SAY . . . GET statement to let the
user enter a choice. Use a DO CASE statement to call various
modules of the program depending on the user’s choice, and to
beep if the choice is invalid. Nest all of this code in a DO
WHILE loop, so the menu is used over and over again until the
user chooses Quit.

To do stub testing, 434


write trivial sample versions of the modules called by the mod¬
ule you are working on. These versions should do something
insignificant, such as telling the user to press any key. Then you
can test and debug the module you are working on before going
on to write the rest of the program.

To let the user append and edit data, 439


create a custom data-entry screen in a hie with an .FMT exten¬
sion. Then use the command SET FORMAT TO followed by
APPEND to let the user add data or followed by some module
that looks up the record to be edited (this module should be fol¬
lowed in turn by EDIT to let the user edit a record). Include
help lines in the data-entry screen telling the user how to move
among fields, page among records, end data entry, and so on.

To write a module that looks up a record, 440


you must get the name to look up from the user, loop through
all the records that match, and ask for verification. If there is no
match, you must make sure that EOF() is true, so the calling
program knows that the name was not found.

To let the user create reports and mailing labels, 450


use the report and label layout windows to define the report
forms and label forms that you want. Then write menu systems
that let the user select among these report and label forms.

To make sure that fields fit into label forms, 454


use the function SUBSTR( K char exp, num expl > [, num exp2]) to
truncate fields that are too long. This function returns a sub¬
string of the specified character expression that begins with the
character indicated by the first numerical expression. If
the optional second numerical expression is included, it spe¬
cifies the length of the substring.

To export data to text files, 464


use the command COPY TO Kfile name> TYPE Kfile type>.
The specified hie type may be SDF to create an ASCII text hie
where records have a fixed length and there is a new line at the
end of each record, or it may be DELIMITED to create an
ASCII text hie where character helds are surrounded by quota¬
tion marks and helds are separated by commas, or it may be
DELIMITED WITH < character > to other delimiters besides
commas between helds.
422 MASTERING FOXPRO

CH. 11

IN THIS CHAPTER, YOU WILL WRITE A COMPLETE


mailing list application using the FoxPro commands and program¬
ming techniques that you learned in previous chapters. This applica¬
tion could act as a stand-alone program to let a user

• keep track of a list of names and addresses

• print mailing labels and reports

• export names and addresses to a text file so that they can be


used by many word processing programs to perform mail-
merge (inserting the names and addresses in form letters)

You will write the entire program in this chapter, but you will
write it in a fairly simple form. In the next chapter, you will modify
the program using some more advanced techniques. Even the basic
techniques used in this chapter, though, are enough to make you
capable of useful FoxPro programming. In fact, much of the work
that programmers do with dB ASE compatible languages is very simi¬
lar to what you will do in this chapter—setting up an application to
make it easy for the user. The programmer creates the database,
indexes, report, and label forms, and then writes a simple menu sys¬
tem to tie them all together.
FoxPro and other dBASE compatible languages are also used to
develop commercial programs. In these cases, programmers would
want to use pop-up menus and windows to create an impressive
interface, but these features are not really needed in the basic applica¬
tions that you would set up for most users.
The program you will write in this chapter, then, is a general-
purpose mailing list program that anyone can use, rather than an
application that is specific to a particular client, which (for example)
would support only that client’s label forms. The techniques you use
in this chapter are commonly used to program basic applications for
people who have acquired FoxPro or another dBASE compatible
program and who want to get down to their business without taking
the time to learn the program.
Finally, the program uses a stripped-down dialect of the Fox-
Pro/dBASE language, which you can use to write programs with
most dBASE compatible languages. You will see in the course of this
chapter how much easier the application is to use than FoxPro itself.
WRITE YOUR OWN PROFESSIONAL MENU APPLICATION 423

ANALYSIS _
Before you begin programming, you must analyze the problem you
are dealing with. Professional programmers who are computerizing a
business must go through a long process of analysis. Usually, they
begin by analyzing all the paper forms the business uses, and organiz¬
ing the data kept on all these forms into a single data “dictionary.”
Once they have the data listed in one place, they can see how it should
be normalized: generally, a problem this complex requires a relational
database. Before programming, they often use data flow diagrams to
show what department or what report uses each element of data. The
data flow suggests how their programs should be organized. In short,
programmers generally gather and analyze a tremendous amount of
information before they write even a line of code.
Of course, this mailing list application is simple enough that the
analysis can be relatively brief. Even with a simple application,
though, you should outline the program in writing before doing any
programming. An excellent way of doing this, which you will use in
this chapter, is the structure diagram. As you will see, this diagram
sketches out the basic functions that the program must perform and
thus gives you an idea of how the program should be broken down
into procedures.
First, though, you should consider the database file and indexes
that the program must use. We can call the file MAILLIST.DBF.
The fields that it needs are fairly obvious: in addition to name and
address, the program should also keep track of telephone numbers, to
make it a complete address book program. Thus, the fields that are
needed are

• Mr., Mrs., Ms., or an honorific

• first name

• last name

• company name
• address

• city

state
424 MASTERING FOXPRO

CH. 11

• zip
• telephone number

Even when the data is this simple, you should list it in writing as part
of your analysis. If you just start programming without analysis, it is
very easy to forget, for example, that you need an honorific in this
program. When you create the structure diagram and think about
exporting the data for mail-merge, however, you will be reminded
that your user may want to begin a letter with the salutation Dear
Mr. So-and-So, Dear Ms. So-and-So, or Dear Prof. So-and-So, and
that it is impossible to do this unless you have a separate held for title
or honorific.
As you can see, analysis is a dynamic process. Things that you do
in the later stages of analysis make you think about and maybe
change the things you have already done in earlier stages of analysis.
As I mentioned, it is best to put everything in writing in advance: it is
much easier to change written notes before you begin programming
than to change the code you have already written. It is very disturb¬
ing to suddenly realize, when you are in the middle of a project, that
you left a held out of your database, and that you have to redesign
your data-entry screens and reports and perhaps also rewrite many
procedures in your program.
Make key decisions during analysis. Should this program have a
held for notes? Should it have two lines for the address?—or should
you assume that the user can use the company name line for the hrst
line of a two-line address? The time to think about these things is
before you begin programming: make a decision that you can stick
with, because it becomes more and more difficult to change as the
project progresses.
One important question is how to handle deleted records. An
extreme solution would be to let the user recall deleted records until
they are packed, as you can with FoxPro itself. This is a bit confusing
for a simple program such as this one, though. At the other extreme,
you could SET DELETED ON so deleted records cannot be used,
and you could automatically PACK the records at some time (for
example, whenever the user exits from the program), then the user
would not even know about packing and would have the impression
that records were permanently deleted as soon as they made that
WRITE YOUR OWN PROFESSIONAL MENU APPLICATION 425

selection from the menu. This option has the disadvantage of wasting
time by packing unnecessarily, though: if you had a large database, it
could take a long time to quit the program.
Though there are arguments for both of the preceding options, this
program will take a middle course: it will SET DELETED ON, so that
the user will not be able to access deleted records, and will also pro¬
vide for a menu option to finalize deletions, so that there will not be
any time wasted. This feature would have to be explained to the user;
if this were an actual commercial program, it would be explained in
the documentation.
It should be fairly obvious to you what indexes you will need for
this program. Users will want to produce reports in alphabetical
order and to produce mailing labels in zip code order (if the program
is to be used for bulk mailing). Which of these indexes the pro¬
gram should generally use as the main index will become more clear
when you create the structure diagram.

MAKING A STRUCTURE DIAGRAM


The structure diagram simply shows all the programs or proce¬
dures that make up the entire mailing program, diagrammed in a
way that makes it obvious how they are related to each other. The
main menu is at the top of the structure diagram for this program:
when the program starts, it presents the user with a menu of the basic
functions that the program performs. Each choice from the main
menu calls another module of the program, which displays a submenu
with choices.
To organize the menu system, we can divide the program’s func¬
tions into four parts:

• Data: lets the user add, edit, look up, or delete records

• Reports: creates printed reports, Rolodex cards, and the like


• Labels: creates a variety of different mailing labels

• Export: creates text files to be used for mail merge

Since each of these presents the user with a menu, we can call them
DATAMENU.PRG, REPTMENU.PRG, LABLMENU.PRG
and EXPTMENU. PRG.
426 MASTERING FOXPRO

CH. 11

These options give us the first cut at a structure chart, shown in


Figure 11.1. Note that the structure chart shows graphically how
these modules are related to each other—that the main menu calls the
other menu programs. Of course, the main menu would also need an
option that lets the user quit the program, but this need not be
included in the structure chart, because it does not require using a
separate program or procedure.

Figure 11.1: The first step in creating the structure chart.

Now, what else needs to be added to this structure chart? In this


first version of the program, you will use a simple technique to let the
user add or edit data: you will use the command SET FORMAT plus
APPEND or EDIT to modify the database file. Thus, DATA-
MENU.PRG needs to use a format file.
In addition, the program must let the user look up a name and pro¬
vide for editing or deleting the record for a given name. In any case,
the program must ask the user for the name, must search for that
name in the file, and must display an error message if the name can¬
not be found.
When the same series of steps must be used more than once in the
program, that is the clue to put those steps in a separate module. Put¬
ting repetitive steps in a separate program or procedure saves some
time when you are writing the program, and it saves a tremendous
amount of work if you need to modify this feature of the program and
to keep it consistent whenever it is used. Thus, in light of the previous
WRITE YOUR OWN PROFESSIONAL MENU APPLICATION 42 7

discussion on looking up names, you should add a procedure (that


you can call LOOKUP), which will be used by DATAMENU for
looking up, editing, and deleting records.
The Report menu should let the user produce an alphabetical list¬
ing of the names, addresses, and telephone numbers in the mailing
list; you can create this report using the report generator. In addition,
you should create a report that includes only names and telephone
numbers, since this is something that users commonly need. Fox¬
Pro’s mailing label generator lets you print out data on 4" x 21/4,/ or
on 3" x 5" Rolodex or index cards, and you can also give these
choices to the user as options on the Report menu.
The Label menu should simply give the user the choice of creating
as many different size labels as possible, since this is meant as a
general-purpose program to be used by many users. We will let the
user choose among all the label forms that are currently listed as stan¬
dard forms by the FoxPro label generator. In an actual application,
you might want to add even more label forms, since the user will not
be provided with the tools to create custom forms.
Finally, the Export submenu will simply use the COPY command
to copy the database to a text file. In an actual application, you would
also add special procedures to export the data in the forms needed by
popular word processors. In this sample program, though, the
EXPORT menu does not need to call any procedures: it will simply
include a number of COPY commands.
Our analysis, then, finally gives us the structure diagram shown in
Figure 11.2. When you study this diagram it will become clear which
index is most important. Virtually all of the modules do better with
the names in alphabetical order: for example, it is best to have the
records in alphabetical order to modify them (so the user can find a
name by paging through them), to look them up (so you can do
a faster search using SEEK), to export names (in mail-merge files—
in alphabetical order), and to produce alphabetical reports. The only
exception is the Label menu, which should use records in zip code
order. Thus, it is best to open the file with the NAMES index as the
main index when the program begins. You should make the ZIPS
index the main index only when the user produces labels—and, to
avoid confusion, you should make the NAMES index the main index
again as soon as the user is done producing labels.
428
CH. 11
MASTERING FOXPRO

re 11.2: The final structure diagram.


WRITE YOUR OWN PROFESSIONAL MENU APPLICATION 429

You can also see by looking at the structure diagram that this pro¬
gram is moderately complex. It would be difficult to start writing a
single program file that does all these things, as they used to do in the
days before structured programming. The structure diagram, though,
breaks it up into small pieces, each of which is easy to understand and
relatively easy to write the program for.

THE MAIN MENU _

In a more complex program, there would be further formal analy¬


sis for each procedure. Often, this analysis would involve writing
pseudocode, an outline of the exact step-by-step method that the final
program will use, but written in plain English, with some of the
details left out so that it is easy to follow. Pseudocode can often be
translated into the final programming code rather easily.
In a program this simple, written in a programming language that
is very much like plain English, more formal analysis is not neces¬
sary, but you do need to think about exactly what the main menu

B An easy way to
create an attractive
module will do before you write it.
To begin with, it should display a title screen, with the program
title screen is to draw it
name and copyright. If you were writing a commercial program, you
with an editor that lets might use an editor that lets you use line-drawing characters to create
you use line characters. the title screen: making the letters out of the line characters can give
Then, when you have the
you an attractive title. Here, though, you can simply display the pro¬
title screen that you want,
just add an @ . . . SAY gram’s name and copyright using regular characters in the center of
statement at the beginning the screen.
of each line—begin¬
While the user is looking at the title screen, the program should
ning with @ 0,0—to
display the screen row by
USE the database file and index files, creating a slight delay before
row. Of course, you must the main menu appears; you can also use a delaying loop to make
use quotation marks to doubly sure the user has enough time to read the title screen. The
enclose what you have
drawn on each line,
program code that is listed makes the loop count up to 200, but if you
including any blank have a fast or a slow computer, you may want to use a higher or lower
spaces that are needed. number. At the same time, the program should SET environmental
variables: for example, you should SET TALK OFF, so that FoxPro
talk does not confuse the user.
430 MASTERING FOXPRO

CH. 11

Then, you can display the main menu with a heading at the
top; the four choices on the structure diagram, plus Quit; and a line
near the bottom asking the user to enter a choice. You will use a con¬
ventional menu program—a series of @ . . . SAY statements to dis¬
play the options and get the user’s choice, followed by a DO CASE
statement that makes the program perform some action that depends
on the choice that was entered. This menu program must be in a DO
WHILE loop, so that the menu screen is displayed repeatedly as long
as the user does not select Quit.
Under ordinary circumstances, you would probably use the Fox-
View screen generator to create the menu screen, so that you can
center the choices easily and use graphic characters to add boxes. As
an exercise, though, you will write this menu by hand, using a series
of @ . . . SAY commands: you should get experience with writing
these programs before you get in the habit of generating them, just as
you should learn to do arithmetic problems by hand before you start
using a calculator.
To make it easy for the user to enter choices, you use the first letter
of each choice as the entry. If you use an @ . . . SAY . . . GET state¬
ment to get the choice, and if you define the variable that the
statement “GETs” as just one character long, then the user can just
press a single key to make the choice, without pressing Enter after¬
wards. Because this keystroke fills up the field, FoxPro beeps and
goes on without waiting for the user to press Enter, just as it does
when you are doing data entry in a Browse window.
This makes it very convenient to move up and down a menu tree,
but the beeps are a distraction when you are using the menu. When
you are setting the environmental variables, then, you should also
SET BELL OFF. Then you can make the menu system beep only if
the user makes an error, by using the command ? CHR(7). Of
course, the beep is useful when you are doing data entry, so that you
know if you have filled a field; thus, you should SET BELL ON when
the user is modifying the data (but SET BELL OFF again after that
is done).
Finally, just before the user quits the program, you should return
all the environment variables to their default setting, using the com¬
mands SET TALK ON, SET BELL ON, and SET DELETED OFF. If
someone is using this program as an application within FoxPro,
rather than as a stand-alone application, they probably want the
WRITE YOUR OWN PROFESSIONAL MENU APPLICATION 431

environment to be back at its default settings when they are through


with it: you do not want to leave them with the Deleted setting on, for
example, because they might inadvertently overlook records that are
marked for deletion at a later time, when they are working with
another database. Remember when you are testing this program that
if you have to interrupt it by pressing Esc, the environment settings
that the program has created will still apply.
This program uses a
conventional form of
capitalization meant to
make it easier to read. The
capitalization of com¬ **************************************************
mands, functions, and the * MAINMENU.PRG
* The main menu for Mail Power
names of fields and vari¬ **************************************************
ables does not actually
* -display the title screen
affect the way the program CLEAR
runs. Only the capitaliza¬ § 11,34 SAY "MAILPOWER!"
@ 14,14 SAY "copyright: Advanced Technology Development Systems"
tion of string literals is
significant.
* -use database and set environment
USE maillist.dbf INDEX names, zips
SET TALK OFF
SET BELL OFF
SET DELETED ON

* -delay to let user read screen


counter = 0
DO WHILE counter < 200
counter = counter + 1
ENDDO

* -create the main loop, to repeat the menu indefinitely


DO WHILE .T.

*-create a variable to hold the user's choice


choice = " "

* -display main menu and get user's choice


CLEAR
@ 0,0 SAY "MAILPOWER! Main Menu"
@ 0,70 SAY DATE()
@ 1,0 SAY " »;
+ •' ti

@ 8,25 SAY "D - Data" ~


@ 10,25 SAY "R - Reports"
@ 12,25 SAY "L - Labels"
@ 14,25 SAY "E - Export for mail merge"
@ 16,25 SAY "Q - Quit MAILPOWER!"
@ 22,26 SAY "What is your choice > " GET choice PICT "!"
READ

* -perform option that user chose


* -or beep if choice was invalid
DO CASE
CASE choice = "D"
DO datamenu
CASE choice = "R"
DO reptmenu

Figure 11.3: The Mail Power! main menu program.


432 MASTERING FOXPRO

CH. 11

Figure 11.3: The Mail Power! main menu program, (continued)

Look carefully at how the main loop of this program works, since
you will see the same sort of thing very frequently in FoxPro and
other dBASE compatible programs. It is an infinite loop, with the
condition DO WHILE .T. at the top. The only way to get out of it is
by pressing Qto execute the command EXIT, which directs program
control to the line following the ENDDO.
If you press another key instead of Q, either the OTHERWISE
statement will beep or one of the CASE statements will execute a
related program, depending on whether your choice was invalid or
valid. Then, program control will be move to the next line after the
ENDCASE of this DO CASE statement. That line is ENDDO, the end
of the main loop, which directs control back to the beginning of this
DO WHILE loop and displays the menu once again.
You will avoid a couple of common errors when you write this sort
of program if you remember that the commands CLEAR and choice
= “ ” must be inside the main loop. The variable choice must be
made equal to a blank each time around, otherwise the value that it
was given the last time through the loop would be displayed by the
command GET choice, and the field where you enter your choice
would not be blank. Of course, the screen also must be cleared each
time the menu is displayed; otherwise the menu will just be superim¬
posed on whatever was on the screen previously.
WRITE YOUR OWN PROFESSIONAL MENU APPLICATION 433

Remember, also, to use GET with PICT “!” in this sort of menu
system, so the user can enter the letters in upper or lower case.
This menu could use a loop with the condition DO WHILE choice
< > “Q” instead of the infinite DO WHILE .T. loop. If you do this,
you would have to initialize the value of choice twice—once before the
loop begins, so the condition is true the first time the program comes
to the DO WHILE statement, and once within the loop, so choice is
made a blank each time around. DO WHILE .T. saves you a tiny bit
of typing. What is much more important, though, is that most people
find that the DO WHILE .T. loop makes the program easier to fol¬
low. You can easily see what happens when the user selects Q,
because it is right there next to the other selections in the DO CASE
statement. There is no need to search for the beginning of the loop to
find what choice lets the user get out of it—and this can be a signi¬
ficant advantage if you are trying to understand a long program.
It is also possible to use the commands following ENDDO within
the DO CASE statement, following CASE choice = “Q”. The pro¬
gram uses the command EXIT if the user selects Q,, in order to break
out of the loop and get to the commands that follow ENDDO. But
why not save a line of code by putting those commands right in the
DO CASE, where EXIT is now? The reason is, studies of structured
programming have found that programs are easier to understand if
control terminates at the end of each module. Though there may be
cases where it is best to put RETURN or QUIT somewhere in the
middle of a module, it does make the program harder to understand
and maintain.
You can see the advantage in this example. To begin with, the pro¬
gram has an asterisk before QUIT, to make it a comment. When you
are testing and debugging the program, you do not want to quit Fox¬
Pro and return to DOS each time you finish running it, because you
need to use FoxPro to modify and retest it. When you are done with
testing, though, you could delete the asterisk so QUIT is executed and
the program returns the user to the operating system when it is done,
rather than returning to FoxPro. Thus, you could make the program
act as a stand-alone program rather than just an application within
FoxPro. It obviously will be easier to make this change because QUIT
is on the last line. Likewise, if you add any other environment settings
in the course of developing the program, it is very easy to set them off
by adding the commands at the end of the program.
434 MASTERING FOXPRO

CH. 11

STUB TESTING _

Just as it is difficult to write a program all at once, it is also difficult


to test a program all at once. If you wait until all of your modules are
written before doing any testing, you will probably spend more time
than you would like wondering which module has the bug that is
making it come out wrong.
MAINMENU.PRG calls four submenu programs. To test it
without actually writing all the submenu programs (and all the pro¬
grams that they call), it is common to write stubs. A stub is a “place¬
holder” program that does something trivial to let you test the
program without having to write the entire module it substitutes for.
For our testing purposes we will write stubs which have the same
names as the submenus but which just clear the screen and ask you to
press any key. After you make sure the main menu works properly,
you will replace the stubs with the actual programs that are needed.
Then, in the next sections, we will stub test the routines the submenu
programs call.
First, you must create the database and index files that this pro¬
gram needs. To avoid confusion, you should create a new subdirec¬
tory to hold your work.

1. If necessary, start FoxPro; if you want, enter CLEAR to clear


the screen. To create anew subdirectory, enter the command
RUN MD \MAILPOW. To make that into the current direc¬
tory, enter the command RUN CD \MAILPOW. Now, new
files you create will be in the MAILPOW directory.
2. Select New from the File menu. Select the Database radio
button and select OK. Use the Structure dialog box to create
a new database file with the structure shown in Figure 11.4.
When you are sure the structure is correct, select OK.

3. Create the two indexes you need: Enter the commands

INDEX ON ZIP TO ZIPS


and then enter the command

INDEX ON LNAME + FNAME TO NAMES


If you prefer, you can use the menu system to create the same
indexes. Notice that it is not necessary to use UPPER
WRITE YO UR OWN PROFESSIONAL MENU APPLICATION 435

System File Edit Structure

Structure: C:\MAILP0W2\MAILLIST.DBF
Name Type Width Dec
Field
* HONORIFIC Character 5
t FNAME Character 15 <Insert>
t LNAME Character 20
t COMPANY Character 50 <Delete>
t ADDRESS Character 50
t CITY Character 20
t STATE Character 2
t ZIP Character 5 ■ < OK - ■
t PHONE Character 13
<Cancel>

Fields: 9 Length: 181 Available: 3819

Figure 11.4: The structure of the Mail Power! database file.

(LNAME + FNAME) as the key to your index: because data


entry will only be done through this program, you can make
sure that all data will be entered in uppercase.
4. Create the main menu program. Select New from the File
menu. Select the Program radio button, and select OK.
Type in the entire listing of MAINMENU.PRG shown in
Figure 11.3, in the previous section. When you are done,
select Save As from the File menu. Name the program
MA1NMENU.

5. Create one of the stub programs, shown in Figure 11.5, for


testing: Instead of using the menu system, as above, to create
the program hie, enter the command MODI COMM DATA-
MENU to open an edit window with the title DATA-
MENU.PRG at the top. Each stub program has just two
lines of code (plus a heading), as shown in Figure 11.5. When
you have entered this code, select Save from the File menu.
6. Create the three other stubs needed for testing. For each one,
just change the heading of this program so it has the appro¬
priate name, then select Save As from the File menu and save
436 MASTERING FOXPRO

CH. 11

***********************************
★DATAMENU.PRG
*stub for testing
★called by MAINMENU.PRG
***********************************

CLEAR
WAIT

***********************************
★REPTMENU•PRG
★stub for testing
★called by MAINMENU.PRG
***********************************
CLEAR
WAIT

***********************************
★LABLMENU.PRG
★stub for testing
★called by MAINMENU.PRG
***********************************
CLEAR
WAIT

***********************************
★EXPTMENU.PRG
★stub for testing
★called by MAINMENU.PRG
***********************************
CLEAR
WAIT

Figure 11.5: Stubs for testing.

it under the name REPTMENU.PRG, LABLMENU


.PRG, and EXPTMENU.PRG, respectively. These pro¬
grams are also shown in Figure 11.5.

7. Now you are ready for testing. Enter DO MAINMENU. The


Main Menu screen should appear, as shown in Figure 11.6.
Try all the menu choices. Try some invalid choices also to see if
the program beeps. If there are errors, select Cancel to stop exe¬
cution of the program (if necessary, press Esc), and edit the pro¬
gram file to correct the error. Once you have made the
correction, enter DO MAINMENU again. After each correc¬
tion, redo all your testing, as if you were starting from scratch.
When you are done, press Qto quit.
WRITE YOUR OWN PROFESSIONAL MENU APPLICATION 437

MAILPOWER! Main Menu 03/15/91

D - Data

R - Reports

L - Labels

E - Export for mail merge

Q - Quit MAILPOWER!

What is your choice > |

Figure 11.6: The Mail Power! Main Menu screen.

Keep testing the program until you are sure this module runs cor¬
rectly. Since you are testing just one module, and its logic is quite
straightforward, it should be easy for you to correct any bugs.

THE DATA SUBMENU _

When you look at your structure chart, you will notice that you
need to create and test the Data submenu next. After all, you cannot
actually test the Report, Label, or Export modules until you have
used this one to add data to the file.
This module itself calls two other modules, a screen format (which
it uses for appending and editing data) and a LOOKUP program
(which it uses for looking up, editing, and deleting records—when
the user must ask for a specific record—but not for appending data).
Obviously, you must have some data before you can edit or delete
any. For the purposes of testing, then, you can begin by writing the
.FMT program that lets you enter data, and writing just a stub of
the LOOKUP program. This allows you to test the Data submenu
itself and to use it to add data. Then, after you have added data, you
will write and test the actual LOOKUP program.
438 MASTERING FOXPRO

CH. 11

First, you must create a new program file DATAMENU.PRG.

You might find it 1. Enter RUN DEL DATAMENU.PRG to delete the stub you
easiest to create this created earlier.
program by editing the
file MAINMENU.PRG 2. Create a new program file and enter the code for the Data
and then saving it with submenu in it, as it is listed in Figure 11.7. The menu screen
the changes that you have
is shown in Figure 11.8. As you can see, this menu is very
made, under the name
DATAMENU.PRG. Be similar to the menu that you created previously.
sure to select Save As
from the File menu when
you are done: if you select
**************************************************
Save, you will overwrite
*DATAMENU.PRG
the previous program. *The Data submenu for Mail Power
♦called by MAINMENU.PRG
**************************************************
*-create the main loop, to repeat the menu indefinitely

DO WHILE .T.

* -create a variable to hold the user's choice


choice = " "

* -display the menu and get user's choice


CLEAR
@ 0,0 SAY "MAILPOWER! Data Submenu"
@ 0,70 SAY DATE()
@ 1,0 SAY "_
II »

@ 8,25 SAY "A - Add a new entry"


@ 10,25 SAY "E - Edit an entry"
@ 12,25 SAY ”D - Delete an entry"
@ 14,25 SAY "L - Look up an entry"
@ 16,25 SAY "F - Finalize deletions"
@ 18,25 SAY "R - Return to the Main Menu"
@ 22,26 SAY "What is your choice > " GET choice PICT "!"
READ

* -perform option that user chose


*~-or beep if choice was invalid
DO CASE
CASE choice = "A"
* -append using custom format screen
SET BELL ON
SET FORMAT TO datascrn
APPEND
SET BELL OFF
SET FORMAT TO
CASE choice = "E”
* -find record user wants and edit
* -using custom format screen if found
DO LOOKUP
IF .NOT. EOF()
SET BELL ON
SET FORMAT TO datascrn
EDIT
SET BELL OFF
SET FORMAT TO
ENDIF
CASE choice = "D"
* -Find record user wants and get

Figure 11. 7: The code for the Data submenu.


WRITE YOUR OWN PROFESSIONAL MENU APPLICATION 439

* -confirmation before deleting it if found


DO LOOKUP
IF .NOT. EOF()
confirm = " "
@ 16,10 SAY "Are you sure you want to
+"delete this record (y/n)? " GET confirm
READ
IF UPPER(confirm) = "Y"
DELETE
dummy = " "
§ 20,7 SAY "The record has been
+"deleted. Press any key to
+ "continue..." GET dummy
READ
ENDIF
ENDIF
CASE choice = "L"
* -use LOOKUP to look up and display the entry
* -if found, get confirmation before going on
DO LOOKUP
IF .NOT. EOF()
dummy = " "
§ 16,16 SAY "Press any key to return to
+"the menu... " GET dummy
READ
ENDIF
CASE choice = "F"
CLEAR
@ 12,15 SAY "One moment please..."
PACK
CASE choice = "R"
EXIT
OTHERWISE
? CHR(7)
ENDCASE

ENDDO
RETURN

Figure 11. 7: The code for the Data submenu, (continued)

The logic of this module should be fairly easy to understand. The


basic structure of the menu itself is just like the Main menu.
The options are displayed using @ . . . SAY statements and the
choice is executed using a DO CASE statement; this process is
repeated until the user selects R, because it is nested in an infinite DO
WHILE loop. The only difference from MAINMENU is that it
returns to the program that called it (MAINMENU.PRG) rather
than quitting when you make this selection.
To understand the commands that it executes when you select var¬
ious options, you must imagine that you have written a format screen
named DATASCRN.FMT. To add data, the program uses the
command SET BELL ON, so that the program beeps if the user
comes to the end of a field while doing data entry. Then it uses the
commands SET FORMAT TO datascrn and APPEND, so the user
440 MASTERING FOXPRO

CH. 11

Figure 11.8: The Data submenu screen.

can add data using this custom screen. When the user is done
appending and presses Ctrl-End or Ctrl-Q, control returns to the
program. Then, the command SET BELL OFF stops the program
from beeping when you make your next menu selection. The com¬
mand SET FORMAT TO closes the format file, so the DATASCRN
format does not interfere with any of the program’s later commands:
an active format file can cause trouble whenever you do formatted
input/output, so it is always best to close it as soon as you are done
with it.
Other options in this menu assume that you have a LOOKUP
program, which lets the user enter the name being searched for, uses
a SEEK command to find it in the database, and displays the names it
has found until it has either displayed the right one or run out of
matching names; if the record is not found, the LOOKUP program
makes sure that EOF() has the value of .T.
If the user selects Edit, the program uses LOOKUP to find the re¬
cord that should be edited. If it finds it, the pointer is on that record,
so this program can use the commands SET BELL ON and SET
FORMAT TO datascrn as well as EDIT to edit the current record—
much as the previous option used SET BELL ON and SET FORMAT
WRITE YOUR OWN PROFESSIONA L MENU APPLICATION 441

TO datascrn and APPEND to add a new record. If LOOKUP does


not find the record, then EOFQ is true, so this program does not do
anything; LOOKUP will already have displayed a message saying
the record cannot be found.
Likewise, if the user selects Delete, this program uses LOOKUP.
If LOOKUP finds the record, this program asks for confirmation
before deleting it. Then, if the user enters Y, it deletes the record and
displays a message telling the user it has been deleted; if the user does
not enter Y, it does nothing. Again, if LOOKUP does not find the
record, then EOF() is true, so this program does not do anything,
and LOOKUP will already have displayed a message saying that the
record cannot be found. Notice the nested IFs that are used here:
the program gets confirmation only IF the record is found, and then
it deletes the record only IF the user enters Y.
If the user wants to look up an entry, this program simply uses
LOOKUP, which either displays the entry that is wanted or displays
a message saying it cannot be found. If LOOKUP does find the
entry, the commands following IF .NOT. EOF() are executed, in
order to give the user a warning before the entry that is being looked
up disappears from the screen.
If the user selects Finalize Deletions, the program simply displays a
message saying to wait a moment and uses the command PACK to
finalize the deletions. It is always good practice to display some sort of
message telling the user to wait when the program does something
that might take time: otherwise, users tend to think that something is
wrong, that the computer has stopped working and is doing nothing.
Finally, if the user chooses Return, the program exits from this
loop, and goes directly to the optional RETURN command following
ENDDO, which makes it return to the MAINMENU program that
called it; it would also return if it simply reached the end of the pro¬
gram. RETURN is used only for the sake of clarity.
If none of these valid choices are selected, the program executes
the command following OTHERWISE and beeps; then it reaches
ENDDO, which makes it loop back up to DO WHILE and display this
menu again.
You should bear in mind that a module this complex cannot be
developed in the polished form that you see here in just one try. If you
were actually developing a program, you would write some approxi¬
mation of this module. Then, you would test it with a stub of
442 MASTERING FOXPRO

CH. 11

LOOKUP and get it running, and you would probably want to


make some changes in DATAENTR as a result of the stub testing,
to make the screen look more attractive. Then, when you wrote the
actual version of LOOKUP, you might find that the program as a
whole would be more user-friendly with some additional changes in
the DATAMENU module. And making these changes might start
you thinking about changes in the LOOKUP module. Though
DATAMENU.PRG is presented here in a final form to save time, in
reality programming is a learning process: you should be prepared to
play with the program to get it working, and to play with it more
to make it better.
Before testing DATAMENU.PRG, you need to write the two
modules that it calls, DATASCRN.FMT and at least a stub of
LOOKUP. PRG.

THE SCREEN FORMA T


First write the format file, DATASCRN.FMT. In an actual pro¬
gramming application, you would undoubtedly use the screen genera¬
tor to create this format file, so you could place the fields attractively,
center the help lines, add graphics, and compose as good-looking a
screen as possible. As with the menu screens, though, you should try
writing this screen by hand as an exercise, so you learn how to create a
format file.
To make it easier for you to type this format file, the listing in Fig¬
ure 11.9 uses the hyphen and pipe (j) characters (from the upper right
of your keyboard) to draw boxes; the screen it will create is shown in
Figure 11.10. In actual program development, it would take a num¬
ber of tries before you got it looking right. In the days before screen
generators, experienced database programmers used to turn out this
sort of quick-and-dirty screen format program in about a half an hour
of work. Notice how easy it is to add the box with the help lines at the
bottom of the screen.

A STUB OF LOOKUP.PRG FOR TESTING


As you have seen, the final version of the LOOKUP program that
this program calls will search for the name that the user enters and, if
WRITE YOUR OWN PROFESSIONAL MENU APPLICATION 443

**************************************************
* DATASCRN.FMT
* format for appending, editing, and displaying data
* called by DATAMENU.PRG
**************************************************
@ 0,0 SAY "MAILPOWER!"
@ 0,70 SAY DATE()
@ 1,0 SAY "_

@ 3,0 SAY "Title:" GET honorific PICT "@!"


@ 3,15 SAY "First name:" GET fname PICT
@ 3,45 SAY "Last name:" GET lname PICT
@ 5,6 SAY "Company:" GET company PICT
@ 7,6 SAY "Address:" GET address PICT "@!"
@ 9,6 SAY "City: " GET city PICT " @ "
@ 9,38 SAY "State:" GET state PICT "@1"
@ 9,50 SAY "Zip code:” GET zip PICT "99999"
@ 11,25 SAY "Telephone:" GET phone PICT "(999)999-9999"
@ 14,15 SAY
@ 15,15 SAY <- -> : Move cursor within field
@ 16,15 SAY
§ 17,15 SAY Tab Shift-Tab : Move cursor to next/last field
@ 18,15 SAY
@ 19,15 SAY PgDn PgUp : Move to next/last record
@ 20,15 SAY
§ 21,15 SAY Ctrl-End : Quit and save changes
@ 22,15 SAY
@ 23,15 SAY Ctrl-Q : Quit and discard changes
@ 24,15 SAY

Figure 11.9: The format program for editing, appending, or deleting records.

Figure 11.10: The data-entry screen produced by the program in Figure 11.9.
444 MASTERING FOXPRO

CH. 11

it does not find it, will print an error message and make EOF() true,
so that DATAMENU will not actually try to edit or delete the non¬
existent record.
For the purposes of testing, we can use a stub of LOOKUP that
never finds the record it is looking for. With this stub, we can test
DATAMENU.PRO and use it to append records but not to delete or
edit records. After you have appended some sample records, you can
rewrite LOOKUP in its final form, and then you can test it by
searching for some of the records you added earlier and try deleting
or editing them. The program in Figure 11.11 will never find the
record it is looking for because the screen format program makes sure
that all entries are made in capital letters, and this stub seeks a lower¬
case letter.

'k-k-k-k-kick'k-k-k-kitick’k-k'k-k'k-k-k-k-k-k-klc-k-k'k'k-k-k-k’k'k-k-k-k'k'k'k-k-k-k'k'k-k-k-k'k

*LOOKUP.PRG
*stub for testing
*called by DATAMENU.PRG
■k'k-k-k-k'k’k-k-k'k'k-k-k-k-k-k-k-k-k'k’k'klck-kic'k-k'kif-k'k'k'k-k-k'k'kifk-k'kick-k-k-k-k-k-k

*-search for an impossible condition, so EOF() will be .T.

CLEAR
SEEK "a"
? "Record not found."
WAIT

Figure 11.11: A stub of LOOKUP.PRG used for testing purposes.

PRELIMINAR Y TESTING
Now you can test some features of the DATAMENU program.
Make all the selections from the Data menu. Try editing, deleting, and
looking up a record, even though you know that the program will not
find the name you are looking for. Use the menu to add five or six
records. Try adding them using lowercase letters, to make sure all the
fields are capitalized. Try adding letters in the Zip and Phone fields. Be
sure to include at least three records that have the same last name, so
you can use them to test the LOOKUP program, which you add next.
WRITE YOUR OWN PROFESSIONAL MENU APPLICATION 445

THE LOOKUP PROGRAM


Consider in more detail what the final version of the LOOKUP
program must do. First, it lets the user enter a name and use the com¬
mand SEEK to search for it. If it is not found, LOOKUP displays an
error message. If it is found, LOOKUP must display all the data
about the person and ask if this is the right record, since there might
be more than one person with the same last name. If the user answers
yes, the program has succeeded. If the user answers no, the program
must display the next record (if it has the same last name) and ask the
user if this is the right record: it must keep doing so until it finds
the right record or there are no more records with the same name.
Remember that the file is indexed by name, so that all records with
the same last name will be in sequence.
Of course, if the initial SEEK does not find a matching record,
FoxPro automatically makes EOF() equal to .T., as the ordinary
side-effect of the SEEK command.
On the other hand, if the initial SEEK finds a matching record but
it is not the one that the user wants, and if the succeeding records also
do not contain the record that the user wants, then LOOKUP itself
must make EOF() equal to .T. If you were using LOCATE and CON¬
TINUE, EOF() would automatically be true when there is no match,
but you want to use SEEK for speed—in case there is a large mailing
list—and so you cannot use CONTINUE. Instead, you make EOF()
true when there is no match by using the commands GO BOTTOM
followed by SKIP.
Whenever there is no match, EOF() is made true, so the program
that called LOOKUP is then able to use the EOF() function to see if
the record was found.
Now that you have the basic idea of what LOOKUP must do,
enter the code for this module, as shown in Figure 11.12. Study the
code while you read the following description of the program, so you
can see in detail how the logic of this program works.
First this module clears the screen, prints the usual heading, and
asks the user for the name to look up, as shown in Figure 11.13. It
uses a picture clause to get the name in all capital letters: the help
446 MASTERING FOXPRO

CH. 11

**************************************************
* LOOKUP.PRG
* lookup a record for editing, deleting or displaying data
* called by DATAMENU.PRG
★*************************************************
* -create a variable to hold the name the user wants
mlookfor = SPACE(20)

* -get the name the user wants,


* -or let the user press Enter to quit.
CLEAR
@ 0,0 SAY "MAILPOWER!"
@ 0,70 SAY DATE()
@ 1,0 SAY "_
I M *1

@ 8,8 SAY "Enter the last name of the record you want:";
GET mlookfor PICT "@1"
@ 11,12 SAY "(Enter the entire last name or just the
+"initial letters)"
@ 13,20 SAY "(or press Enter to return to the menu)"

READ

* -If the user presses enter, move the pointer to


* make EOF() true and then return to DATAMENU
IF mlookfor = SPACE(20)
GO BOTT
SKIP
RETURN
ENDIF

* -trim blanks, in case the user did not enter whole name
* -or entered leading blanks by mistake
mlookfor = ALLTRIM(mlookfor)

* -look for the name the user entered


SEEK mlookfor

* -if the name is not found, display an error message


IF EOF()
dummy = " "
@ 16,18 SAY "The name " + PROPER(mlookfor);
+ " is not in the file."
@ 18,21 SAY "Press any key to continue... " GET dummy
READ

* -if the name is found, see if it is the right one


* -put the confirmation in a loop, so you can ask
* -repeatedly for all records with same name
ELSE
DO WHILE .T.
§ 2,0 CLEAR
@ 3,0 SAY "Title: " + honorific
@ 3,15 SAY "First name: " + fname
@ 3,45 SAY "Last name: " + lname
@ 5,6 SAY "Company: " + company
@ 7,6 SAY "Address: " + address
@ 9,6 SAY "City: " + city
@ 9,38 SAY "State: " + state
@ 9,50 SAY "Zip code: " + zip
@ 11,25 SAY "Telephone: " + phone
% 12,0 SAY "_
•• n

Figure 11.12: The module for looking up names.


WRITE YOUR OWN PROFESSIONAL MENU APPLICATION 44 7

mconfirm = " "


@ 14,18 SAY "Is this the record you want (y/n)?
GET mconfirm
READ

* -if the name is correct, exit from the loop and


* -return to the calling program with the pointer
* -on the desired record. If the name is
* -not, check for other records with that name.
IF UPPER(mconfirm) = "Y"
EXIT
ELSE
SKIP
IF lname = mlookfor
LOOP
ELSE
* -if no other records with that name,
* -print error message and make EOF true
dummy = " "
@ 16,18 SAY "The name you want is not in
+"the file."
@ 18,21 SAY "Press any key to continue...

D It will save you


time to edit
READ
GO B0TT
SKIP
GET dummy

EXIT
DATASCRN.FMT ENDIF
ENDIF
in order to create
ENDD0
LOOKUP.PRG. When ENDIF
LOOKUP asks the user
if the record it has found
is correct, this program Figure 11.12: The module for looking up names, (continued)
displays the data in a
form that is similar
lines tell the user to enter all or just the beginning of the name (since
to the one used by
DATASCRN.FMT. you have not SET EXACT ON, FoxPro can find a match with only
This gives the program a some of the letters) and to press Enter to return to the menu (and can¬
consistent feel and looks
cel the command). It is generally a good idea to give users the chance
good when the program
moves from looking up to to cancel a command of this sort, as you no doubt realize if you ever
editing a record. used a program that does not let you cancel.
If the user simply presses Enter, so that the variable that holds the
name is still equal to 20 blanks, the program moves the pointer to
make EOFQ true and then returns to the DATAMENU.PRG; since
EOFQ is true, DATAMENU will not try to delete or edit the current
record. Using RETURN in the middle of a module in this way is not a
perfect example of structured programming, but it is justified,
because it would be so much more trouble to nest the entire module
in a DO WHILE loop just to be able to use EXIT.
If the user does enter a name, this program goes on to trim blanks
from it in case the user entered leading or trailing blanks by mistake;
thus it will just search for the letters entered. Then it seeks that name.
448 MASTERING FOXPRO

CH. 11

The whole rest of the program consists of a large IF/ELSE statement:


what it does depends on whether the seek finds a match or not.
If SEEK does not find the name, the program’s response is simple.
It uses the short list of commands that follow IF to display an error
message saying the name is not found and then returns to the calling
program. Because EOF() is true after an unsuccessful SEEK, the
DATAENTR will not try to edit or delete the current record.
If SEEK does find the name, things are more complicated. The
program must use the long list of commands following ELSE, start¬
ing by displaying all the data from the record and asking the user if it
has found the right person, as in Figure 11.14, since there might be
more than one record with the same name. Notice that all of these
commands are nested in a DO WHILE .T. loop, since the program
may have to ask the question over and over again if there are many
people in the list with the same last name.
Then the program goes one of two ways, depending on whether
the record found is the right one or not.
If the user confirms that this record is correct, the program simply
exits from this DO WHILE loop and returns to the calling program.
If the user was looking up the name, the data has been displayed and
WRITE YOUR OWN PROFESSIONAL MENU APPLICATION 449

MAILPOWER! 03/15/91

Title: MR. First name: SAMUEL Last name: SMITHSON

Company: GENERAL INTERNATIONAL

Address: 4432 INTERNATIONAL PLAZA

City: NEW YORK State: NY Zip code: 10022

Telephone: (415)284-1059

Is this the record you want (y/n)? |

Figure 11.14: The program displays the name and asks if it matches.

nothing else needs to be done, and DATAENTER just asks the user
to press the key to continue. If the user wants to edit or delete, the
pointer is on the right record, and the calling program can do what is
needed.
If the user does want to continue the search for another record with
the same name, the LOOKUP skips to the next record and checks it to
see if it matches. If it does match, the command LOOP sends the pro¬
gram back to DO WHILE .T. so that it displays the data in the new
record and asks the user if it is the right one. The program keeps doing
this until it finds a record that does not match.
When it finds a different name after exhausting all the matching
names in the file, it displays a message saying that a matching record
is not in the file. Then it uses GO BOTT and SKIP to make EOF()
equal to .T., and it exits from the DO WHILE loop so that it returns
to the calling program. As usual, because EOF() equals .T., DATA-
MENU does not try to edit or delete a record.
To sum up, then, if a match was found, the pointer is on the
matching record, so that DATAENTR can do what is needed. If no
match is found, EOF() is true, so that DATAENTR does not do
something foolish.
450 MASTERING FOXPRO

CH. 11

LOOKUP is the most complex program in this section, and it


shows how important it is to indent properly in order to make code
easier to understand. Make sure you can follow its logic: once you
understand it, you know enough about control flow to make FoxPro
do most anything you want it to.
Test this program to make sure that you did not make any mis¬
takes in entry. Try deleting, editing, and looking up existing records
to see how this program interacts with DATAMENU. Note that in
Figure 11.15, for example, the display of the name comes from
LOOKUP and the question about whether it should be deleted
comes from DATAENTR.

MAILPOWER! 03/15/91

Title: MR. First name: SAMUEL Last name: SMITHSON

Company: GENERAL INTERNATIONAL

Address: 4432 INTERNATIONAL PLAZA

City: NEW YORK State: NY Zip code: 10022

Telephone: (415)284-1059

Is this the record you want (y/n)?


*

Are you sure you want to delete this record (y/n)? Q

The record has been deleted. Press any key to continue... |

Figure 11.15: Deleting a record.

REPORTS AND MAILING LABELS _


You have finished the most difficult part of the programming.
Looking at your structure chart, you can see that reports and labels
come next. To add these features, you just need to use FoxPro’s
report and label generator to create the forms you need and also to
write two simple menus programs to tie them together.
WRITE YOUR OWN PROFESSIONAL MENU APPLICATION 451

THE REPORT MENU


The Mail Power! Report menu will let the user print a complete
report that contains all the data in the mailing list, and (since the user
might find it handy) a report with just names and telephone num¬
bers. Since there are standard FoxPro label forms that let you print
out the data on 3 x 5 (index card size) Rolodex cards or on smaller
" "

4" x 2V4" Rolodex cards, you can also give the user these options on
the Report menu.
When you save these forms, there is no need to save the environ¬
ment. The program itself makes sure that the proper database file
and index is in use when the report or labels are produced, so the
REPORT FORM and LABEL FORM commands that the program
uses to produce them will not have to include the ENVIRONMENT
option that makes them use these saved environments.

1. You must create the first two reports by using the report lay¬
out window. The database file should already be in use from
the program testing; if it is not, enter USE MAILLIST. Select
New from the File menu. Select the Report radio button, and
select OK.
2. Select Page Layout from the Report menu. Make the top
margin 6, the bottom margin 6, the printer indent 5, and the
right margin column 75. Then select OK.

3. Move the cursor to the second line of the page header band.
Type MAILPOWER! Complete Report. Press Enter to stop
editing the text and the space bar to select the text object.
Select Center from the Report menu to center it, and press
Enter to deselect it.

4. Move the cursor to the second line of the detail band. Select
Add Line from the Report menu to add a line to the detail
band.

5. Begin entering expressions in the detail band. Select Field from


the Report menu. In the text box to the right of the Expression
text button, enter PROPER(LNAME). Move the cursor so the
width is entered automatically. Then select OK.
452 MASTERING FOXPRO

CH. 11

6. Move the cursor down a line, then move it to the left margin.
Press the right arrow key five times. Select Field from the
Report menu, and, in the text box, enter the expression
PROPER(FNAME) and place it as in Step 5.

7. Move the cursor down a line and to the left margin. Place the
field expression PHONE, as in Step 5.

8. Move the cursor up one line and right to column 21. Use the
menu to place the expression PROPER(COMPANY) as
above.

9. Move the cursor to immediately below the P of PROPER


(COMPANY). Place the expression PROPER(ADDRESS),
as above.

10. Move the cursor immediately below the P of PROPER


(ADDRESS). Place the expression PROPER(CITY). Press
the right arrow key three times and place the expression
STATE. Press the right arrow key three times again and
place the expression ZIP.

11. Move the cursor to the footer band. Select Remove Line
from the Report menu to remove one line. Move the cursor
to the second line of the three in the page footer band and to
the left margin.

12. Now, since the report may be long, you should add page
numbers. Select Expression from the Report menu, then
select the Expression text button to call up the expression
builder. In the text box, type “Page Number ” (do not forget
the quotation marks). Select the String popup control and
select + , select the String popup control again and select
LTRIM(), then select the String popup control once more
and select STR(). From the scrollable list of memory vari¬
ables, select _PAGENO. If you want, select the Verify text
button to make sure the expression is valid. The expression
should look like Figure 11.16. Select the OK text button to
return to the Report Expression dialog box, and select the
OK text button to place the expression. Press the space bar to
select the expression and then select Center from the Report
menu to center it. Press Enter to deselect it.
WRITE YOUR OWN PROFESSIONAL MENU APPLICATION 453

Figure 11.16: The expression to display the page number.

13. You now have the complete report form shown in Figure
11.17. Select Save As from the File menu and, when the Save
Report As dialog box appears, type the name COMPLETE,
select the Environment check box so that it is not checked,
and then select the Save text button to save the file.

14. Now, to create the second report, alter this form so it pro¬
duces a report with just names and telephone numbers.
Remove the second and third line in the detail band by put¬
ting the cursor on them, selecting Remove Line from the
Report menu, and entering Y to confirm that you want to
remove the objects on the lines. Move the cursor to PRO-
PER(COMPANY) and then select and delete this expres¬
sion. With the cursor on column 22, place the expression
PROPER(FNAME). With the cursor on column 40, place
the expression PHONE. Move the cursor to the tide, select
Text from the Report menu so you can edit the title, and
change it to MAILPOWER! Phone Report. When you are
done editing, select this text object and select Center from the
Report menu to center it. Then deselect it.
454 MASTERING FOXPRO

CH. 11

Figure 11.17: The report form for the first report.

15. Select Save As from the File menu. When the Save Report
As dialog box appears, type PHONES in the text box, make
sure the Environment check box is not checked, and select
Save to save the report under this name. The final form of
this report is shown in Figure 11.18. Then close the report
layout window.

USING SUBSTR() FOR FINE-TUNING


The other two reports are created by using the label layout window.
No doubt, you noticed that your first report just barely fit into the width
of the report layout window. This is because some fields of this database
are very long. Since Label forms are generally narrower, you should
shorten some of these fields when you fill out these forms.
You can do this by using the function SUBSTR(), which lets you
use a substring of any character expression. This function has the fol¬
lowing form:

SUBSTR(<char exp, num expl >[<, num exp2>])


WRITE YOUR OWN PROFESSIONAL MENU APPLICATION 455

Figure 11.18: The report form for the second report.

Char exp represents the character expression that you want to use a
substring of. Num expl is a numeric expression that you use to specify
which character you want the substring to begin with. Num exp2 is an
optional numeric expression that you use to specify the length of the
substring; if this expression is omitted, the substring continues until
the end of the string.
For example, the function

SUBSTR(/,abcdefghijkl,,,1,3)

would return the value abc. This substring starts with the first charac¬
ter of the string specified and is three characters long. To give
another example, the function

SUBSTRC'abcdefghijkrjO)

would return the value jkl, since this substring starts with the tenth
character of the string specified and continues to the end.
In the exercises below, you will use this function to make a field fit
in the width of the label form. For example, if the label form is 40
456 MASTERING FOXPRO

CH. 11

characters wide, you will use the function

SUBSTR(PROPER(ADDRESS),1,40)

to enter its address. This function returns a substring that begins with
the first character of PROPER(ADDRESS) and includes 40 charac¬
ters. If the address field is more than 40 characters wide, this function
will simply cut off its final characters, so it fits in the label form.

REPORTS USING LABEL FORMS


The first label form you will use to create a report is wide enough
for all the fields of your database. The second is narrower, though, so
you will need to use SUBSTR0 with it.
In order to center the fields on these label forms, we want to skip a
few lines. Some releases of FoxPro require you to put characters on
the first lines of label forms, and they display an alert saying there is
an error if you try to save the form when these fields are blank. To
avoid this potential problem, the forms will have “ ” on the first line,
a string consisting of the blank character: FoxPro will be satisfied that
you are printing something on that line, even if you are just printing
a blank space.

1. To create the next “report,” select New from the File menu.
Select the Fabel radio button, and select OK. When the label
layout screen appears, select Layout from the Label menu
and select 3" x 5" Rolodex. Then fill out the label layout
screen as illustrated in Figure 11.19. Select Save As from the
File menu, select the Environment check box so it is not
checked, and save the label form, using the name INDEX.

2. To create the next “report,” select 4" x 2V4" Rolodex from the
Label menu. The new label layout will keep the fields that were
there, and you can edit them so they they look like the form
shown in Figure 11.20. Then select Save As from the File
menu, make sure the Environment check box is not checked,
and save the label form using the name ROLODEX.
WRITE YOUR OWN PROFESSIONAL MENU APPLICATION 45 7

System file Fdit. Database Record Program Window Label


____INDfX.ll.iX _

Remarks 5" x 5 Rolodex

Margin Width Number Across


I-9 -1--50 --► 1
« H
M H
TRIM(LNAME) + ", " + TRIM(FNAME)
H COMPANY;
e ADDRESS Spaces
i 14 TRIM(CITY) + STATE + " " + ZIP 4—0 —►
g Between
h PHONE
t

1
t
4- Lines Between
1

Figure 11.19: The label form for the third report.

Figure 11.20: The label form for the fourth report.


458 MASTERING FOXPRO

CH. 11

B To save time and


effort in testing, you
can type && before the
3. To tie these forms together, create the menu using the code
shown in Figure 11.21, which is very similar to the menu
programs you created earlier. (It is probably easiest to create
words TO PRINT to
make them comments for it by editing an earlier menu program and saving it under a
now, as they are in the new name.) Select Save As from the File menu and save it
listing in Figure 11.21,
under the name REPTMENU.PRG, overwriting the file
since you do not want the
reports printed each time you created earlier to hold the stub of that program. The
you test the program. It is menu screen it will create is shown in Figure 11.22.
easy to delete these
ampersands later.

*REPTMENU.PRG
*The report submenu for Mail Power
*called by MAINMENU.PRG
**************************************************
*-create the main loop, to repeat the menu indefinitely

DO WHILE .T.

* -create a variable to hold the user's choice


choice = " "

* -display main menu and get user's choice


CLEAR
@ 0,0 SAY "MAILPOWER1 Report Submenu"
@ 0,70 SAY DATE()
@ 1,0 SAY "_
+"_
@ 8,25 SAY "C - Complete Report"
@ 10,25 SAY "P - Phone Numbers and Names"
@ 12,25 SAY "3-3x5 Rolodex Cards"
@ 14,25 SAY "4-4x21/4 Rolodex Cards"
@ 16,25 SAY "R - Return to the Main Menu"
@ 22,26 SAY "What is your choice > " GET choice PICT
READ

* -perform option that user chose


* -or beep if choice was invalid
DO CASE
CASE choice = "C"
REPORT FORM complete
WAIT
CASE choice = "P"
REPORT FORM phones
WAIT
CASE choice = "3"
LABEL FORM index
WAIT
CASE choice = "4"
LABEL FORM rolodex
WAIT
CASE choice = "R"
EXIT
OTHERWISE
? CHR(7)
ENDCASE

ENDDO
RETURN

Figure 11.21: The Mail Power! Report menu program.


WRITE YOUR OWN PROFESSION A L MENU APPLICATION 459

MAILPOWER! Report Submenu 04/04/91

C - Complete Report

P - Phone Numbers and Names

3- 3x5 Rolodex Cards

4- 4x2 1/4 Rolodex Cards

R - Return to the Main Menu

What is your choice > |

Figure 11.22: The Mail Power! Report menu screen.

4. In the Command window, Enter DO MAINMENU and test


all the new options you have just added.

THE LABEL MENU


After you have finished testing your Report menu, you can create
the Mail Power! Label menu in much the same way. The easiest way
is to create the new label forms by modifying an existing form,
removing what you do not need:

1. Enter MODI LABEL ROLODEX to use the previous form.


Put the cursor on the T of TRIM(LNAME), and press the
Backspace key to delete the previous lines, until the line with
the name is the first line of the form. At this point, Backspace
will no longer have any effect. Then delete the line that says
PHONE, and press Backspace to delete this field name and
to move the cursor until it is on the same line as City, State,
and Zip, but be careful not to delete any of the field names on
this line. Move the cursor back to the line that has the name,
and edit it so it reads

TRIM(FNAME) + " " + TRIM(LNAME)


460 MASTERING FOXPRO

CH. 11

2. Select Layout from the Label menu and select the first standard
format on the list, V/2" x 15/i6" x 1. The fields all remain on
this new form. Since the width of this column is 35, change the
name line to

SUBSTR(TRIM(FNAME),1,14) + " " + TRIM(LNAME)


Likewise, edit the company and address line, so they read

SUBSTR(COM PAN Y, 1,35);


and

SUBSTR(ADDRESS,1,35)
3. Select Save As from the File menu and save this under the
name ONE-COL (since it produces one-column labels).
Make sure not to save the environment.

Notice that the name line was altered so that the first name is trun¬
cated if the name is too long to fit in the label: at most, the name can
consist of 14 characters from the first name, one blank, and twenty
characters from the last name, for a total of 35 characters.
Now, you should continue to produce labels with all the other
default layouts on the label menu. Produce them as you did above,
by selecting the layouts listed below, editing the character expressions
where needed, and selecting Save As from the File menu to rename
them. (The first few will not need editing, as they just use same-size
labels in a two-column and three-column format.)
Use the following names and field expressions:

Layout 3V2" x 15/i6" x 2

Name TWO-COL

Fields SUBSTR(TRIM(FNAME), 1,14) + “ ” +


TRIM(LNAME)

SUBSTR(COMPANY, 1,35)

SUBSTR( ADDRESS, 1,35)


WRITE YOUR OWN PROFESSIONAL MENU APPLICATION 461

TRIM(CITY) + “ ” + STATE + “, ” +
ZIP

Layout 3V2" X 15/l6" X 3

Name THRE-COL

Fields SUBSTR(TRIM(FNAME), 1,14) + “ ” +


TRIM(LNAME)

SUBSTR(COMPANY, 1,35)

SUBSTR( ADDRESS ,1,35)

TRIM(CITY) + “ ” + STATE + “, ” +
ZIP

Layout 4" X l7/i6" x 1

Name LARGE

Fields SUBSTR(TRIM(FNAME) 1,11) + “ ” +


TRIM(LNAME)

SUBSTR(COMPANY, 1,32)

SUBSTR( ADDRESS, 1,32)

TRIM(CITY) + “ ” + STATE + “, ” +
ZIP

Layout 32/io" x “/12" x 3

Name CHESHIRE

Fields TRIM(FNAME) + “ ” + TRIM(LNAME)

SUBSTR(COMPANY, 1,40)

SUBSTR( ADDRESS, 1,40)

TRIM(GITY) + “ ” + STATE + “, ” +
ZIP

Layout 6V2" X 35/s ENVELOPE

Name SMALLENV

Fields
462 MASTERING FOXPRO

CH. 11

SPACE(15) + TRIM(FNAME) + “ ” +
TRIM(LNAME)
SPACE(15) + COMPANY;

SPACE(15) + ADDRESS

SPACE(15) + TRIM(CITY) + “ ” + STATE


+ ” + ZIP

Layout 97/8" x 7 Vs ENVELOPE

Name LARGEENV

Fields

SPACE(25) + TRIM(FNAME) + “ ” +
TRIM(LNAME)

SPACE(25) + COMPANY;

SPACE(25) + ADDRESS

SPACE(25) + TRIM(CITY) + “ ” + STATE


+ ” + ZIP

Once you are done creating all the label forms, write the Label menu
program to tie them together, using the code shown in Figure 11.23,
which will display the menu screen shown in Figure 11.24. Test all the
new options you just added.
WRITE YO UR OWN PROFESSIONAL MENU APPLICATION 463

ic-k'k-k-k-k-k'k'k'k-kick-k-k-k-k-k-k-k-k-k'k-k-k'k-k'k-k'k-k'k'k-k-k'k'k'k-k-kick-k-k-k'k-k-k-k-k

*LABLMENU.PRG
♦The label submenu for Mail Power
♦called by MAINMENU.PRG
**************************************************
*-create the main loop, to repeat the menu indefinitely

DO WHILE .T.

* -create a variable to hold the user's choice


choice = " "

* -display main menu and get user's choice


CLEAR
@ 0,0 SAY "MAILPOWER! Label Submenu"
@ 0,70 SAY DATE()
@ 1,0 SAY "_
+ »_
@ 6,25 SAY "1 - One-column labels"
@ 8,25 SAY "2 - Two-column labels"
@ 10,25 SAY "3 - Three-column labels"
§ 12,25 SAY "L - Large one-column labels"
@ 14,25 SAY "C - Cheshire labels"
@ 16,25 SAY "S - Small Envelopes"
@ 18,25 SAY "W - Wide Envelopes"
@ 20,25 SAY "R - Return to Main Menu"
@ 22,26 SAY "What is your choice > " GET choice PICT "!"
READ

* -perform option that user chose


* -or beep if choice was invalid
DO CASE
CASE choice = "1"
LABEL FORM one-col &&T0 PRINT
WAIT
CASE choice = "2"
LABEL FORM two-col &&TO PRINT
WAIT
CASE choice = "3"
LABEL FORM thre-col &&TO PRINT
WAIT
CASE choice = "L"
LABEL FORM large &&TO PRINT
WAIT
CASE choice = "C"
LABEL FORM Cheshire &&TO PRINT
WAIT
CASE choice = "S"
LABEL FORM smallenv &&T0 PRINT
WAIT
CASE choice = "W"
LABEL FORM largeenv &&TO PRINT
WAIT
CASE choice = "R"
EXIT
OTHERWISE
? CHR(7)
ENDCASE

ENDDO
RETURN

Figure 11.23: The Mail Power! Label menu program.


464 MASTERING FOXPRO

CH. 11

MAILPOWER! Label Submenu 03/16/91

1 - One-column labels

2 - Two-column labels

3 - Three-column labels

L - Large one-column labels

C - Cheshire labels

S - Small Envelopes

W - Wide Envelopes

R - Return to Main Menu

What is your choice > |

Figure 11.24: The Mail Power! Label menu screen.

EXPORTING FOR MAIL-MERGE


The final module you need to create lets the user export the data to a
text file to use in mail-merge. It is very simple to create: it just uses a con¬
ventional menu system, like the ones you have already created, to let the
user choose among the options of the COPY command that export
the data to a delimited text file. The options that are available are

• COPY TO <file name> TYPE SDF creates a system data for¬


mat file, an ASCII text file where records have a fixed length
and there is a new line at the end of each record. Fields are
not delimited, and leading or trailing blanks are retained so
the fields have a uniform length in all records.
• COPY TO <file name > TYPE DELIMITED creates a delim¬
ited file, an ASCII text file where character fields are sur¬
rounded by quotation marks and fields are separated by
commas. There is a new line at the end of each record.
• COPY TO <file name> TYPE DELIMITED WITH TAB is
like TYPE DELIMITED except that fields are separated
with tabs rather than with commas.

• COPY TO <file name> TYPE DELIMITED WITH <char¬


acter > is like TYPE DELIMITED except that character
fields are surrounded by the character indicated instead of by
quotation marks.
WRITE YOUR OWN PROFESSIONAL MENU APPLICATION 465

FoxPro also includes a DELIMITED WITH BLANK option,


which has fields separated by a single blank space rather than by
commas, but this option can cause trouble when the fields themselves
have blanks in them, so we will not use it.
This final module of the MAILPOWER program is shown in Fig¬
ure 11.25, and the menu it produces is shown in Figure 11.26. After
entering it, you should test all its options and then thoroughly retest
the entire program.

**************************************************
*EXPTMENU.PRG
*The export submenu for Mail Power
★called by MAINMENU.PRG
**************************************************
*-create the main loop, to repeat the menu indefinitely

DO WHILE .T.

* -create a variable to hold the user's choice


choice = " "

* -display main menu and get user's choice


CLEAR
@ 0,0 SAY "MAILPOWER! Export Submenu"
@ 0,70 SAY DATE()
@ 1,0 SAY "_";

@8,25 SAY "S - Export to SDF File"


@ 10,25 SAY "C - Export to Comma Delimited File"
@ 12,25 SAY "T - Export to Tab Delimited File"
@ 14,25 SAY "R - Return to the Main Menu"
@ 22,26 SAY "What is your choice > " GET choice PICT "I"
READ

* -perform option that user chose


* -or beep if choice was invalid
DO CASE
CASE choice = "S”
COPY TO export.txt TYPE SDF
CASE choice = "C"
COPY TO export.txt TYPE DELIMITED
CASE choice = "T"
COPY TO export.txt TYPE DELIMITED WITH TAB
CASE choice = "R"
EXIT
OTHERWISE
? CHR(7)
ENDCASE
IF choice = "S" .OR. choice = "C" .OR. choice = "T"
CLEAR
dummy = " "
@ 10,10 SAY "The data has been copied to a file
+"named EXPORT.TXT"
@ 12,20 SAY "Press any key to continue... " GET dummy
READ
ENDIF

ENDDO
RETURN

Figure 11.25: The program to export data for mail-merge.


466 MASTERING FOXPRO

CH. 11

MAILPOWER! Export Submenu 03/16/91

S - Export to SDF File

C - Export to Comma Delimited File

T - Export to Tab Delimited File

R - Return to the Main Menu

What is your choice > |

Figure 11.26: The Mail Power! Export menu screen.

While you are testing the program, you might want to review
some of the code to make sure you understand it. If you understand
the programming techniques used in this chapter, you can begin set¬
ting up applications for users. Though there are more advanced pro¬
gramming techniques for you to learn, the programs in this chapter
represent the bread and butter of database programming.
>
Using Advanced
Programming Techniques
To combine the modules of a program in a single file, 473
use the command PROCEDURE Kprocedure name^> followed
by the code in a module.

To create a separate file for procedures, 473


use the command SET PROCEDURE TO Kfile name>. Then
you use the command DO Kprogram name>, FoxPro searches
for the specified program first as a procedure in the current
.PRG file, then as a procedure in the file specified by the SET
PROCEDURE command, and finally as the name of a separate
.PRG file.

To control the scope of variables, 477


use the command PRIVATE <memvar lists*, and the memory
variables that are listed will be accessible only to the module
where they are created; or use the command PUBLIC Kmem-
var list >, and the memory variables that are listed will be acces¬
sible to all the modules of the program.

To pass the value of a variable to a program or procedure, 478


use the command PARAMETER Kmerrwar list> as the first com¬
mand of the program. When you call the program, use the
command DO WITH Kexpr list >. The expressions in the list
following DO WITH will be assigned in order to the memory
variables in the list following PARAMETER.

To pass values back and forth between two program modules, 478
it is best to use a user-defined function. You can begin this with
the command FUNCTION Kfunction name> or PROCE¬
DURE <procedure name>. These commands are identical.
To pass values to a user-defined function, 480
put the value in the parentheses of the function, just as you do
when you are using a built-in FoxPro function. The user
defined function must begin with the command PARAM¬
ETER Kmemvar list>, and the expressions you put in the
parentheses when you call it are assigned to the memory vari¬
ables in order.

To pass a value from a user-defined function back to the calling 481


program,
use the command RETURN K expressions. The expression that
you specify will be returned as the value of the function. You can
use it in the calling program in the same way that you use the
value of a built-in FoxPro function.

To give more protection to your data, 483


read user input into memory variables rather than using SET
FORMAT TO followed by APPEND or EDIT, which lets the
user scroll through the database and read or edit any record
there. By reading input into memory variables, you let the user
work only with the current record. You can use this method
either to append or to edit data.

To watch a program’s code as it executes, 498


select Echo or Step from the Program menu, or use the com¬
mand SET ECHO ON or SET STEP ON. Either of these
opens up the Trace window, where the code is displayed as the
program executes. Echo lets the program execute from begin¬
ning to end. Step makes it execute one line of code at a time:
you must select the Resume text button to make the next line
execute.
472 MASTERING FOXPRO

CH. 12

IN THIS CHAPTER, YOU WILL LEARN SOME OL THE


many advanced programming techniques that can be used with Fox¬
Pro. The chapter will emphasize more subtle structured program¬
ming techniques than you used in Chapter 11. There, you wrote a
fairly rough structure chart and did the sort of quick-and-dirty job of
structured programming that is generally used by consultants who
program dBASE compatible systems for small businesses. In this
chapter, you will make the program even more structured. The sort
of approach you will take here takes more time in the beginning and
so is not often used with some of the simple applications needed by
small businesses. But it can make it much easier to modify or debug a
more complex application that might be distributed commercially.
Whichever sort of programming you plan to do, though, the
examples in this chapter will help you by sharpening your thinking.
First, you must learn some techniques that are necessary to doing
more powerful sorts of structured programming with FoxPro. In the
last chapter, you broke down the work that the program had to do
and put each type of task into a separate .PRG file. Now, you will
learn how to make them all procedures in a single file. In addition
to learning how to create procedures, you will learn how to create
user-defined functions and how to pass the values of memory vari¬
ables among different modules of the program.
You will change the program so it reads the data that it gets from
the user into memory variables, so the user cannot scroll through the
entire database file. As you remember, Fox View gave you several
options which let you generate programs that read data into memory
variables in this way. Now, you will learn to implement this method
of getting data from the user. You will use this to create a general-
purpose password routine for the mailing list program, which you
can also incorporate into other programs. Both of these examples will
take advantage of the sophisticated methods of passing memory vari¬
ables among procedures that you learn in the beginning of this chap¬
ter and will use them in more and more advanced ways.
USING AD VANCED PROGRAMMING TECHNIQUES 473

ADVANCED TECHNIQUES OF
STRUCTURED PROGRAMMING -
You have seen that structured programming involves breaking the
program down into smaller parts. In most structured programming lan¬
guages, all of these modules can be kept in a single file, and each one is
called a subroutine or a procedure. It is generally easier to keep track of
what you are doing when the entire program is there in one file.
DBASE II did not let you create several procedures within a single
file. Each module of the program had to be in a separate .PRG file, as
they were in the Mail Power! program that you created in the last
chapter. This is adequate for simple programs, but as developers
began to use dBASE to create more complex applications, they
started complaining about this limitation.
As a result, dBASE III let users create procedure files, which could
hold many procedures. This innovation let programs run more
quickly, and it made programming somewhat easier, since modules
of the program did not all have to be in different files, but it was still
necessary to put procedures in a separate file from the main .PRG
file, which is executed when the program is started.
FoxPro goes a step further and lets you put procedures in the main
program file itself, so that you can now write programs as you do in
almost every structured language.
It is common for programmers to accumulate libraries of proce¬
dures that they have found useful for many purposes. These can be
kept in separate procedure files, so they can be used by any program
that you write. It is also common for programmers to keep all the new
procedures written for the current program in a single file, and now
FoxPro lets you do this as well.

CREA TING PROCEDURES


It is very easy to create a procedure. Simply use the command
PROCEDURE <L procedure namey. The code that follows this com¬
mand will be treated just as if it were in a separate .PRG file. You can
use it by entering the command DO <procedure namey.
474 MASTERING FOXPRO

CH. 12

Remember this If the procedure is in a separate procedure file, you must use the
default order of command SET PROCEDURE TO <file name> before doing it. If
searching to avoid confu¬
the procedure is in the same file as the program that is doing it, you
sion. In case you create
more than one program do not need to use the SET PROCEDURE command. When it sees a
or procedure with the DO < name> command, FoxPro looks first in the current file to see if
same name, FoxPro
there is a procedure with the specified name. Then, it looks in a pro¬
might not execute the
one you expected. cedure file, if one has been opened previously using SET PROCE¬
DURE TO, for a procedure with the specified name. Then, it looks
for a .PRG file with the specified name.
Like a .PRG file, a procedure can use the command RETURN at
any point to return to the program or procedure that called it. It can
optionally include this command at the end, but FoxPro automati¬
cally returns to the calling program when it reaches the end of the
procedure, just as it does when it reaches the end of a program.
In fact, procedures are so similar to programs that you can per¬
form a simple exercise to get experience with the PROCEDURE com¬
mand by combining all the .PRG files in your Mail Power! program
into a single .PRG file.
The code that is now in MAINMENU.PRG will be at the beginning
of this new .PRG file, so that the Main menu is executed when the pro¬
gram begins. All of the other .PRG files you created in the last chapter
will be procedures within the same file: all you have to do is use your edi¬
tor to copy them into the file and then add the command PROCEDURE
plus the name of the .PRG file at the beginning of each one. When Fox¬
Pro sees a command such as DO DATAMENU, it will do the datamenu
procedure rather than the datamenu program.
FoxPro includes a utility named FoxBind that turns separate
.PRG files into procedures for you, which you might want to learn
later. For a fairly short program such as this one, though, it is very
easy to do the same thing by hand. You should do it yourself for now,
so that you learn the PROCEDURE command.
When you created the original .PRG files, the FoxPro editor auto¬
matically put a DOS end-of-file mark at the end of each one. This
mark shows up in the FoxPro editor and in most editors as a small
arrow pointing right. In some editors, though, it shows up as ~Z
(Gtrl-Z represented by a caret followed by Z). To avoid possible con¬
fusion, you will delete this character. If you have changed editor pref¬
erences, however, it might cause even more confusion: make sure the
Gtrl-Z Sensitive check box is not checked.
USING AD VANCED PROGRAMMING TECHNIQUES 475

D If you are already


using FoxPro, you
1. First, you might want to create a new subdirectory to work
in, so you do not disturb the first version of the program. If
can enter all these same
commands in the Com¬
so, at the DOS prompt, enter MD \MAILPOW2 to create the
mand window by preced¬ directory. Then enter CD \MAILPOW2 to make it the cur¬
ing each one with RUN. rent directory. Then enter COPY \MAILPOW\* .* to copy
all the Mail Power! files into it.

2. If necessary, start FoxPro. Make sure you’re in the


MAILPOW2 directory. If it isn’t your current directory,
enter RUN CD \MAILPOW2 in the Command window.
Enter MODI COMM MAINMENU to open a file to edit the
Main menu. Press Ctrl-End to move to the end of the file.
The small arrow just to the left of the cursor is the DOS end-
of-file mark: press Backspace to delete it.

3. Press Enter five or six times, to skip lines before the next pro¬
cedure. Then type PROCEDURE datamenu, and press Enter
twice to skip more lines. Then select Open from the File
menu. Use the popup control of the Open dialog box to select
Program. Select DATAMENU.PRG and press Enter or
select the Open text button to edit that file. Press Shift-Ctrl-
End to mark all the text in the DATAMENU.PRG file.
Select Copy from the Edit menu to copy all the text in the
file. Then press Esc or click the close box to close it and to
return to the end of the MAINMENU. PRG file, a couple of
lines below the command PROCEDURE datamenu, which
you entered a moment ago. Select Paste from the Edit menu
to place the DATAMENU.PRG file that you copied in this
location. The cursor should be at the end of the file you just
pasted: press Backspace to delete the arrow that is the end-of-
file marker, as you did before.

4. That is all there is to converting a .PRG file to a procedure.


Do the same with all the .PRG files in this application. Press
Enter five or six times to skip lines. Type PROCEDURE
reptmenu, and press Enter twice to skip lines. Open the
REPTMENU.PRG file and use the editor to copy the entire
file at the end of the current file, under the command PRO¬
CEDURE reptmenu, as you did previously for datamenu.
Press Backspace to delete the end-of-file marker. In just the
same way, enter the command PROCEDURE lablmenu,
copy LABLMENU.PRG under it, and delete the end-of-file
mark. Then enter the command PROCEDURE exptmenu,
copy EXPTMENU.PRG under it, and delete the end-of-file
mark. Finally, in the same way, enter the command PROCE¬
DURE lookup and copy LOOKUP.PRG under it, but since
this is the end of the file, there is no need to delete the end-of-
file mark.

5. Since this the entire Mail Power! program, you will save it all
under the name MAILPOW.PRG. First, scroll up through it
and modify the comments at the beginning of each procedure
to reflect the changes you made. Though the program will
run perfectly well in its current form, the comments you
wrote when the procedures were separate programs are no
longer quite accurate. Instead of DATAMENU.PRG, for
example, the comment should say DATAMENU PROCE¬
DURE; and you will probably also want to move the com¬
ments so they come above the PROCEDURE command.
There is no longer a separate MAINMENU.PRG to call
these procedures, but it is conventional in many program¬
ming languages to refer to the module of the program that is
executed when it begins as the main module, and you might
want to change your comments using this terminology. You
might want to look ahead to the final version of the program
file (shown in Figure 12.15) to copy some of its comments.

6. Once you are satisfied with the comments, save the file by
selecting Save As from the Program menu. Enter the name
MAILPOW in the Save Current Document As dialog box, and
select the Save text button. Then close the editing window.

7. To avoid confusion, delete the program files from the earlier


version. At the Command window, enter RUN DEL ????
MENU.* and then enter RUN DEL LOOKUP.* to delete
the menu programs and lookup program (both compiled
and text).

8. Now try the new program. Enter DO MAILPOW in the


Command window. Notice that, as it compiles this file,
USING AD VANCED PROGRAMMING TECHNIQUES 477

the compiler tells you which procedure it is compiling at any


given time. Test the program to make sure that it runs
exactly the same as it did when it was in separate .PRG files.

This program illustrates the simplest use of procedures, no


different from the old-fashioned use of .PRG files that you made in
the last chapter.

THE SCOPE OF VARIABLES


AND PASSING PARAMETERS
You define the In addition to introducing procedures, dBASE III also added fea¬
scope of a memory tures that give you more control over memory variables in your pro¬
variable in the same way,
regardless of whether the
grams. Though it was not necessary to the programming you did in
modules of your program the last chapter, when you do more complex programming you often
are in procedures or in want to control whether memory variables are accessible to all the
separate .PRG files.
modules of the program or only to the module where they are cre¬
ated. This is sometimes called the scope of the variable.
To determine a variable’s scope, you can use one of two simple
commands at the beginning of any .PRG file or procedure:

• PRIVATE < memvar li$t> makes the specified memory vari¬


ables available only to that .PRG or procedure. If the same
variables are used elsewhere in the program, there is no dan¬
ger of confusion.

• PUBLIC < memvar list> makes the specified memory vari¬


ables available to all programs and procedures.

PRIVATE is useful if you are writing a large program where you


might inadvertently use more than one variable named mcounter or
mname. It is particularly useful if you create libraries of procedures,
that you use in many programs: if you define the variables in the
library as private, you can SET PROCEDURE TO that library file
without having to worry about whether the memory variables in the
file have the same names as the memory variables you are using in
the program.
478 MASTERING FOXPRO

CH. 12
/) /W&t/c tPY/Sts* FV^-aJ ~n¥£r fAo&Ztf/ff
-/YYA T T£P YT .

PUBLIC, of course, is useful if you need to change the value of a


variable in one module and have the new value available to all the
other modules in the program.
Apart from these two alternatives, though, there are also many
cases where you want the values of variables to be available to only
CAUtvf two modules.
9%k:~a£wa/' MMY MU (s') To let the calling module pass the value of a variable to the module
,yx APP4&&e>F A&N that it calls, you use the command PARAMETER Kmemvar list> as
Po #Taj prrry 4W? the first command in the module that is called. Then, the simplest
way of passing a parameter to that module when you call it is to use
the command DO WITH Kexpr list>. The expressions in the list fol¬
lowing DO WITH are assigned in order to the memory variables in
Pft C>C$PVX£ 8TV the list following PARAMETER, and thus are passed to the module
p#/ift/ne:T£f?5 AW* k that is called.
p//nen/&0/v AAR2 For example, all of the menu programs in the mailing list program
had a similar heading at the top of the screen: the name of the main
/PrA K--\ To 3
program (MAILPOWER!), the menu’s name, and the date, all
( ’AMzC*'>
underlined. The code for the Data submenu’s heading, for example,
is shown in Figure 12.1.

CLEAR
@ 0,0 SAY "MAILPOWER! Data Submenu"
@ 0,70 SAY DATE()
@ 1,0 SAY "_
+"

Figure 12.1: The original code to create the Data submenu header.

When you have code that is repeated, it is generally a cue that it


should be put in a separate module to make the program more struc¬
tured. Because of the slight difference between the headers of the
different menus, you could not put them in a separate module ear¬
lier. Now you can do it by passing a parameter.
Add a new procedure called SCRNHEAD to MAILPOW.PRG,
with the code shown in Figure 12.2.
USING ADVANCED PROGRAMMING TECHNIQUES 479

******************************************

*PROCEDURE SCRNHEAD
*a general purpose screen header
*called by the MAIN program and by
*procedures DATAMENU, REPTMENU, LABLMENU, EXPTMENU, LOOKUP
*******************************************

PROCEDURE scrnhead
PARAMETER menuname

CLEAR
@ 0,0 SAY "MAILPOWER! " + menuname
@ 0,70 SAY DATE()
@ 1,0 SAY "_" ;
+ ii ii

Figure 12.2: Code for a general-purpose screen header.

Then, instead of using the code in the original version of DATA¬


MENU to display the screen header, that procedure simply needs to
use the command:

DO scrnhead WITH “Data Submenu"

When the DATAMENU procedure gets up to this code, it executes


the SCRNHEAD procedure to print out the menu heading. The
PARAMETER command of SCRNHEAD receives the words Data
Submenu that followed DO scrnhead WITH as a parameter and
assigns them as the value of the variable menuname, which followed its
PARAMETER command. Thus, when it prints the screen header,
the expression “MAILPOWER! ” + menuname has the value
MAILPOWER! Data Submenu, so that the heading looks just the
same as it did in the earlier version of the program
Of course, the other menu procedures call SCRNHEAD with the
appropriate parameter; even the MAIN menu program can use this
procedure, using the command:

DO scrnhead WITH “Main Menu"

Finally, the LOOKUP procedure (like the format screen) includes


the same header without any screen name, and it
can be called by using the command

✓✓ //
DO scrnhead WITH
480 MASTERING FOXPRO

CH. 12

The SCRNHEAD module expects its parameter to be initialized as a


character string, and it will display an error message if it is not, but it
is easy to get the header you want for LOOKUP by using a string
that is a blank space as the parameter.
You should add the new SCRNHEAD procedure shown in Fig¬
ure 12.2 to the end of your program. Modify the other procedures by
using the command DO SCRNHEAD WITH, deleting code that dis¬
plays the header. (If you have any trouble modifying these modules,
see the final version of the program in Figure 12.15 at the end of the
chapter).
It may seem that the extra trouble you take in analysis to break down
the program in this way is not worth the keystrokes you save with it.
Wouldn’t it be easier to write the header in each procedure, especially
since you can use your editor to copy it? As you will see, having the
header in a separate procedure requires more thought at first, but it pays
off when you must modify the program. Imagine how much easier it
would be to change the header—for example, if your client decided that
it should display the time as well as the date—now that it is in one mod¬
ule used by all the program’s procedures.

USER-DEFINED FUNCTIONS
It is also possible to use the PARAMETER command to pass a
value back to the calling procedure. Although this was common in
dBASE III + programming, it is no longer necessary in FoxPro,
because there is a much more elegant way of accomplishing the same
thing, using user-defined functions.
You are no longer limited to the functions that are provided as part
of the FoxPro language. If they are inadequate for your purposes,
you can create functions of your own, which you can use just like the
program’s built-in functions.
FoxPro lets you use the command FUNCTION just as you use the
^command PROCEDURE. In fact, the way that these two commands
work is identical, but as a matter of programming style it makes sense to
use FUNCTION at the beginning of a user-defined function and PRO¬
CEDURE at the beginning of a procedure, in order to make the pro¬
gram easier to understand when you are modifying or debugging it.
USING AD VANCED PROGRAMMING TECHNIQUES 481

The real difference between procedures and user-defined func¬


tions is the way you pass parameters and return a value. So far, you
have used the word RETURN by itself to return control to the calling
function. Remember, though, that by definition a function returns
a value. If you end a user-defined function with the command
RETURN <expry, the expression is returned to the calling program
as the value of that function.
User-defined functions are used just like ordinary functions.
Rather than passing a value to the user-defined function by using the
command DO . . . WITH, you simply put the value (or values)
being passed to the function in the parentheses following it. The func¬
tion itself begins with a PARAMETER < parameter list> command,
and the value or values passed to it are assigned to the variables in the
parameter list in order, just as they are with ordinary procedures.
When the function reaches the command RETURN <.expr>, the
expression returned is used as the value of the function, just as it is
with one of the built-in functions of FoxPro.
This will be very simple if you try a simple example. As you know,
there are functions in FoxPro to make all of the letters of a character
string uppercase or lowercase and to capitalize the first letter of each
word. But what if you need a function to capitalize just the first letter
of the entire string, regardless of how many words are in it? For
example, what if you have sentences that are written in all capital let¬
ters and you want to print them with just the first letter capitalized?
It is easy to create a user-defined function to do this for you. As you
can see in Figure 12.3, the function INITCAP0 takes a string as its
parameter. UPPER(SUBSTR(mstring, 1,1)) makes the first charac¬
ter of the string uppercase, and LOWER(SUBSTR(mstring,2))
makes the rest of the string lowercase, so the function returns the
string in the form you want. In this exercise, you will use this func¬
tion from the Command window, and you will get experience in cre¬
ating a procedure file and using the SET PROCEDURE TO
command, as well as experience in creating a user-defined function.

1. If you want, enter CLEAR in the Command window to clear


the screen. Then enter MODI COMM MYFUNCTS to edit a
new program file that holds the user-defined functions you
create, and enter the code shown in Figure 12.3. When
482 MASTERING FOXPRO

CH. 12

Figure 12.3: The code for the user-defined function.

you have finished, select Save from the File menu and then
close the window.

2. In the Command window, enter the command SET PROCE¬


DURE TO MYFUNCTS to make this new file the active pro¬
cedure file. Since this is the first time you have used it, it will
compile automatically.

3. In the Command window, enter ? to skip a line. Then enter


If there is a typo¬
graphical error in ? INITCAP(“KNOW THYSELF!”). FoxPro displays Know
your program code that thyself!, as you can see in Figure 12.4.
you must correct, the
procedure file will auto¬
matically be closed when
you edit it. You must use
System File Edit Database Record Program Window_
the command SET
Know thyself!
PROCEDURE TO
MYFUNCTS again
before retesting it.

Command
MODI COMM MYFUNCTS
SET PROCEDURE TO MYFUNCT
?
? INITCAP("KNOW THYSELF!

Figure 12.4: Using a user-defined function.


USING AD VAN CEO PROGRAMMING TECHNIQUES 483

As you can see, you use the INITCAP0 function that you created
yourself in the same way that you use built-in functions such as
UPPER() and PROPER0. The parameter that you pass to the func¬
tion is placed in the parentheses of the function, and the expression
that it returns is the value of that function. User-defined functions,
like any functions, can be used either in programs or from the Com¬
mand window.
Though you can manage without it when you are doing basic
database programming, you will find that passing values between
modules in this way becomes more and more important as you
become a more advanced programmer. In the rest of this chapter,
you will look at more sophisticated examples of parameters and user-
defined functions.

READING USER INPUT


INTO MEMORY VARIABLES _

There is another advanced programming technique that is so com¬


mon that you have already run into it a couple of times in this book.
Remember that some FoxView templates gave you the option of
reading user input into memory variables, and that this was men¬
tioned as a common use of the command APPEND BLANK.
You have seen that the simplest way of letting the user modify a
database file is by using the command SET FORMAT TO Kfile
namey followed by the command APPEND and EDIT or CHANGE,
as you did in the version of the mailing list program that you wrote in
the last chapter. As you know, this method uses the specified custom
data-entry screen, which arranges the fields so they are easier to
understand and adds help for the user, and it lets the user append or
edit the database just as you would if you were working in the Browse
window. The user can page up and down through the database file,
and can see and modify all the records in it.
It is common for programmers to want to give more protection
than this to the database, letting the user access a record only by look¬
ing that record up by name. In an accounting program, for example,
you would not want to let the user page up through the earlier entries
and modify them. You probably would want the user to be able to
484 MASTERING FOXPRO

CH. 12

modify an earlier entry only by looking it up by name, so that the


program could maintain an audit trail by automatically keeping
records of when and how entries were modified. There are also many
programs where you might want to include password protection that
lets everyone add new entries but lets only authorized users modify
earlier entries; later in this chapter, we will add this sort of protection
to the Mail Power! program.
Of course, this level of security is not possible if you use SET FOR¬
MAT TO and APPEND, because everyone who appends data can
also page up through the records and modify earlier data. To protect
the data, you must get user input in a different way. First create a
memory variable for each field in the database. Then use @ . . .
SAY . . . GET commands to read the user’s input into these memory
variables. Finally, use the REPLACE command to give the database
fields the values that the user entered in the memory variables.
If you are appending records, you must initialize all the mem¬
ory variables with blank spaces. For example, you could use the
commands

mfname = BLANK(15)
mlname = BLANK(20)

and so on, creating a memory variable for each field in the database,
with the same length as the field and a similar name (with the initial
m added to show that it is a memory variable).
Then you use a series of commands such as

@ 8,0 SAY "First name: " GET mfname


@ 8,30 SAY "Last name: " GET mlname

and so on for all the fields of the database file, and then the command
READ to have the user enter data. The user is able to access only the
memory variables, not the actual database.
Finally, when the user has entered all the data (and, if you choose,
has confirmed that it is correct), you use a series of commands such as

APPEND BLANK
REPLACE fname WITH mfname
REPLACE Iname WITH mlname
USING AD VANCED PROGRAMMING TECHNIQUES 485

and so on for all the fields in the file. You add the new record by using
the command APPEND BLANK rather than APPEND, so that the
user still does not have access to the database file. Then you replace
all the fields in this new blank record with the data that the user
entered.
If you want to edit an existing record rather than appending a new
one, you use a very similar technique. The difference is that you first
must look up the record that the user wants to edit, and initialize all
the memory variables with the current values of its fields. If your pro¬
gram has a LOOKUP module that works like the one you wrote in
the last chapter, for example, you could write

DO lookup
IF .NOT. EOFO
mfname = fname
mlname = Iname

and so on, giving all the memory variables the values that the fields
currently have (assuming the program found the record that the user
wants to edit).
Then, to let the user modify them, you could use much the same
code you used for appending. The commands

@ 8,0 SAY "First name: " GET mfname


@ 8,30 SAY 'Last name: " GET mlname

and so on would display default values in the GET field that are the
same as the values in the current record. Then when the command
READ is executed, the user could change these defaults or keep them.

H Though it is easier to
understand for
Finally, when the user is done, the commands

REPLACE fname WITH mfname


instructional purposes if
you use a separate
REPLACE Iname WITH mlname
REPLACE command for
each field, you can also use and so on would replace the values that are currently in the records
this command to change with the values that the user entered. If you were the user, it would
the value of more than one
seem just like editing a record: the difference is that you cannot page
field with a single line of
code. For more details, see up and down through the database and that you do not automatically
Appendix C. go on to the next record when you are done with this one, as you do
486 MASTERING FOXPRO

CH. 12

when you use EDIT or CHANGE. In this way the programmer can
keep a close watch over the integrity of the data.
Despite the similarity between them, database programmers
sometimes write two separate modules for appending and editing:
they must write the code twice for initializing the memory variables,
displaying them on the screen, getting user input, and replacing the
actual variables with memory variables. That is the quick-and-dirty
way to do things, but it could end up being more work in the long
run: for example, if you want to modify the screen display, you must
rewrite all the @ . . . SAY . . . GET statements twice and look back
and forth between the two versions to make sure they are identical.
Since this chapter is about more structured methods of program¬
ming, we will do the extra thinking that is needed to write a module
called GETDATA, which will let the user both edit and append data.
Because there are slight variations in the things that GETDATA
must do to append and to edit, the DATAMENU procedure will
pass a different parameter to it depending on what must be done, and
it will include IF statements that make it execute code depending on
the parameter. This is a somewhat more sophisticated use of param¬
eters than in the earlier exercise, where the parameter was just dis¬
played as part of the header.
Remember the original bit of code from the DATAENTR proce¬
dure, shown in Figure 12.5, that was used to append and edit. To
revise this procedure so that is can be used with the new GETDATA
procedure, you will replace it with the code in Figure 12.6.
You can begin to see already that this is a more elegant way of writ¬
ing the program. For example, notice that SET BELL ON and SET
BELL OFF have been removed from both of these: it is obvious that
GETDATA can use them once for both editing and appending.
(LOOKUP will also be included in GETDATA, for a reason that
will become apparent when we write that module.)
GETDATA will display a screen similar to the screen that the orig¬
inal format file displayed to get input from the user. But first, GET¬
DATA must use DO LOOKUP if it is editing data; then, if
LOOKUP finds the record it wants, it will go on with code that ini¬
tializes memory variables with the values in the fields of the current
record of the database file.
USING AD VANCED PROGRAMMING TECHNIQUES 487

********************************

♦program fragment for appending and editing


♦from the first version of PROCEDURE DATAMENU
***********★***★**★★*★★****★***

DO CASE
CASE choice = "A"
* -append using custom format screen
SET BELL ON
SET FORMAT TO datascrn
APPEND
SET BELL OFF
SET FORMAT TO
CASE choice = "E"
* -find record user wants and edit
* -using custom format screen if found
DO LOOKUP
IF .NOT. EOF()
SET BELL ON
SET FORMAT TO datascrn
EDIT
SET BELL OFF
SET FORMAT TO
ENDIF

ENDCASE

Figure 12.5: Code for appending and editing from the first version of the
program.

********************************
♦program fragments revised code for appending and editing
♦to be incorporated in PROCEDURE DATAMENU
*******************************

DO CASE
CASE choice = "A"
*-append using GETDATA
DO getdata WITH "append"

CASE choice = "E"


*-Use GETDATA to find and edit record user wants
DO getdata WITH "edit"

ENDCASE

Figure 12.6: Revised code for appending and editing.

What if the user is appending a record, though? Then, instead of


looking up a record, GETDATA simply begins with APPEND
BLANK, which adds a blank record to the database file and makes it
the current record.
488 MASTERING FOXPRO

CH. 12

Thus, when it initializes all the memory variables with the values in
the fields of the current record, it will give them the values in the record
to be edited if it is editing, and it will simply give them the values in the
new blank record if it is appending.
In either case, after initializing the memory variables, it displays
them with a series of @ . . . SAY . . . GET statements and lets the
user change them. If the user confirms that the changes should be
kept, it uses a series of REPLACE statements to enter them in the
database file.
If the user does not want to keep them, the program does not have
to do anything if it is editing: it just omits the REPLACE commands
and leaves the original data there in the record. If it is appending,
though, it must do something with the blank record it appended at
the beginning of this procedure. The simplest thing to do is just
to DELETE this blank record on the spot: since this program has SET
DELETE ON, the blank record that is marked for deletion will never
be noticed. It will be eliminated completely if and when the user
finalizes deletions, without the user ever knowing that it was there.
Now that you have the basic idea of how it works, you can enter
the program and try it out. If you are puzzled by the code while you
are entering it, look at the more detailed discussion after the exercise.
You might want to modify the code in DATASCRN.FMT to create
part of the code in the GETDATA procedure. The data-entry screen
displayed by GETDATA is almost identical to the format screen that
was used previously. The only differences are that instructions about
paging through the database and about saving or discarding changes
have been removed, and that the instructions have been moved up a bit
to leave room below them for the questions that the program now asks
the user.

1. Enter MODI COMM MAILPOW to edit the program.

2. Modify the DATAENTR procedure by changing what was


shown in Figure 12.5 to what was shown in Figure 12.6.

3. Add the GETDATA procedure listed in Figure 12.7 to the


end of the MAILPOW program. Then select Save from the
File menu, and close the edit window.

4. You can also delete the format file, which is no longer


needed. Enter RUN DEL DATASCRN.FMT.
USING AD VANCED PROGRAMMING TECHNIQUES 489

Enter DO MAILPOW and test the program, correcting any


typographical errors. The screen displayed by GETDATA is
shown in Figure 12.8.

*PROCEDURE GETDATA
*new module for editing or appending data
*to be added to MAILPOW.PRG
*called by DATAMENU procedure

PROCEDURE getdata
PARAMETER mode

*-repeat for as long as the user wants to edit or append


DO WHILE .T.

* -append a blank record if you are appending or


* -find the record to be edited if you are editing
IF mode = "append"
APPEND BLANK
ENDIF

IF mode = "edit"
DO LOOKUP
ENDIF

* -If LOOKUP has not found the record to edit, so that


*- EOF() is true, do nothing.
* -If LOOKUP has found the record to edit, initialize
*- variables with the values in its fields.
* -jf you are appending, initialize memory variables
*- with blanks from the current record.
IF .NOT. EOF()
mhonor = honorific
mfname = fname
mlname = lname
mcompany = company
maddress = address
mcity = city
instate = state
mzip = zip
mphone = phone

* -set environment for data entry


SET BELL ON

* -Print the screen header,


* -including the words "Append" or "Edit" Records
DO scrnhead WITH PROPER(mode) + " Records"

* -Display fields and get user input


@ 3,0 SAY "Title:” GET mhonor PICT "0!"
@ 3,15 SAY "First name:" GET mfname PICT "@!"
@ 3,45 SAY "Last name:" GET mlname PICT "01"
§ 5,6 SAY "Company:" GET mcompany PICT "01"
@ 7,6 SAY "Address:" GET maddress PICT "@!"
@ 9,6 SAY "City: " GET mcity PICT "01"
@ 9,38 SAY "State:" GET mstate PICT "@t"
0 9,50 SAY "Zip code:" GET mzip PICT "99999"
0 11,25 SAY "Telephone:" GET mphone;
PICT "(999)999-9999"
0 13,15 SAY "-
-f- "_M

Figure 12. 7: A procedure to get data in memory variables.


490 MASTERING FOXPRO

CH. 12

@ 14,15 SAY "I : Move cursor within field";


+ -' | "
M •
@ 15,15 SAY "|
+" | "
@ 16,15 SAY "| Tab Shift-Tab Move cursor to ";
+"next/last field |
»• f•
6 17,15 SAY ”- '———— -°-

READ

* -return to environment setting used


* -for choices and menus
SET BELL OFF

* -have user confirm that input is right


confirm = "Y"
@ 19, 15 SAY "Do you want to finalize these";
+ " changes (y/n) ? " GET confirm PICT "!
READ

* _if it is right, put it in database file


IF confirm = "Y"
REPLACE honorific WITH mhonor
REPLACE fname WITH mfname
REPLACE lname WITH mlname
REPLACE company WITH mcompany
REPLACE address WITH maddress
REPLACE city WITH mcity
REPLACE state WITH mstate
REPLACE zip WITH mzip
REPLACE phone WITH mphone

@ 21, 15 SAY "The database file has been changed."

* -if it is not right, do not put it in file, and


* -if a blank record has been appended, delete it.
ELSE
@ 21, 15 SAY "The changes will be discarded."
IF mode = "append"
DELETE
ENDIF
ENDIF

ENDIF

*-let the user append or edit another record


again = "Y"
@ 23, 15 SAY "Do you want to " + mode + " another (y/n) ? "
GET again PICT "!"
READ

IF again = "Y"
LOOP
ELSE
EXIT
ENDIF
ENDDO

Figure 12. 7: A procedure to get data in memory variables, (continued)

Notice that virtually all of the code in this new procedure is in a


large DO WHILE .T. loop, so that it can be repeated over and over
again to let the user edit or append more records. The only statement
executed before the loop begins is the PARAMETER command,
which assigns the parameter that is passed to this procedure to the
USING AD VANCED PROGRAMMING TECHNIQUES 491

MAILPOWER! Append Records 04/04/91

Title: First name: Last name: SCHMALTZ

Company:

Address: 590 OCEAN AVE.

City: BROOKLYN State: [QQ Zip code: 11226

Telephone: (212)784-1059

! <- -> : Move cursor within field

I Tab Shift-Tab : Move cursor to next/last field

Do you want to finalize these changes (y/n) ? Q

The database file has been changed.

Do you want to append another (y/n) ? Q

Figure 12.8: The data-entry screen displayed by the GETDATA procedure.

variable named mode. Remember that the DATAMENU procedure


called this procedure with the command DO GETDATA WITH
“append” or the command DO GETDATA WITH “edit”; so the
variable mode now has one of these two values.
The first command executed within the loop depends on what you
are doing. If mode equals “append”—that is, if the parameter has
this value because you are appending—APPEND BLANK is the first
command. If mode equals “edit”, on the other hand, DO LOOKUP
is the first command. As you know, LOOKUP leaves the pointer on
the record to be edited if it can find it, or makes EOF() true if it can¬
not find it. (You can see that LOOKUP must be called by GET¬
DATA, rather than by DATAMENU, because it is executed each
time the user edits a record. By putting it here, you make it possible
to edit multiple records without returning to the Data menu.)
All of the editing is nested in an IF .NOT. EOF() statement. The
only way that EOF() can be true is if LOOKUP was used and did not
find the record that was being looked for. In this case, LOOKUP will
already have displayed an error message, and GETDATA merely
skips all the steps that display and let the user edit data, and goes
down to the command that asks whether the user wants to try editing
another.
492 MASTERING FOXPRO

CH. 12

If the user is appending, the pointer is on the new, blank, record. If


the user is editing and LOOKUP was successful, the pointer is on the
record to be edited. In either case, EOF() is not true, and so the heart
of the program is executed. First, memory variables are created with
the values of all of the fields in the current record of the database: all
blanks if you are appending, or the actual name, address, and so on if
you are editing.
SET BELL ON is executed only at this point, so that the program
will beep only during data entry. Then @ SAY . . . GET statements
are used to display the values of the fields (blanks if you are append¬
ing or the values of the current record if you are editing) and let the
user change their values. SET BELL OFF is executed as soon as this
data-entry portion of the program is done, because we do not want
the program to beep during the portion that follows, when it uses
single-keystroke @ . . . SAY . . . GET statements to ask the user
questions.
After the user enters the data, the program asks for confirmation
that the values should be changed in the database. Notice that the
program initializes the variable confirm with the letter Y rather than
with the usual blank space that you have used in the past. This is
because the user ordinarily will confirm the changes, and this makes
it easy to do so by pressing Enter and accepting the default value of Y
that is already there. If the user does enter Y, the series of REPLACE
commands makes the changes in the database. If not, the user is
given a reassuring message that the changes will be discarded; this
sort of message is needed to avoid an error in case the user mistakenly
presses the wrong key and thinks that the changes are being saved. In
addition, if the mode is “append”, the blank record is deleted, as dis¬
cussed earlier.
Then the user is given the opportunity to edit or append another
record, again with a default answer of Y, since it is common to do
data entry for several records at a time. Notice the expression “Do
you want to” + mode + “another (y/n) ? ” Of course, this will dis¬
play Do you want to append another (y/n) ? or Do you want to edit
another (y/n) ?. If the user enters Y, the program loops back to the
beginning and, depending on the value of mode, either appends a
blank record or looks up a record to edit, and then goes through the
whole loop again. When the user enters something else, the program
exits from the loop and returns to the DATAMENU procedure.
USING AD VANCED PROGRAMMING TECHNIQUES 493

A GENERAL-PURPOSE
PASSWORD PROCEDURE _

Now you are ready for a very sophisticated example of structured


programming, similar to the sort of thing that is commonly used in
the C language and other advanced programming languages.
Professional programmers often create libraries of general-
purpose procedures or functions that they use in many different pro¬
grams. In this section, you will create a general-purpose password
procedure of this type.
To make it general-purpose, you will include this password in a
procedure file. Imagine that you plan to keep many utilities in this
file, so you call it UTILS. Then any program can use one of these
utilities by using the command SET PROCEDURE TO UTILS.
Consider that this password procedure will have to request a
password and see whether the user gets it right, and then it will have
to return a message to the program that called it, to let that program
know whether the user should be given access to data that is password
protected.
Because it must return a value, the password procedure must actu¬
ally be a user-defined function. Earlier in this chapter, you looked at
INITCAP(), a user-defined function that had just one line of code, a
RETURN <expr> command, so that it did nothing but return
a value. Remember, though, that a user-defined function can con¬
tain the same commands as any other procedure; so it can do any¬
thing you want it to do before it returns a value.
Thus, you will create a function in the form PASSWORD(<c/ztfr
expy) which asks the user for a password, and returns the value .T.
if the user knows the password or the value .F. if the user does not
know the password. As you will see, this function uses the specified
character expression to customize the message that it displays (just as
you passed a parameter to the SCRNHEAD procedure that you
wrote earlier so that it could customize the screen header).
To call this function, the DATAMENU procedure just has to
change the Edit option as shown in Figure 12.9. Compare this with
the earlier version of the same code, and you will see that it simply
adds SET PROCEDURE TO utils and adds IF password(Editing)
before—and, of course, ENDIF after—the command DO getdata
494 MASTERING FOXPRO

CH. 12

WITH “edit”. Then, if the password is not correct, the program will
skip the GETDATA procedure.
Once you have written PASSWORDQ, you can add the same
protection in the appropriate place in this same way in any program
you write, just by enclosing a command in IF password( ) and
ENDIF (after setting the PROCEDURE file).
With this background, you should have no trouble understanding
the password function, shown in Figure 12.10.

DO CASE

CASE choice = "E"


*-use GETDATA to find and edit record user wants

SET PROCEDURE TO utils


IF password("Editing")
DO getdata WITH "edit"
ENDIF

ENDCASE

Figure 12.9: Revising the code for editing.

First, the PARAMETER command assigns the parameter that was


passed to this function to the variable mdoing. Remember that, to
add password protection for editing, you are going to use the com¬
mand PASSWORD(“Editing”), so that word is assigned to mdoing.
The function is going to give the user three chances to get the
password, in case of typographical errors. Thus, it uses a variable
named counter and a DO WHILE loop to ask for the password three
times; counter is declared as PRIVATE to make sure there is no possi¬
bility of interference with any other memory variables in the program
that calls this procedure.
Each time through the loop, the function clears the screen. Then
it displays a message that says, in this case, Editing is password
protected.
If the user enters the correct password, which is OPEN SESAME,
it exits from the loop; otherwise, it adds 1 to the counter and loops
back to the DO WHILE statement. At first, the user is able to try
again, but after the user misses three tries, the counter is equal to 3
USING AD VANCED PROGRAMMING TECHNIQUES 495

***********************************
♦FUNCTION PASSWORD
*a general purpose password function
'k'k'k’k-k’k'k'k-k-k'k'k-k-k’k'k'k-k-k-k’k'k'k'k’k-k'k’k-k'k-k-k-k-k'k

FUNCTION password
PARAMETER mdoing

PRIVATE counter

counter = 0
DO WHILE counter < 3
CLEAR
mtry = SPACE(11)
@ 10, 20 SAY mdoing + " is password protected."
@ 12, 20 SAY "Enter the password > " GET mtry
READ

IF mtry = "OPEN SESAME"


EXIT
ELSE
? CHR(7)
counter = counter + 1
LOOP
ENDIF
ENDDO

IF mtry = "OPEN SESAME"


RETURN .T.
ELSE
RETURN .F.
ENDIF

Figure 12.10: A general-purpose password function.

and so the loop is not executed again. The loop is simply followed by
an IF . . . ELSE statement, which returns .T. if the user got the
password right or returns .F. if the user got it wrong.
Try this password function out:

Create a new program file named UTILS.PRG, which


includes the code for the PASSWORD() function, as shown
in Figure 12.10, and save it.
Modify the code in the MAILPOW program for editing, as
shown in Figure 12.9. Of course, in place of <char exp>
there, you should use the character expression “Editing”, so
that the actual statement reads IF password(“Editing”).

Test the program. It should display the screen shown in Fig¬


ure 12.11 to ask the user for the password. If the correct
password is not entered in three tries, it should skip editing
and return to the menu.
496 MASTERING FOXPRO

CH. 12

Figure 12.11: Asking the user for the password.

If you understand the password function in this form, then you are
ready to rewrite it in a form that makes it both a bit harder to under¬
stand and a bit more useful.
The one problem with the current function is that it is hard to
modify. To change the password, you must modify the words
“OPEN SESAME” in two places and probably also modify the
number of spaces that you give to mtry as its initial value. You can
solve this problem by using another variable, mright, to hold the cor¬
rect password, as shown in Figure 12.12.
Notice that, in this version of the program, you use initialize mtry
by using the function LENQ, which returns the length of a character
string: SPACE(LEN(mright)) returns a number of spaces equal to
the length of mright, no matter what the value of mright is, so that you
can now change the password without having to physically edit the
number of spaces displayed in the field where the user enters
the password. Likewise, the IF statements within the loop and at the
end of the program use the condition IF mtry = mright rather than
IF mtry = “OPEN SESAME”. Thus, it is now very easy to change
the password: you just need to modify the one line of code at the
beginning of the program that initializes mright.
USING AD VANCED PROGRAMMING TECHNIQUES 497

***********************************
♦FUNCTION PASSWORD
*a general purpose password function
***********************************

FUNCTION password
PARAMETER mdoing

PRIVATE counter, mright

mright = "OPEN SESAME"

counter = 0
DO WHILE counter < 3
CLEAR
mtry = SPACE(LEN(mright))
@ 10, 20 SAY mdoing + " is password protected."
@ 12, 20 SAY "Enter the password > " GET mtry
READ

IF mtry = mright
EXIT
ELSE
? CHR(7)
counter = counter + 1
LOOP
ENDIF
ENDDO

IF mtry = mright
RETURN .T.
ELSE
RETURN .F.
ENDIF

Figure 12.12: Revised code for the password function.

This final version of PASSWORD0 is very sophisticated code. As


an exercise, you should modify the earlier version of PASSWORD0
to incorporate these changes and try adding comments on your own.
If you can add comments that explain this function adequately, then
you are ready for sophisticated forms of structured programming.

A FEW EXTRA TRICKS _


Most of the features of the Program menu popup merely let you do
things that you have already learned about, but there are one or two
features of it that deserve special attention.
If you look at Figure 12.13, you will see that most features of the Pro¬
gram menu look familiar. Selecting Do from the Program menu is
equivalent to entering DO <prog namey, except that it displays a dialog
box that lets you select the program to be run from a scrollable list.
498 MASTERING FOXPRO

CH. 12

Figure 12.13: The Program menu.

As you learned in Chapter 10, selecting Cancel or Resume from


the Program menu will cancel or restart a program you interrupted
by pressing Esc.
Selecting Talk from the Program menu is a simple way of setting
Talk on or off, so that you can determine whether you will see the
values of variables that are created, for example, and other features of
FoxPro talk that might be useful during debugging. Selecting Com¬
pile from this menu lets you compile a program, in case you do not
want it to be compiled automatically during testing.
These features are fairly obvious. The really interesting and useful
features of the Program menu are Echo and Step, which let you use
the Trace window. The Trace window, shown in Figure 12.14, actu¬
ally displays each line of code as the program is run. For example, it
underlines the @ . . . SAY statement that makes it display text on
the screen at the same time that it displays the text on the screen. Of
course, you will often want to move the Trace window to see the dis¬
play on the screen.
If you select Echo from the Program menu or enter the command
SET ECHO ON, the program will execute as usual, and you will be
able to watch the lines of code pass by in the Trace window as the
USING AD VANCED PROGRAMMING TECHNIQUES 499

MAILPOWER! Main Menu 05/26/91

A) @ 8,25 SAY "D - Data"


10.25 SAY "R - Reports"
CPe/v P&/3U 12.25 SAY "L - Labels"
14.25 SAY "E - Export for mail merge"
-
16.25 SAY "Q - Quit MAILPOWER!"
y/z. tP' 22.26 SAY "What is your choice > " GET c

L - Labels
n E - Export for mail merge
K>-y

Q - Quit MAILPOWER!
NZCt
4 M

FP A, A I
What is your choice >
Mi-
Dil

r'fi
t i]
T) C
Figure 12.14: The Trace window.
aS§ Uj i fjpO-Aj
n< THE 'TRU

' <^r s,mmNn * K


program executes. It is often hard to debug the program, though,
' ^ SPftcsBM °'K when it is moving by in this way.
cuckoo °A-i 1o If you select Step from the Program menu or enter the command
UHZ of SET STEP ON, the Trace window will open and the program will
I IA execute one step at a time. There will be two text buttons at the bot¬
yJ (O mty:
l/U inJVO
tom of the Trace window, Resume and Cancel. You must select
c "Vc
Resume to make the program go to the next step (by clicking it with
Vfil
I If you have a delay-
the mouse or simply pressing R). Select Cancel to cancel execution of
Bn ing loop in your
program, it is agonizing
the program.
to make it execute over The Trace window is tremendously useful both for debugging and
and over again when you as a learning tool. If you cannot understand why a program’s logic is
have selected Step. Put
asterisks before all the
not working as you expected, you can almost always find the bug by
steps of delaying loops, setting Step on and watching the code as the program executes. The
such as the loop that Trace window is invaluable as a learning tool, because it makes con¬
counts to 200 while dis¬
trol flow so apparent. You should set Step on and DO the Mail
playing the Mail Power!
title screen. These steps Power! program, so you can watch each line of code executed as the
are then considered com¬ program runs. Test the program in this way and pay particular atten¬
ments and are not exe¬
tion to control flow, for example, to DO WHILE, IF . . . ELSE, and
cuted. Delete the asterisks
when you are finished
DO CASE statements. Notice, also, how control flows as one module
with the Trace window. calls another module and returns to another.
ffpp fo Btek
500 MASTERING FOXPRO

CH. 12

There is one other trick that you will find useful if you want to dis¬
tribute your programs as stand-alone applications. Rather than start¬
ing FoxPro and entering DO MAILPOW in the Command window
(or selecting Do from the Program menu), you can run your pro¬
gram directly from the operating system. All you have to do is enter
the command FOXPRO MAILPOW at the DOS Prompt to start
FoxPro and immediately execute the MAILPOW program. If you
enter this command, FoxPro will display its title screens for a
moment, but it will not display its Command window or menu bar:
instead, it will go directly to the Mail Power! main menu.
Of course, like any You can even relieve your user of the trouble of entering the word
other DOS com¬
mand, a batch command
FOXPRO as part of the command, by creating a DOS batch file. If
must be in the current you create a plain text file with the extension .BAT, DOS will exe¬
directory or on the search cute all the commands in that file when its name is entered. Thus,
path to be executed.
you can create a file named MAILPOW.BAT which has only the
command

FOXPRO MAILPOW

in it. When the user enters MAILPOW at the DOS prompt, DOS
will execute the command in the .BAT file and will start FoxPro and
immediately execute the Mail Power! program. (You can also add
commands to the .BAT file to do things such as automatically mak¬
ing the right directory into the current directory before executing the
program: for more information, see any intermediate or advanced
book on using DOS.)
Remember that you wrote the Main Menu module of Mail
Power! with the command QUIT at the end. Initially, you made this
command a comment, but if you delete the asterisk, then the pro¬
gram will execute the command and return to DOS as soon as the
user selects Quit from its main menu.
If you write a .BAT file so that users can just enter MAILPOW at
the DOS prompt to run the program, and if you include QUIT so the
user returns to the DOS prompt immediately after quitting the pro¬
gram, you will have made Mail Power! into a stand-alone program,
which is totally independent of FoxPro.
There is a FoxPro run-time module which you can use to run
stand-alone programs of this sort. A run-time module lets you dis¬
tribute your custom stand-alone programs to users who do not own
USING AD VANCED PROGRAMMING TECHNIQUES 501

To protect the code FoxPro. You must purchase the run-time module once, and then you
of programs that have the right to copy it and distribute it with your programs.
you distribute, you can
enter the command SET
You now have all the background in basic programming tech¬
ECHO OFF as the first niques that you need to write this sort of program. Though FoxPro
line of code in the pro¬ has many specialized commands and functions that we did not cover,
gram. Then users will not
this book did give you a very strong background in structured pro¬
be able to use the Trace
window to see the source gramming, and you should be able to apply the techniques you
code of the compiled learned to any programming problem that you need to solve.
program that you
Appendix C discusses some FoxPro commands that you have not
distribute.
learned yet, and your FoxPro Commands and Functions reference book
discusses the specialized commands that are used for working with
windows, pop-up menus, low-level file input/output, and many
other advanced capabilities of the FoxPro language. The Commands
and Functions reference includes sample programs using the more
difficult commands. Like any brief samples, though, these sample
programs can teach you to use these commands but cannot teach you
to use a large number of commands to build a complex program. The
background in structured programming that you have gotten in this
book will let you use any of these commands in your own work.
Figure 12.15 shows the final listing of the entire program. As an
exercise in structured programming technique, you might want to
rewrite the LOOKUP module as a user-defined function. Instead of
having it move the pointer to make EOF() true, have it return the
value of .T. if the record is found and .F. if the record is not found:
have the module ihat calls it use IF LOOKUP() rather than DO
LOOKUP with IF .NOT. EOF(). This is a much more elegant tech¬
nique and a step toward advanced programming.

★★★***********************************************
* MAILPOW.PRG
* a menu-driven, general purpose mailing-list program

*-display the title screen


CLEAR
@ 11,34 SAY "MAILPOWER!"
@ 14,14 SAY "copyright; Advanced Technology Development Systems"

Figure 12.15: The structured form of the complete MAILPOW program.


502 MASTERING FOXPRO

CH. 12

* -use database and set environment


USE maillist.dbf INDEX names, zips
SET TALK OFF
SET BELL OFF
SET DELETED ON

* -delay to let user read screen


counter = 0
DO WHILE counter <200
counter = counter + 1
ENDDO

* -create the main loop, to repeat the menu indefinitely


DO WHILE .T.

* -create a variable to hold the user's choice


choice = " "

* -display main menu and get user’s choice


DO scrnhead WITH "Main Menu"
@ 8,25 SAY "D - Data"
0 10,25 SAY "R - Reports"
@ 12,25 SAY "L - Labels"
0 14,25 SAY "E - Export for mail merge"
0 16,25 SAY "Q - Quit MAILPOWER!"
0 22,26 SAY "What is your choice > " GET choice PICT "I"
READ

* -perform option that user chose


* -or beep if choice was invalid
DO CASE
CASE choice = "D"
DO datamenu
CASE choice = "R"
DO reptmenu
CASE choice = "L"
DO lablmenu
CASE choice = "E"
DO exptmenu
CASE choice = "Q"
EXIT
OTHERWISE
? CHR(7)
ENDCASE
ENDDO

* -close the database and return environment to


* -default settings before exiting.

CLOSE DATABASES
SET TALK ON
SET BELL ON
SET DELETED OFF

♦QUIT

**************************************************
*DATAMENU procedure
*The Data submenu for Mail Power
♦called by the main module
**************************************************

Figure 12.15: The structured form of the complete MAILPOW program,


(continued)
USING AD VANCED PROGRAMMING TECHNIQUES 503

PROCEDURE datamenu

*-create the main loop, to repeat the menu indefinitely

DO WHILE .T.

* -create a variable to hold the user's choice


choice = " "

* -display the menu and get user's choice


DO scrnhead WITH "Data Submenu"
@ 8,25 SAY "A - Add a new entry"
@ 10,25 SAY "E - Edit an entry"
@ 12,25 SAY "D - Delete an entry"
@ 14,25 SAY "L - Look up an entry"
@ 16,25 SAY "F - Finalize deletions"
@ 18,25 SAY "R - Return to the Main Menu"
@ 22,26 SAY "What is your choice > " GET choice PICT "1"
READ

* -perform option that user chose


* -or beep if choice was invalid
DO CASE
CASE choice = "A”
* -append using GETDATA procedure
DO getdata WITH "append"
CASE choice = "E"
* -ask for password: if it is correct,
* -use GETDATA procedure to find record
* -user wants and edit it if found
SET PROCEDURE TO utils
IF password("Editing")
DO getdata WITH "edit"
ENDIF
CASE choice = "D"
* -Find record user wants and get
* -confirmation before deleting it if found
DO LOOKUP
IF .NOT. EOF()
confirm = " "
@ 16,10 SAY "Are you sure you want to
+"delete this record (y/n)? " GET confirm
READ
IF UPPER(confirm) = "Y"
DELETE
dummy = " "
@ 20,7 SAY "The record has been
+"deleted. Press any key to
+"continue..." GET dummy
READ
ENDIF
ENDIF
CASE choice = "L"
* -use LOOKUP to look up and display the entry
DO LOOKUP
IF .NOT. EOF()
dummy = " "
@ 16,16 SAY "Press any key to return to the";
+" menu... " GET dummy
READ
ENDIF

Figure 12.15: The structured form of the complete MAILPOW program,


(continued)
504 MASTERING FOXPRO

CH. 12

CASE choice = "F"


CLEAR
@ 12,15 SAY "One moment please...
PACK
CASE choice = "R"
EXIT
OTHERWISE
? CHR(7)
ENDCASE
ENDDO
RETURN

•ic'kic'k’kic'k'k'k'k-k'k'klt'k'k-kleic'kic'k-k’k-iclclc'k-k’k'kic'k'k'klc-k'k'k'k'klc'k'k'k'k'k-kls'k

*REPTMENU procedure
*The report submenu for Mail Power
*called by the main module
**************************************************

PROCEDURE reptmenu

*-create the main loop, to repeat the menu indefinitely

DO WHILE .T.

* -create a variable to hold the user's choice


choice = " "

* -display main menu and get user's choice


DO scrnhead WITH "Report Submenu”
@ 8,25 SAY "C - Complete Report"
@ 10,25 SAY "P - Phone Numbers and Names"
@ 12,25 SAY "3-3x5 Rolodex Cards"
@ 14,25 SAY "4-4x2 1/4 Rolodex Cards"
@ 16,25 SAY "R - Return to the Main Menu"
@ 22,26 SAY "What is your choice > " GET choice PICT "1"
READ

* -perform option that user chose


* -or beep if choice was invalid
DO CASE
CASE choice = "C"
REPORT FORM complete &&TO PRINT
WAIT
CASE choice = "P"
REPORT FORM phones &&TO PRINT
WAIT
CASE choice = "3"
LABEL FORM index &&TO PRINT
WAIT
CASE choice = "4"
LABEL FORM rolodex &&T0 PRINT
WAIT
CASE choice = "R"
EXIT
OTHERWISE
? CHR(7)
ENDCASE

ENDDO
RETURN

Figure 12.15: The structured form of the complete MAILPOW program,


(continued)
USING AD VANCED PROGRAMMING TECHNIQUES 505

**************************************************
*LABLMENU procedure
*The label submenu for Mail Power
*called by the main module
**************************************************

PROCEDURE lablmenu

*-create the main loop, to repeat the menu indefinitely

DO WHILE .T.

* -create a variable to hold the user's choice


choice = " "

* -display main menu and get user's choice


DO scrnhead WITH "Label Submenu”
@ 6,25 SAY "1 - One-column labels"
@ 8,25 SAY "2 - Two-column labels"
@ 10,25 SAY "3 - Three-column labels"
@ 12,25 SAY "L - Large one-column labels"
@ 14,25 SAY "C - Cheshire labels"
@ 16,25 SAY "S - Small Envelopes"
§ 18,25 SAY "W - Wide Envelopes"
@ 20,25 SAY "R - Return to Main Menu"
@ 22,26 SAY "What is your choice > " GET choice PICT "
READ

*--.-perform option that user chose


*-or beep if choice was invalid
DO CASE
CASE choice = "1"
LABEL FORM one-col &&TO PRINT
WAIT
CASE choice = "2"
LABEL FORM two-col &&TO PRINT
WAIT
CASE choice = "3”
LABEL FORM thre-col S.&T0 PRINT
WAIT
CASE choice = "L"
LABEL FORM large &&TO PRINT
WAIT
CASE choice = "C"
LABEL FORM Cheshire &&TO PRINT
WAIT
CASE choice = "S"
LABEL FORM smallenv &&TO PRINT
WAIT
CASE choice = "W"
LABEL FORM largeenv &&TO PRINT
WAIT
CASE choice = "R"
EXIT
OTHERWISE
? CHR ( 7
ENDCASE

ENDDO
RETURN

Figure 12.15: The structured form of the complete MAILPOW program,


(continued)
506 MASTERING FOXPRO

CH. 12

**************************************************
*EXPTMENU procedure
*The export submenu for Mail Power
*called by the main module

PROCEDURE exptmenu

*-create the main loop, to repeat the menu indefinitely

DO WHILE .T.

* -create a variable to hold the user's choice


choice = " "

* -display main menu and get user's choice


DO scrnhead WITH "Export Submenu"
@ 8,25 SAY "S - Export to SDF File"
@ 10,25 SAY "C - Export to Comma Delimited File"
@ 12,25 SAY "T - Export to Tab Delimited File"
@ 14,25 SAY "R - Return to the Main Menu"
@ 22,26 SAY "What is your choice > " GET choice PICT "!"
READ

* -.-perform option that user chose


* -or beep if choice was invalid
DO CASE
CASE choice = "S"
COPY TO export.txt TYPE SDF
CASE choice = "C"
COPY TO export.txt TYPE DELIMITED
CASE choice = "T"
COPY TO export.txt TYPE DELIMITED WITH TAB
CASE choice = "R"
EXIT
OTHERWISE
? CHR(7)
ENDCASE

IF choice = "S" .OR. choice = "C" .OR. choice = "T"


CLEAR
dummy = " "
@ 10,10 SAY "The data has been copied to a file
+ "named EXPORT.TXT"
@ 12,20 SAY "Press any key to continue...
GET dummy
READ
ENDIF

ENDDO
RETURN

**************************************************
* LOOKUP procedure
* lookup a record for editing, deleting or displaying data
* called by the DATAMENU procedure
**************************************************

Figure 12.15: The structured form of the complete MAILPOW program,


(continued)
USING ADVANCED PROGRAMMING TECHNIQUES 507

PROCEDURE LOOKUP

* -create a variable to hold the name the user wants

mlookfor = SPACE(20)

* -get the name the user wants,


* --or let the user press Enter to quit.

DO scrnhead WITH " "


@ 8,8 SAY "Enter the last name of the record you want:";
GET mlookfor PICT
@ 11,12 SAY "(Enter the entire last name or just the
+"initial letters)"
@ 13,20 SAY "(or press Enter to return to the menu)"
READ

* -If the user presses enter, move the pointer to


* -make EOF() true and then return to DATAMENU
IF mlookfor = SPACE(20)
GO BOTT
SKIP
RETURN
ENDIF

* -trim blanks, in case the user did not enter whole name
* -or entered leading blanks by mistake
mlookfor = ALLTRIM(mlookfor)

* -look for the name the user entered


SEEK mlookfor

* -if the name is not found, display an error message


IF EOF()
dummy = " "
@ 16,18 SAY "The name " + PROPER(mlookfor);
+ " is not in the file."
@ 18,21 SAY "Press any key to continue... " GET dummy
READ

* -if the name is found, see if it is the right one


* -put the confirmation in a loop, so you can ask
* -repeatedly for all records with same name
ELSE
DO WHILE .T.
@ 2,0 CLEAR
@ 3,0 SAY "Title: " + honorific
@ 3,15 SAY "First name: " + fname
@ 3,45 SAY "Last name: " + lname
@ 5,6 SAY "Company: " + company
@ 7,6 SAY "Address: " + address
@ 9,6 SAY "City: " + city
@ 9,38 SAY "State: " + state
@ 9,50 SAY "Zip code: " + zip
@ 11,25 SAY "Telephone: " + phone
@ 12,0 SAY "_
+"

Figure 12.15: The structured form of the complete MAILPOW program,


(continued)
508 MASTERING FOXPRO

CH. 12

mconfirm = "
6 14,18 SAY Is this the record you want (y/n)?
GET mconfirm
READ

* -if the name is correct, exit from the loop and


* -return to the calling program with the pointer
* -on the desired record. If the name is
* -not, check for other records with that name.
IF UPPER(mconfirm) = "Y"
EXIT
ELSE
SKIP
IF Iname = mlookfor
LOOP
ELSE
* -.—if no other records with that name,
* -print error message and make EOF true
dummy = " "
@ 16,18 SAY "The name you want is not in
+ "the file."
@ 18,21 SAY "Press any key to continue...
GET dummy
READ
GO BOTT
SKIP
EXIT
ENDIF
ENDIF
ENDDO
ENDIF

******************************************
*PROCEDURE SCRNHEAD
*a general purpose screen header
‘called by the MAIN program and by
‘procedures DATAMENU, REPTMENU, LABLMENU, EXPTMENU, LOOKUP

PROCEDURE scrnhead
PARAMETER menuname

CLEAR
@ 0,0 SAY "MAILPOWER1 " + menuname
@ 0,70 SAY DATE()
@ 1,0 SAY "_
il II

**********************************
‘PROCEDURE GETDATA
‘new module for editing or appending data
‘to be added to MAILPOW.PRG
‘called by DATAMENU procedure
■k-k'kie-k-k'k'k'kic'kicieit'kicieick'k'k'k-k'k'k'kicie-k'k'k'kie

PROCEDURE getdata
PARAMETER mode

Figure 12.15: The structured form of the complete MAILPOW program,


(continued)
USING AD VANCED PROGRAMMING TECHNIQUES 509

* -repeat for as long as the user wants to edit or append


DO WHILE .T.

* -append a blank record if you are appending or


* --—find the record to be edited if you are editing
IF mode = "append"
APPEND BLANK

ENDIF

IF mode = "edit"
DO LOOKUP
ENDIF

* -If LOOKUP has not found the record to edit, so that


*- EOF() is true, do nothing.
* -If LOOKUP has found the record to edit, initialize
*- variables with the values in its fields.
* -If you are appending, initialize memory variables
*- with blanks from the current record.
IF .NOT. EOF()
mhonor = honorific
mfname = fname
mlname = lname
mcompany = company
maddress = address
mcity = city
mstate = state
mzip = zip
mphone = phone

---set environment for data entry


SET BELL ON

Print the screen header,


including the words "Append" or "Edit" Records

DO scrnhead WITH PROPER(mode) + " Records"

*-Display fields and get user input


@ 3,0 SAY "Title 2" GET mhonor PICT "@!"
@ 3,15 SAY "First name:" GET mfname PICT "@!"
@ 3,45 SAY "Last name:" GET mlname PICT "@! "
@5,6 SAY "Company:" GET mcompany PICT "@1"
@ 7,6 SAY "Address:" GET maddress PICT "@!"
@ 9,6 SAY "City: " GET mcity PICT "@!"
@ 9,38 SAY "State:" GET mstate PICT "@!"
@ 9,50 SAY "Zip code:" GET mzip PICT "99999"
@ 11,25 SAY "Telephone:" GET mphone;
PICT "(999)999-9999"
@ 13,15 SAY "---";

„,
+ "-.
14,15 SAY "| <- -> : Move cursor within";
+" field |
15,15 SAY
+" |
16,15 SAY "| Tab Shift-Tab : Move cursor to ";
+"next/last field |
17,15 SAY " ________ " •
r
+

Figure 12.15: The structured form of the complete MAILPOW program,


(continued)
510 MASTERING FOXPRO

CH. 12

READ

* -return to environment setting


* -used for choices and menus
SET BELL OFF

* -have user confirm that input is right


confirm = "Y"
§ 19, 15 SAY "Do you want to finalize these";
+ " changes (y/n) ? " GET confirm PICT "I"
READ

*-if it is right, put it in database file


My "
IF confirm =
REPLACE honorific WITH mhonor
REPLACE fname WITH mfname
REPLACE lname WITH mlname
REPLACE company WITH mcompany
REPLACE address WITH maddress
REPLACE city WITH mcity
REPLACE state WITH mstate
REPLACE zip WITH mzip
REPLACE phone WITH mphone

@ 21, 15 SAY "The database file has been changed1.”

* -If it is not right, do not put it in file, and


* -if a blank record has been appended, delete it.

ELSE
@ 21, 15 SAY "The changes will be discarded."
IF mode = "append"
DELETE
ENDIF
ENDIF
ENDIF

*-let the user append or edit another record


again = "Y"
@ 23, 15 SAY "Do you want to " + mode + " another (y/n) ?
GET again PICT "!"
READ

IF again = "Y”
LOOP
ELSE
EXIT
ENDIF
ENDDO

***********************************

★FUNCTION PASSWORD
★a general purpose password function
***********************************

FUNCTION password
PARAMETER mdoing

PRIVATE counter, mright

mright = "OPEN SESAME"

Figure 12.15: The structured form of the complete MAILPOW program,


(continued)
USING AD VANCED PROGRAMMING TECHNIQUES 511

counter = 0
DO WHILE counter < 3
CLEAR
mtry = SPACE(LEN(mright))
@ 10, 20 SAY mdoing + " is password protected."
@ 12, 20 SAY "Enter the password > " GET mtry
READ

IF mtry = mright
EXIT
ELSE
? CHR(7)
counter = counter + 1
LOOP
ENDIF
ENDDO

IF mtry = mright
RETURN .T.
ELSE
RETURN .F.
ENDIF

Figure 12.15: The structured form of the complete MAILPOW program,


(continued)
- .
Hill

WmK0SS$
ill
514 MASTERING FOXPRO

APP. A

INSTALLING FOXPRO IS A VERY SIMPLE PROCESS.


After you enter the INSTALL command, it is essentially done for you.
First, however, you must create a directory for FoxPro and make a
simple alteration in your AUTOEXEC.BAT file. Then, after the main
program is installed, you must choose which optional features you need.
This appendix will recommend that you install the features that are used
in this book, but you can also install added features.
You must have enough hard disk space before you install FoxPro.
The program plus the optional features that this appendix recom¬
mends require almost 3 megabytes of hard disk space. In addition,
you should have 1 megabyte or more of free space on your hard disk,
because FoxPro creates temporary files while it is running that can
take a megabyte or more of space.
Before installing FoxPro in the way that is recommended, then,
you should have 4 megabytes of free space on your hard disk. If you
do not have this much space, you can install the smaller FoxPro help
file, which is 650 kilobytes smaller than the regular help file; or you
can save a full 875 kilobytes by installing no help file at all. You can
also save space by not installing FoxView; but then you will not be
able to do the exercises in Chapter 9. The base FoxPro package with¬
out any extra features requires about 1.5 megabytes of disk space.
To find out how much free disk space you have, just look at the
directory of the hard disk. Virtually all IBM compatible microcom¬
puters use the letter C to designate the hard disk drive: unless you
have some special hardware configuration, you may assume that C is
the hard drive, as in all of the following instructions.

1. Make sure you are logged into your hard disk. If you are not,
enter the command C: (do not forget to include the colon
after the disk letter). You can be in any subdirectory of the
hard drive.

2. Enter the command DIR. The directory of files will scroll by


and the number of bytes free will be at the bottom of the list.

If you do not have more than 1 megabyte of free disk space when
you are running FoxPrp, it might terminate abnormally and return
you to DOS. This would most likely occur when you are editing files
or programs, which requires extensive use of temporary files. For
INSTALLING FOXPRO 515

other operations, though, this would happen very rarely, even if you
have only half a megabyte free.
Before installing FoxPro, you also need two things that came with
the program:

• five 5V4-inch disks or three 3V2-inch FoxPro distribution


disks
• the envelope with your activation key and serial number

The envelope includes a demonstration activation key on the out¬


side and a “live” activation key on the inside. Note that once you
open the envelope to use the inside key, you accept the FoxPro licens¬
ing agreement: you should read this agreement before opening the
envelope. If you want to install a demo version of FoxPro, to try
the program out, do not open the envelope: just use the key and serial
number from the outside. This DEMO version works the same way
as FoxPro except that it lacks some of the features of the live version
and cannot hold more than 120 records. You can upgrade from the
demo to the live version of FoxPro at any time by reinstalling the pro¬
gram using the inside key.
Before installing either the live or the demo version, you must
create a “home directory” to hold the program. In the course of
installation, FoxPro will create other directories under the home
directory to hold samples, demos, tutorials, compiled templates, and
template source code, if you choose to include them. You will see, as
we have said, that there is a separate section of the installation process
where you choose among these optional products. If you have the
extra disk space and want to select more options than are used in this
book, feel free to do so.
It is best to name the home directory FOXPRO, though you may use
another name if you choose. Then you just need to make the home
directory the current directory, and enter the INSTALL command.

1. If you have not already done so, make sure you are logged
into your hard drive. If your hard drive is drive C, enter the
command C: to make that the current drive. Make sure you
are in the root directory: if you are not sure what subdirec¬
tory you are in, enter the command CD \ to move to the root
directory. (The backslash stands for the root directory.)
2. Type MD \FOXPRO to make a new directory named FOX¬
PRO under the root directory.

3. Type CD \FOXPRO to change this new directory into the


current directory.

4. Now you are ready to install FOXPRO. Insert FoxPro disk 1


into your A: floppy disk drive. You must enter A:INSTALL
plus the letter of your hard disk drive followed by a colon.
Thus, assuming that your hard disk is drive C:, type A:IN-
STALL C: and press Enter. FoxPro asks you to confirm that
the files should be installed in the current directory of the disk
whose letter you enter—the C:\FOXPRO directory that
you just created and made the current directory. Read the
information on the screen, which tells you about your serial
number, then press any key to continue installation.

5. Enter your serial number and activation key when FoxPro


prompts you for them. FoxPro will begin installing files onto
your hard disk, and will display a bar to show how much of each
file has been installed. Some FoxPro files on the distribution
disk are in compressed form so they take up less space; they are
automatically decompressed before they are installed on the
hard disk. This can take up time if you have a slow computer,
so be patient if FoxPro seems to be waiting and doing nothing
before it starts installing.

6. If instructions appear on the screen, telling you to replace one


disk with the next and to press any key to continue, follow
them. Finally, a message will be displayed telling you that
FoxPro has been installed and that you can begin optional
products installation.

7. Press any key to continue with optional products installa¬


tion. FoxPro will install some support for the additional fea¬
tures or products and then prompt you to enter your monitor
type. Unless you have one of the specific Compaq or Toshiba
monitor types listed, just select Generic Color if you have
a color monitor or Generic Monochrome if you have a mono¬
chrome monitor.
INSTALLING FOXPRO 517

8. Now you can use the Contents window to select which


optional features you want installed. Notice that the feature is
listed in the left column, the amount of disk space that it takes
is in the center column, and the right column indicates
whether it will be installed or not. The details window on the
right describes what each optional feature does. The instruc¬
tions on the top tell you how to select the features. The win¬
dow at the bottom of the screen tells you how much disk space
you have free and how much you need for the features you
have selected.

9. Press the space bar to select the Help hie, which is currently
underlined. (If you are short of disk space, you can press the
down arrow to move the underline to the small Help hie and
then press the space bar; if you are very short of disk space,
do not select either.) Note that the word YES appears to its
right to indicate that it has been selected.

10. Press the down arrow key to move the underline to FoxView,
the screen and applications design tool, and press the space
bar to select it.

11. Press the down arrow key to move the underline to Compiled
Template, which is used when you generate code with Fox-
View, and press the space bar to select it.

12 If you decide that you want any other optional features, select
them in the same way. If you have a color monitor, you
should select color sets.

13. After you have selected all the options you want, press Enter
to install everything you have selected. FoxPro asks you for
confirmation: press Enter to install or N to abort. As it is
installing the optional features, FoxPro will ask you to insert
other disks: follow its instructions by inserting the appropri¬
ate disk and pressing any key to continue. For FoxView, it
will again ask for your monitor type and name, since Fox¬
View is a separate product that has been integrated with
FoxPro. Enter them as you did in Step 7 above.
518 MASTERING FOXPRO

APP. A

14. After the optional products are installed, FoxPro will display
a message saying FoxPro Installation Complete and will
return you to the DOS prompt. Remove the installation disk
from the A: drive. You are now in the FOXPRO directory of
your hard drive, which you created before installation. If you
want to see the files you have installed, enter DIR.

Some sample databases are automatically installed along with the


program. This book does not use them, since it creates samples of its
own: unless you have some reason for keeping them, you should
delete these sample files:

1. Assuming you are still in the C:\FOXPRO directory, enter


CD DEMO to make the C:\FOXPRO\DEMO directory the
current directory. (If you have changed the current drive, enter
C: first to return to the hard drive. If you have changed director¬
ies, enter CD \FOXPRO\DEMO instead of just CD DEMO.)

2. Enter DIR. Make sure that this is the DEMO director)7 and
that it includes files such as DEMO.DBF.

3. Enter DEL *. * to delete all files in this directory. When DOS


asks if you are sure, enter Y.

4. Enter CD \FOXPRO to return to the FOXPRO directory.


(Do not forget the backslash before the word FOXPRO.)
Then enter RD DEMO to get rid of the DEMO directory.

Finally, before using FoxPro, you should change the PATH com¬
mand in your AUTOEXEC.BAT file. This is the file in your root
directory which contains a list of commands that DOS automatically
executes whenever you start your computer.
A PATH command determines which directories the system looks
in when you enter a command at the DOS prompt. DOS always
looks in the current directory, and then looks in any directories listed
in the PATH command. For example, consider this typical PATH
command:

PATH C:;C:\DOS;C:\UTIL;C:\WP50;C:\FOXPRO
INSTALLING FOXPRO 519

Notice that a semicolon is used to separate directory names but is not


used after the final directory name.
After this command is executed, DOS looks not only in the current
directory, but also in the root directory, in a directory named C:\DOS
which contains DOS commands, in a directory named C :\UTIL which
contains utility programs, in a directory named C:\WP50 which con¬
tains a word processing program, and in a directory named C ^FOX¬
PRO which contains FoxPro. Once you have entered this command,
you can execute any of these programs from any directory: you do not
have to be in the directory that contains them to use them.
Thus, you should add the new directory you created to hold Fox¬
Pro to the directories already listed in your PATH command, so you
can use FoxPro from any directory in your hard disk.

Enter CD \ to make the root directory the current directory.


Enter TYPE AUTOEXEC.BAT to display the contents of this
file on the screen.

If you have this file, use any word processor or text editor that
can edit plain ASCII files (which some word processors call
DOS files) to change it. If you do not have this file, you
should create one, again using any editor that can create
ASCII files.

Your AUTOEXEC.BAT file probably contains a line that


begins with the word PATH and looks like the PATH com¬
mand listed above. If so, add the directory you just created to
hold FoxPro. (Add it to the end of the list). Add a semicolon
before but not after the directory name. Use the full name,
beginning with the letter of the disk, followed by a colon, fol¬
lowed by a backslash, followed by the subdirectory name—
for example, C:\FOXPRO.

4. If you do not have a PATH command in your AUTOEXEC


.BAT file, add one on a separate line from the other com¬
mands. If you do not have an AUTOEXEC.BAT file, you can
create one with just the PATH command. (If you don’t have a
clock/calendar, you probably also want to include the com¬
mands DATE and TIME, each on a separate line, so the
computer continues to ask the date and time when you start it,
520 MASTERING FOXPRO

APP. A

as it does when you start the computer without an AUTOEX¬


EC. BAT file.) In either case, the command will simply be
PATH C:\FOXPRO. If you want to add other directories to the
search path, just remember to place semicolons between direc¬
tory names but not after the last directory name.

When you start your computer again, the AUTOEXEC.BAT com¬


mand will be executed, including the PATH command that you added.
M—— ', . >,;;;.: :■■ ■

liiiiiiiliiliiiiiiai
' . i .

:
fggg^j|p||g§g^$§||^gPl

1111
522 MASTERING FOXPRO

APP. B

YOU CAN USE FOXPRO’S SYSTEM MENU POPUP TO


access the filer and a number of other desktop utilities, including a
calculator, a calendar/diary, an ASCII chart, a screen capture util¬
ity, and a utility that lets you use DOS special characters.
These menu options were not discussed in the main body of this
book because they are not directly related to the main purpose of
FoxPro—database management. As utilities, they are useful (by
definition), but they are not of the essence of the program, so it did
not make sense to interrupt learning the main functions of FoxPro to
learn about them. Now that you have finished the main portion of
this book, though, you will find that it is worth your while to learn the
capacities of these added utilities.

THE FILER _
The filer is a file management utility that can perform most of the
functions of the DOS operating sytems. Because DOS is based on
procedural commands that are difficult to learn, many commercial
programs have been developed that act as menu-driven substitutes
for it. The filer replaces DOS with a system that uses text buttons,
text boxes, scrollable lists, and the other interface features that you
should be very comfortable with after having used FoxPro. It is also
much more powerful than DOS.
The filer has two panels. Its Files panel lets you work with individ¬
ual files. Its Tree panel lets you work with the entire subdirectory sys¬
tem, so you can manipulate all the hies in a directory or a group of
directories.
When you are using the filer, you can move between these panels
in two ways. Each has a text button in its lower right corner that lets
you toggle to the other: select the Files or Tree text button of the
respective panels to toggle between panels. When you are using
the filer, a Filer menu pad is added to the menu bar: the last option
on its menu popup lets you move to the panel you are not using.
Depending on which panel you are using, select Tree Panel or Filer
Panel from the Filer popup in order to toggle between the two.
THE FOXPRO FILER AND DESK TOP UTILITIES 523

You can start the filer by selecting Filer from the System menu or
by entering FILER in the Command window. When you first start it,
the Files panel appears: since this is the default panel of the filer, we
will discuss it first.

THE FILES PANEL


D The first three files
in the scrollable list
When you start the filer, you use the Files panel, shown in Fig¬
ure B. 1. If you compare the text buttons on this panel with the options
in the illustration are
on the Filer menu bar, shown in Figure B.2, you will see that the selec¬
temporary files created by
FoxPro, which FoxPro tions on the Filer popup are essentially the same as the selections offered
names using random by the text buttons in the dialog box. (The two menu options that are
combinations of letters
dimmed, Mkdir and Chdir, are activated when the Tree panel is used
and numbers. You
should never delete or and are offered as text buttons in that panel.) As with some other fea¬
otherwise alter these files tures of FoxPro that you have learned, the menu of the filer is meant
while you are using Fox¬
largely as an alternative to selecting text buttons: if you get in the habit of
Pro, and they are
dimmed in the filer’s
using the Control-key combinations listed on the menu, you will be able
scrollable list, so you to use the filer very quickly even with the keyboard.
cannot access them. If
some are not deleted
automatically when you
quit from FoxPro, you
can delete them from the
DOS prompt—but do not
do this while FoxPro is
still running.

Figure B.l: The Files panel.


524 MASTERING FOXPRO

APR B

System File Edil: Database Record Program Window Filer


Filer

Name Ext Size Last Modified Attr

00161E0C Feb-91 12:22a . a.


00162421 Feb-91 12:22a . a.
00170146 0 26- Feb-91 12:23a .a.
ANSWER5 .DBF 778 12- Feb-91 3:00a .a.
ANSWER5 . FPT 742 12- Feb-91 3:00a .a. Tag 011
CALNAMES . IDX 1024 08- Jan-90 3:55a .a. Tag IJone
DATAENTR . FMT 1028 07- Feb-91 10:52a .a. Inflert
DATAENTR . PRX 1223 07- Feb-91 10:31a .a.
DATES
EMPLIST
.IDX
.DBF
1024
1738
08-
07-
Jan-90 3:55a
Feb-91 10:33a
.a.
.a.
Sind...
Mkdir..
P
EMPLIST • FPT 803 02- Feb-91 2:39a .a. Chdir
Sort...
< Find > < Copy > Move < Delete >
< Edit > < Attr > Rename < Size > Tree PaneQ

Figure B.2: The Filer menu.

MOVING AMONG DIRECTORIES AND FILES


The filer’s Files panel contains a scrollable list of files and Drv and
Dir popup controls that are very similar to the ones you have seen
elsewhere in FoxPro, for example, in the Open and the Save As dia¬
log boxes.
The hierarchical
As in these other dialog boxes, the scrollable list of files in the filer
directory structure
was explained in Chap¬
includes (in addition to the names of the files in the current directory)
ter 2. If you need to the names of all the children directories that are under the current
review the details of how directory enclosed in square brackets, and two dots enclosed in
the directory structure is
square brackets to represent the parent directory of the current direc¬
organized, see that
chapter. tory. By selecting parent or child directories, you can move up and
down through the entire hierarchical directory system.
This scrollable list also contains other details about the file, which
are included in DOS directories but not in similar scrollable lists of
files that you have seen in FoxPro. In addition to a file’s name and
extension, the filer’s scrollable list also includes the file’s size (in
bytes) and the date and time that it was last modified, as DOS direc¬
tories do. Finally, in the column at its far right, the filer’s scrollable
list includes the files’ attributes: these determine such things as
whether a hie can be written to or can be read only. The filer makes it
THE FOXPRO FILER AND DESKTOP UTILITIES 525

easy to change them using the Attr text button or via a menu selec¬
tion: attributes will be discussed in detail when these selections are
discussed.
The two popup controls in the filer also work like the popup con¬
trols that you have seen in the Open and Save As dialog boxes. The
Drv popup lets you change the drive—for example, you can select A:
to make floppy disk drive A the current drive. The Dir popup control
lets you move quickly through a directory structure that is many lev¬
els deep, by letting you select any subdirectory, up to the root direc¬
tory, from the popup rather than repeatedly selecting the parent
directory from the scrollable list.
The text box labeled Files Like (under the Dir popup control) lets
you use a scrollable list that displays only some of the files in the cur¬
rent directory. The default setting for Files Like is *. *, which displays
all files, but you can specify files to be displayed by using literal char¬
acters in combination with the two DOS wild-card characters:

• * represents any word

• ? represents any single character

The file name and extension are two different words, so that *.*
represents any name followed by any extension. If you wanted to list
only your FoxPro database files, you could enter *.DBF in this text
box, so files with any name followed by the DBF extension would be
listed. If you have a group of files that you gave names beginning
with the letter J, you could list them all by entering J??????. * in this
text box.
You can combine more than one specification in this box if you
separate them with semicolons. For example, you could enter
*.DBF;*.DBT;*.FPT to list all database files and any associated memo
files (including both FoxPro and the older dBASE compatible
memo hies). Do not leave a space after the semicolon.

TAGGING FILES
The process of tagging hies is the key to using the hler. Tagging
simply means selecting a hie in such a way as to make a triangle
marker appear to the left of its hie name. Most text buttons or menu
526 MASTERING FOXPRO

APP. B

selections work only on files that are tagged. If no file is tagged when
you select them, they will simply display an error message.

Tagging Files Individually with the Keyboard To tag an individual


file using the keyboard, move the highlight to it and press the space
bar. A triangle appears to the left of any file that you tag.
Since you generally want to perform commands on a single file,
tagging one file normally eliminates any tag you previously put on
another file. If you want to tag more than one file while selecting files
individually, press Shift and the space bar together, and the tags you
created previously will not be eliminated.
If a file is already tagged, moving the highlight to it and pressing
Shift and the space bar together will eliminate the tag.

Tagging Files Individually with the Mouse To tag an individual file


using the mouse, point to the file and click. To tag more than one file,
hold down the Shift key when you select later files—or hold down the
Shift key and drag the mouse to select a number of consecutive files.
To untag a file using the mouse, press Shift while you point to the
file and click. If it is already tagged, the tag will disappear.

Tagging Groups of Files The filer also contains three text buttons
that let you tag and untag groups of files; there are three menu
options that are identical to these text buttons.

• Tag All: tags all the hies that are displayed in the scrollable
list. This option is most useful if you use it in combination
with the Files Like text box. For example, enter *.DBF in the
Files Like text box, so that your database hies are displayed;
then select Tag All to tag all the database hies.

• Tag None: removes tags from all hies in all directories. Unlike
Tag All, Tag None does not work only on displayed hies—it
works on all hies in all directories. Use it to make sure that
you do not have any hies tagged that you do not know about.

• Invert: removes tags from all tagged hies, and tags all un¬
tagged hies in the current directory. For example, if you want
to delete all except the database hies in the current directory,
THE FOXPRO FILER AND DESKTOP UTILITIES 527

you can tag the database files and then select Invert. The
database files will be untagged and all the other files will be
tagged, at which point you can then select Delete.

You can also tag more than one file at a time by selecting the Find
text button (or menu option), described in the next section.

FIND
Selecting the Find text button or selecting Find from the Filer
menu calls up the Find dialog box, shown in Figure B.3.

System Kile Edit Database Record Program Window Filer


Filer

Name Ext Size Last Modified Attr

[..]
01252061
06-Nov-90 1:27a .... Q Drv.

0125285D
01261E1F Find and tag files which have names like
ANSWER5
ANSWER5
CALNAMES
DATAENTR [ ] Specify text to search for...
DATAENTR
DATES [ ] gearch subdirectories
EMPLIST
EMPLIST « Sind * < gancel >
< Firid > < Copy > < Move > < Delete >
< Edit > < Attr > < Rename > < Size >

Figure B.3: The Find dialog box.

The Find dialog box lets you tag files based either on their names
or on their content. It can search in just the current directory or in a
number of directories.
The simplest way to use Find is to fill in the text box in the same
way that you do the Files Like text box of the Filer dialog box. As you
can see in the illustration, this box contains *.* by default, which
means it matches all files unless you instruct it to do otherwise. You
can fill it out with the wild-card characters (* and ?) and literal
528 MASTERING FOXPRO

APP. B

characters just as you learned to do with the Files Like text box in the
previous section.
Even if you are just searching for file names in this way, though,
the Find dialog box does more than the Files Like text box, because
you can select its Search Subdirectories check box to find matching
files in all subdirectories under the current directory. If you want to
search all the directories in the current drive, just make the root direc¬
tory the current directory before beginning the search. For example,
if you make the root directory the current directory, enter *.DBF in
the text box, and check the Search Subdirectories check box, you can
tag all the database files in all the directories of the current disk drive.
You can also use Find to search text files. It will tag those that con¬
tain text that you specify. If you select the Specify Text To Search For
check box, you will call up the dialog box shown in Figure B.4.

System File Edit Database Record Program Window Filer


Filer-

Name

[••] Tag only those files that contain


01252061
0125285D mmsm
01261 ElF fTflii
ANSWERS
ANSWERS of the following strings:
CALNAMES
DATAENTR
DATAENTR
DATES
EMPLIST
EMPLIST

< Find > [X] Qgnore case « Ek »


< Edit >
[ ] Hatch words < @ancel >

Figure B.4: Dialog box for tagging files based on content.

Though you cannot see them in the illustration, there are three
text boxes under the words “of the following strings, ’ ’ where you can
fill in the character strings that you want to search for.
The Any and All radio buttons are useful if you fill in more than
one of these text boxes: they let you specify whether the file or files
THE FOXPRO FILER AND DESKTOP UTILITIES 529

should be tagged if they contain any of the strings you specified, or


whether they should be tagged only if they contain all the strings you
specified.
The Ignore Case check box, as you might imagine, lets you deter¬
mine whether the search will tag a file if the capitalization of the char¬
acters in the file is different than in the string you specified. As you
can see, the search ignores capitalization by default.
Checking the Match Words check box makes the search tag a file
only if the string that matches your specification is a separate word,
not embedded in some larger word. If you were looking for the word
id, for example, you would want to check this check box so that the
program does not tag files that contain words such as slid, idiom, and
widget.
Consider an example that combines several capacities of Find: tag¬
ging all the FoxPro programs in your hard disk that contain the
LOOP command. First, you move to the root directory of your hard
disk. Then select Find to call up the Find dialog box, and enter
*.PRG in its text box. Check the Search Subdirectories check box,
check the Specify Text to Search For check box to call up the second
dialog box, enter LOOP in its text box as the string to search for,
remove the check from the Ignore Case check box (assuming that you
capitalize the key words in your programs), check the Match Words
check box, and select OK to return to the Find dialog box. Finally,
select Find to tag the matching files.
As you will see, you can use the filer to perform operations on all of
these files after they are tagged. For example, you can delete, copy,
or even edit all of them at once.

COPY
Selecting the Copy text button, or Copy from the Filer menu, calls
up the Copy dialog box, shown in Figure B.5.
This dialog box lets you copy tagged files. Copying a file preserves
the original file and creates a duplicate of it that either has another
name or is in another location.
Remember that the files must be tagged before you call up the
Copy dialog box.
530 MASTERING FOXPRO

APP. B

System File Edit Database Record Program Window Filer


Filer

Name Ext Size Last Modified Attr

[77] 06-Nov-90 1:27a .... fl Drv. ( ~C


00280
00280
00282 Copy tagged files as
►ANSWE
ANSWE <Target. directory. . . Q C:\LEARNFOX\
CALNA
DATAE
DATAE
DATES
EJ1 eplace existing files
reserve directories

EMPLI
EMPLI
Copy < Cancel >
< Find
< Edit > < Attr > < Rename > < Size > < Tree >

Figure B.5: The Copy dialog box.

The Copy Tagged Files As text box, at the top of this dialog box,
lets you specify the name of the file. The default, *. *, keeps the origi¬
nal name of the file. You can change the name by adding literals
instead of the wild-card characters. For example, if you want to make
backups of tagged files, you can enter *.BAK in this text box: all the
tagged files will be copied to files with the same name except for
the .BAK extension.
The target directory text button and text box let you specify the direc¬
tory that you want the copies of the file to be in. If you select this text but¬
ton, you will call up the Select Target Directory dialog box, shown in
Figure B.6. As you can see, this dialog box works like the Open or Save
As dialog box: it lets you use a scrollable list to move to the parent or chil¬
dren directories of the current directory; the Directory popup control
lets you move quickly up and down the subdirectory tree; and the Drive
popup control lets you select the disk drive. Alternately, you can just
type the disk and directory in the text box to the right of this text button.
Notice that the default target directory is the current directory; you
have also seen that the default is for the copies to have the original files’
names. You must change one of these defaults. You can copy files to
another directory or disk while keeping their current names, or you can
THE FOXPRO FILER AND DESKTOP UTILITIES 531

System file Edit Database Record Program Window Filer


Filer

Name
Select Target Directory
[..] C:\MAILPOW c
00280
00280 [■ J Drive
00282
►ANSWE
ANSWE
Co

<fl
MAILP0W1
MAILP0W2
[MAILP0W3
]_
CALNA Directory MAILPOW
DATAE
DATAE
DATES « Select »
EMPLI
EMPLI < Open >

< Find < Cancel >
< Edit > >

Figure B.6: The Select Target Directory dialog box.

copy files in the current directory with different names, but you cannot
have two files with the same name in the same directory.
If you check the Replace Existing Files check box of this dialog
box, the files produced by the COPY command will overwrite exist¬
ing files with the same names without giving you any warning. If you
do not check this check box, the command will display an alert before
it overwrites a file. After you select Yes or No to determine whether
that file will be overwritten, the command will go on and copy the
rest of the tagged files.
If you check the Preserve Directories check box, the command will
copy the directory structure as well as the files that are tagged. If this
check box is not checked, tagged files from various subdirectories will
all be copied into a single subdirectory. This feature will be explained
in the discussion of the filer’s Tree panel.

MOVE
Selecting the Move text button, or Move from the Filer menu,
calls up the Move dialog box, shown in Figure B.7.
532 MASTERING FOXPRO

APP. B

System file Edit Database Record Program Window filer


f 1 ler

Name Ext Size Last Modified Attr

[..] #6-Nov-90 1:27a Q Drv. C


00280
00280
00282 Move tagged files as *.*
►ANSWE
ANSWE
CALNA
DATAE [ 1 (Replace existing files
DATAE [ J preserve directories
DATES
EMPLI
EMPLI
« Mofle » < Cancel >
< Find
< Edit > < Attr > < Rename > Size Tree

Figure B. 7: The Move dialog box.

Move is like Copy, except for one point. Copy creates a duplicate
file and preserves the original; Move creates a duplicate file and elim¬
inates the original.
As you can see, the Move dialog box looks exactly like the Copy
dialog box, and all of its features function in the same way. The only
difference is that, after you enter all of the specifications and select
Move, the original file is eliminated. The effect is that the file is
moved from its current location to the specified location; it is not just
copied at the specified location.

DELETE
Selecting the Delete text button, or Delete from the Filer menu,
calls up the Delete dialog box, shown in Figure B.8.
This dialog box asks you to confirm that you want to delete each of
the tagged files. Select Delete to delete the one file whose name is dis¬
played. Select Skip to retain the file whose name is displayed; the dia¬
log box will go on and ask you about deleting any other tagged files.
Select Delete All to avoid this file-by-file confirmation process and
delete all tagged files immediately. Needless to say, you should use
Delete All with caution.
THE FOXPRO FILER AND DESKTOP UTILITIES 533

SORT
Selecting the Sort text button or Sort from the Filer menu calls up
the Sort dialog box, shown in Figure B.9.

System File Edit. Database Record Program Window Filer


Filer

Name Ext Size Last Modified Attr

[••] 06-Nov-90 1:27a Drv.


00280325 0 27-Feb-91 12:40a . a.
00280B
002822
►ANSWER
ANSWER Are you sure you want to delete this file?
3
CALNAM
DATAEN C:\LEARNF0X\ANSWER5.DBF
DATAEN
DATES « delete » < gkip > < Delete 011 > < gancel >
EMPLIS
EMPLIS

< Find > < Copy > < Move > < Delete > Sort >
< Edit > < Attr > < Rename > < Size > < Tree >

Figure B. 8: The Delete dialog box.

System File Edit Database Record Program Window Filer


Filer

Name Ext Size Last Modified Attr

[..]
00280325
06-NOV-90 1:27a 1 Drv.

00280B16
00282223 Select Sort Criteria LEARNFOX
►ANSWER5 .DBF
ANSWERS . FPT ame
CALNAMES . IDX tension (•) 0scendlng Like
DATAENTR . FMT lze
DATAENTR . PRX ( ) descending
DATES .IDX Attributes ag All >
EMPLIST .DBF ag None >
EMPLIST .FPT « gjK » < gancel > Invert >

< Find > < Copy > < Move > < Delete >
< Edit > < Attr > < Rename > < Size > Tree

Figure B.9: The Sort dialog box.


534 MASTERING FOXPRO

APP. B

This dialog box lets you change the order in which files are dis¬
played in the filer’s scrollable list. As you can see, the radio buttons
Name and Ascending are checked by default, so that the files are dis¬
played alphabetically by name.
You can also select radio buttons to display the files in the order
determined by their extension, size, date, or attributes. (Attributes
will be discussed later in this appendix.) The most useful of these is
Extension: it is often handy to sort by extension so that files of the
same type (database files, index files, program files, and so on) are
grouped together.
The other two radio buttons let you choose ascending or descend¬
ing order. You might want to choose Descending in order to have the
most recent dates come first, or to have the largest files come first.

EDIT
Selecting Edit opens edit windows for all tagged files.
You might find this useful, for example, if you want to open edit
windows for all your program files. You could enter *.PRG in the
Files Like text box and then select Tag All to tag all program files,
then simply select Edit to open edit windows for all these files. The
edit windows will appear to be stacked, and you can call any one for¬
ward to work on it.

ATTR
Selecting the Attr text button, or Attr from the Filer menu, calls up
the Attributes dialog box, shown in Figure B.10.
These attributes are represented by letters in the Attr column of
the file list.
An r in this column means that the file is Read Only: a user can
read the hie but cannot delete, edit, or otherwise modify it.
An a in this column means that the hie is newly created or has been
modihed since it was last backed up. Most backup programs back up
only hies that have this attribute and switch this attribute off so they
do not copy them again the next time they do a backup. The attribute
is switched on again if the hie is modihed.
THE FOXPRO FILER AND DESKTOP UTILITIES 535

Figure B.10: The Attributes dialog box.

Changing the sys¬ An h in this column means that the hie is a hidden hie, which does
tem or the hidden not appear in an ordinary DOS directory. DOS includes two hidden
attribute can let you
create later errors that
hies in the root directory, IBMBIO.COM and IBMDOS.COM;
prevent your operating you have not seen these in your root directory, but you can see them,
system from working. with the h attribute, if you use the hler to look at your root directory.
An s in this column means that the hie is a system hie. There are
several key DOS hies that are protected with this attribute, because
they must have a specihc location on the disk. The hler does not let
you move, delete, rename, or overwrite a hie with this attribute.
You can alter any of these attributes by selecting the appropriate
check box. Then, if you select the Change text button, FoxPro will
ask you to conhrm that you want to make this change to each of the
tagged hies. If you select Change All, FoxPro will change all tagged
hies without this conhrmation process.

RENAME
Selecting the Rename text button, or Rename from the Filer
menu, calls up the Rename dialog box, shown in Figure B. 11.
536 MASTERING FOXPRO

APP. B

System Database Record Program Window Filer


Filer

Name Ext Size Last Modified Attr

[..]
00280325
00280B16
002D2Fp-
01332D
06-NOV-90
27-Feb-91
27-Feb-91
1:27a
12:40a
12:40a
. a.
. a. 1 Drv.

«]
►ANSWER Rename: ANSWER5.DBF
ANSWER
CALNAM To:
DATAEN
DATAEN * Rename » < Cancel >
dates l—
EMPLIST .DBF 1738 07-Feb-91 10:33a .a.
1 Invert

< Find > < Copy > Move < Delete > Sort
< Edit > < Attr > < Rename > < Size > Tree

Figure B.ll: The Rename dialog box.

To rename a file, simply fill in the new name in the text box of this
dialog box and select Rename. The current file name appears in
the dialog box by default, in case you want to give the new file a simi¬
lar name. The dialog box lets you rename all of the tagged files
in turn.
If another file already has the new name you want to give to a file,
an alert will appear, saying you have made an error: You cannot use
Rename to give a file a name that is already used. The alert asks you
to choose Yes if you want to continue renaming other tagged files or
No if you want to cancel the process and return to the Files panel.

SIZE
Selecting the Size text button, or Size from the Filer menu, calls up
the Size dialog box, shown in Figure B.12.
This dialog box simply displays information about tagged files,
including the number of hies currently tagged, their total size in
bytes, and the amount of space they occupy on the disk in clusters
and bytes.
The number of bytes the hies occupy on the disk is greater than the
number of bytes in the hies themselves, because disk space is broken
THE FOXPRO FILER AND DESKTOP UTILITIES 537

System file Edit Database Record Program Window Filer


Filer

Name Ext Size Last Modified Attr

[..]
00280325
00280B16 Tagged File Statistics
002D2F0F
01332D1E Files: 1
►ANSWER5 .DBF Bytes: 778
ANSWER5 • FPT les Like
CALNAMES . IDX Actual space occupied: *.*
DATAENTR . FMT
DATAENTR . PRX Clusters: 1 < Tag All >
DATES .IDX Bytes: 4,096 < Tag None >
EMPLIST .DBF < Invert >
QK
< Find > < Copy < Sort >
< Edit > < Attr < Tree >

Figure B. 12: The Size dialog box.

up into clusters, and files must be allocated some whole number of


clusters. You can see in the illustration that although the file occupies
778 bytes, it has been allocated one cluster—of 4,096 bytes. There¬
fore, this 778-byte hie takes up 4,096 bytes of space on the disk.

THE TREE PANEL


Selecting Tree, the final text button on the lower right of the Files
panel, or selecting Tree Panel from the Filer menu, lets you use the
filer’s Tree panel, shown in Figure B.13.
First, FoxPro will take a moment to scan your entire directory
structure, because it uses this panel to work with entire subdirectories
and all the hies they contain (rather than just with hies in the current
subdirectory, as the Files panel does).
As you can see from the illustration, this panel displays a graphic
representation of the hierarchical directory structure. The letter C: at
the top represents the root directory. All of the subdirectories con¬
nected directly with it by lines are directly under the root. You can
see that TEMPLCOD is a subdirectory of the FOXPRO subdirec¬
tory, and the MAILPOW directory has three subdirectories,
538 MASTERING FOXPRO

APP. B

System File Edit Database Record Proaram Window Filer* 1


Filer

Directory tree of Volume:

Drv .
-BIN
-CSBOOK
-FOXPRO
1-TEMPLCOD
-FPBOOK
-LEARNFOX Files: 587
-MAILPOW Used: 9,379,840
—MAILP0W1 Free: 1,212,416
-MAILPOW2
-MAILPQW3
-MISC

<Rename> <Chdir > < Mkdlr >


< Copy > < Move > < Delete > < Size > < Files >

Figure B.13: The Tree panel.

MAILPOW 1, MAILPOW2, MAILPOW3, which include


different versions of the program created during testing. The current
directory, LEARNFOX, has a bullet to its left.
All these directories are in a scrollable list, and you can move the
highlight among them as you do in any scrollable list. This panel also
has a popup control that lets you select the drive, and some basic data
on the number of hies on the disk, the amount of space they use, and
the amount of space free.

TAGGING DIRECTORIES
You must tag the directories that you manipulate with the Tree
panel just as you tag the hies that you manipulate with the Files
panel. As with the Files panel, a triangle appears to the left of a direc¬
tory that is tagged in the Tree panel.

RENAME
Selecting the Rename text button or selecting Rename from the
Filer menu calls up the Rename dialog box, shown in Figure B.14.
THE FOXPRO FILER AND DESKTOP UTILITIES 539

System file tdi't. Database Record Program Window Filer


F i 1 er

Figure B.14: The Rename dialog box.

This dialog box renames the tagged directories, and works just like
the dialog box that is used for renaming files. Fill in the new name in
its text box: the current name appears as the default, in case you want
to use a similar name. If multiple subdirectories are tagged, the filer
lets you rename them all in sequence.

CHDIR
Selecting the Chdir text button or selecting Chdir from the Filer
menu lets you change the current directory. Simply tag the directory
that you want as the current directory, and make this selection. The
bullet that shows which directory is the current directory will move to
indicate the change.

MKDIR
Selecting the Mkdir text button or selecting Mkdir from the Filer
menu calls up the Mkdir dialog box, shown in Figure B. 15.
To create a new subdirectory under the current directory, simply
enter the name you want to give it and select Mkdir.
540 MASTERING FOXPRO

APP. B

System file Ldit. Database Record Program Window Filer


filer

Directory tree of Volume:

I
C: Drv.
-BIN
-CSBOOK
-F0

-FP Make subdirectory in: C:\LEARNFOX


-LE 587
New Subdirectory name: ,840
, 416

—MI
E « Mkdir » <Cancel >

<Rename> <Chdir >


< Copy > < Move > < Delete > < Size > < Files

Figure B. 15: The Mkdir dialog box.

COPY
Selecting the Copy text button, or Copy from the Filer menu, calls
up the Copy dialog box, shown in Figure B. 16.
This dialog box is like the one that you use to copy files, and it is
used the same way, except that it copies all the hies of the directories
that are tagged when you use it from the Tree panel.
The Preserve Directories check box becomes useful in this panel. If
you do not check it, all the hies in tagged directories will be copied
into a single target directory. If you do check it, the hler will create a
subdirectory structure under the target directory that corresponds to
the structure of tagged subdirectories under the highest tagged direc¬
tory . The hies in the highest tagged directory will be copied into the
target directory, but hies in the directories under it will be copied into
separate, newly created subdirectories with the same names as their
original directories.

MOVE
Selecting the Move text button, or Move from the Filer menu,
calls up the Move dialog box, shown in Figure B.17.
THE FOXPRO FILER AND DESKTOP UTILITIES 541

System File Edit Database Record Program Window


Filer

Directory tree of Volume:

C: 1 Drv.

(Target directory. Q C:\LEARNFOX\

[ 3 1jeplace
< existing files
L J lireserve directories 87
40
16

Copy < gancel >

<Rename> <Chdir > < Mkdir >


< Copy > < Move > < Delete > Size Files

Figure B. 16: The Copy dialog box.

Figure B.17: The Move dialog box.

As in the Files panel, the Move option of the Tree panel is identical
to the Copy option, except that the original files are deleted and only
the copies in the new locations are left.
542 MASTERING FOXPRO

APP. B

DELETE
Selecting the Delete text button, or Delete from the Filer menu,
calls up the Delete dialog box, shown in Figure B.18.
Use this feature This dialog box looks like the one that the Files panel uses to delete
with extreme cau¬ files, but there is one vital difference. The one in the Files panel lets
tion, as you cannot see
you confirm the deletion of each file that is tagged; this one only
the names of the files
in the directories that lets you confirm the deletion of each directory that is tagged. Select
you are deleting. Delete to confirm the deletion of the directory, or Skip to skip it and
make the filer continue with the next directory.

System Fi le Edit Database Record Program Window Filer


l Filer

Directory tree of Volume:


,
1
%
Drv .
\-—BIN

—FO
1_ Delete directory: C:\LEARNFOX
—FP
—LE
—MA
El Delete files only
X] Remove all sub-directories
587
,840
,416
t «|]elete » < j§kip > <Delete 011 > <gancel >
t

<Rename> <Chdir > < Mkdir >


< Copy > < Move > < Delete > < Size > < Files

Figure B. 18: The Delete dialog box.

You can also delete all tagged directories without confirmation by


selecting Delete All.
If the Delete Files Only check box is checked, the files in the spe¬
cified directories will be deleted, but the directories themselves will
remain (though, of course, they will be empty). The default state of
the Delete Files Only check box is not checked; unless you check it, the
hies will be deleted and the directories themselves removed.
If the Remove All Subdirectories check box is checked, not only
the tagged directory but all the subdirectories under it will be deleted.
THE FOXPRO FILER AND DESKTOP UTILITIES 543

You do not need to tag the subdirectories individually: just tag the
single directory at the top of the group that you want to delete and use
this check box.
The fact that this check box is checked by default makes it very
dangerous. If you mistakenly tag your root directory and then select
Delete All without changing the default setting of the check boxes,
the filer can delete every file and every directory of your hard disk.

SIZE
Selecting the Size text button or selecting Size from the Filer menu
calls up the Size dialog box, shown in Figure B. 19.

System tile Ldit Database Record Program Window Filer


F1 ler . •

Directory tree of Volume:

C:
C
-BIN
-CSBOOK Tagged Directory Statistics
-FOXPRO
1-TEMPLCOD Files: 102
-FPBOOK Bytes: 164,541
-LEARNFOX les : 587
-MAILPOW Actual space occupied: ed: 9,379,840
-MAILP0W1 ee: 1,212,416
-MAILP0W2 Clusters: 118
-MAILP0W3 Bytes: 485,328
-MISC
« 0k »
<Rename> <Chdir
< Move > < Delete >

Figure B.19: The Size dialog box.

As you can see, this dialog box is gives you basic statistics about the
number of hies in the tagged directories, their size, and the number
of clusters and actual disk space they occupy, just like the dialog box
that appears when you select Size from the Files panel.

FILES
Selecting the Files text button on the lower right, or selecting Files
Panel from the Filer menu, brings you back to the Files panel.
544 MASTERING FOXPRO

APP. B

THE DESKTOP UTILITIES _

The filer is the most elaborate utility included with FoxPro, but the
System menu also includes a number of desktop utilities similar to
the ones included in other popular programs. These utilities are
meant to replace items that ordinarily clutter up your desk, such as a
calculator and an appointment calendar.

THE CALCULATOR
Selecting Calculator from the System menu calls up the calculator,
shown in Figure B.20.

System File Edit Database Record Program Window


1 Calculator

MC 7 8 9 / -f

MR 4 5 6 * %

M+ 1 2 3 - C

M- 0 ± + =

Figure B.20: The calculator.

The calculator is used like many pocket calculators, so it is easy to


learn. If you are using the mouse, you simply click the numbers or
operators you want to use, just as you would press the buttons of a
calculator. If you are using the keyboard, you just press the key of
any number or operator that is represented on your keyboard; for
functions that are not represented by a single key on the keyboard,
use the keys shown in Table B. 1.
THE FOXPRO FILER AND DESKTOP UTILITIES 545

Table B. 1: Special Keys for Using the FoxPro Calculator with the Keyboard

Key Function Calculator Equivalent

Q square root

N plus or minus ±

A add to memory M+
value

S subtract from M-
memory value

R recall memory MR

Z clear memory MC

The discussion below talks about typing and using numbers, oper¬
ators, and calculator functions. In every case, this means either
selecting them with the mouse or typing them using the keyboard
and the special keys listed in the table.
The functions of the calculator keys will probably be familiar to you.
The number keys and the decimal point are, of course, used to
enter numbers. Simply type in the number and it will appear on the
display panel on the top of the calculator.
The arithmetic operator keys + , - , *, and / are used to indicate
addition, subtraction, multiplication, and division. To perform these
operations, type the first number, then type the operator (when you
type the operator, the first number that you typed will be highlighted
in the display panel to indicate that it is fully entered, and the opera¬
tor that you typed will appear to its right), then type the second num¬
ber. Once the second number is on the display panel, type = to
complete the calculation.
To find a square root, first type the number. When it is displayed
correctly, use the square root operator. The result will be displayed in
the display panel immediately.
The percent operator lets you perform operations that use some
percentage of the number in the display panel. For example, to find
a number 10 percent larger than a given number, first type the given
number, and when it is in the display panel, type + , then type 10,
then use % . A number 10 percent larger than the original number is
displayed.
546 MASTERING FOXPRO

APP. B

The ± (plus/minus) operator changes the sign of the number that is


displayed: it is equivalent to multiplying the number by - 1. Just use
this operator, and the sign of the value that is displayed will change
instantly.
C clears the value from the display area. If you have pressed an
operator key and there is an operator displayed to the right of the
value, then you must use C twice to remove the operator as well as
the number.
MC, MR, M + and M - let you temporarily store values in the cal¬
culator’s memory and work with those values. When a value is stored
in memory, an M appears to the left of the display panel.
To store the value that is currently displayed in the display panel,
simply use M + . An M will appear to the left of the display panel to
indicate that there is a number stored in memory. To recall the num¬
ber from memory, use MR. The value in memory will appear in the
display panel, overwriting any value that is currently displayed. To
clear the value that is in memory, use MC. The value will be cleared
and the M to the left of the display panel will disappear.
The M + and M - keys are used to add or subtract from the num¬
ber that is in memory. For example, if you want to make the value in
memory 10 less than it is, enter 10, then use M- . Then when you
press MR, you will recall a number that is 10 less than the number
that was previously in memory.
If you select Preferences from the Edit menu popup while you are
using the calculator, you can use the Calculator Preferences dialog
box to alter the default settings of the calculator. This dialog box con¬
tains just two sets of radio buttons.
The first set lets you determine the way in which the calculator
affects the NumLock key of your computer. As you know, you can
use the numeric keypad on the right of your computer keyboard
either to enter numbers or to move the cursor (using the arrow keys,
PgUp, PgDn, Home, and End). You toggle between these two func¬
tions of the numeric keypad by pressing the NumLock key. In its
default mode, the calculator does not affect the current setting of the
NumLock key; if you find it more convenient, though, you can
choose one of the preferences to automatically make the numbers on
THE FOXPRO FILER AND DESKTOP UTILITIES 547

the keypad available to you whenever you use the calculator. You
can make your choice from three radio buttons:

• Don’t Alter NumLock: When the calculator is used, the status


of NumLock remains what it was. This is the default setting.

• Remember NumLock State: The calculator remembers what


the NumLock status was the last time it was used and reverts
to that status automatically when you use it.

• Force NumLock On: NumLock is turned on automatically


when you use the calculator, so that you can use the numeric
keypad to enter numbers.

The other set of radio buttons lets you adjust how decimals are dis¬
played. It also includes three choices:

• Automatic: The number of decimal places the calculator dis¬


plays in the results of calculations depends on the number of
decimal places in the numbers that are entered and on the
operations that are performed. This is the default setting.

• Floating: displays numbers with as many decimal places as


are needed to show the entire number as precisely as possible.
Unnecessary trailing zeros are eliminated.

• Fixed: displays numbers with a fixed number of decimal


places. When you make this selection, a text box appears that
lets you enter the number of decimal places you want dis¬
played. All numbers are displayed with this number of deci¬
mal places, with trailing zeros added if necessary.

THE CALENDAR/DIARY
Selecting Calendar/Diary from the System menu calls up the
Calendar/Diary window, which is shown in Figure B.21 along with
the related Diary menu popup.
548 MASTERING FOXPRO

APP. B

System File Edit Database Record Program Window Diary

March 1991 1 Back Month PgUp |


Isu Mo Tu We Th Fr Sa Ahead Month
Back Year IShif t + PglipB
1 2 Ahead Year Ishift + PgDnB
Today |hhi|
3 m 5 6
7 8 9
Diary _IF]!
10 11 12 13 14 15 16 Calendar

17 18 19 20 21 22 23 delete...

24 25 26 27 28 29 30

31

<<-M><M+><<-Y><Y*> <Todav>

Figure B.21: The calendar/diary.

Whenever you select the calendar/diary, the calendar is on the


current date, and any entry for that date in the diary is shown in
the Diary panel (the right half of the window). Selecting dates on the
calendar lets you see existing diary entries and make entries in
the diary for those dates. The diary entry is thus associated with the
calendar date and is displayed when that date is selected. If there is
an entry for a given day, that date appears on the calendar in en¬
hanced display.
When you begin, the calendar is selected. The name of the month
is underlined in the Calendar panel when the calendar is active, and
the cursor appears in the Diary panel when the diary is active. You
can move between the two in several ways:

• press Tab to move to the Diary panel and Shift-Tab to move


to the Calendar panel

• select Diary or Calendar from the Diary menu popup to


move to the corresponding panel

• using the mouse, simply click on the panel that you want to
move to
THE FOXPRO FILER AND DESK TOP UTILITIES 549

When the Diary panel is active, use the usual editing techniques to
make diary entries. They may be of any length, and you can scroll
through them in the usual ways or resize or zoom the Calendar/"
Diary window to see more of an entry.
When the Calendar panel is active, move among the days of the
current month by using the arrow keys or (if you have a mouse) sim¬
ply by clicking the day that you want. To move to a different month,
either use the text buttons at the bottom of the Calendar panel, the
corresponding options on the Diary menu, or the hot keys, as follows:

• The text button, the Back Month option on the Diary


menu, or the PgUp key moves you back a month.

• The M“* text button, the Ahead Month option on the Diary
menu, or the PgDn key moves you forward a month.

• The *~Y text button, the Back Year option on the Diary
menu, or the Shift-PgUp key combination moves you back
a year.

• The Y-* text button, the Ahead Year option on the Diary
menu, or the Shift-PgDn key combination moves you for¬
ward a year.

In addition, the Today text button, the Today option on the Diary
menu, or the T key moves you back to the current date, no matter
where you are in the calendar when you select it.
The Delete option of the Diary menu lets you delete all entries in
the Diary prior to the date selected on the Calendar. It presents you
with a warning before deleting this data, and the No text button is the
default choice. These should help you to avoid deleting data by mis¬
take. Select the Yes text button to confirm that you want to delete all
entries prior to the date selected on the calendar.
Use the usual editing techniques to delete the entry for a single day.

SPECIAL CHARACTERS
Selecting Special Characters from the System menu calls up the
Special Characters window, shown in Figure B.22.
550 MASTERING FOXPRO

APP. B

System 1 i ie l.diy Database Recc3rd Proqram Window


1 Special Characters
If TP = P T T r T 1 E
r
un HI
I h + H 1 1 + 4 II h + ^ HHi |

1 1 - Ik A j - k =L J 1 JL J

1 <• t 4- i A T ► i

linn ■ J 1 m r n *-
o i * ♦ * * • ■0 5 9 4 * *

C £ * A f % * ii SI § « » l : - ;
a p r TTE CT P T i 0 Q S ~ 0
£ n = ± * < -r ° vT n 2

aA aX X
a a. 1 l
a a CL e e e e 6 i 1 1 aj
0 6 6 6 6 U u U Li u y
2 o £
<E Q Q R R

Figure B. 22: The Special Characters window.

D Not all printers


handle all these
This utility gives you an easy way of using the special characters
that are available in the extended ASCII character set. You can add
special characters. Before
using them in a docu¬
any of these characters to any text that you are creating using the
ment you want to print, FoxPro editor—for example, if you are using a foreign name and
make sure that they will want to include a letter with an accent mark.
work with your printer by
Notice that the top third of this panel includes box-drawing char¬
checking its documenta¬
tion or by creating and acters, the middle includes special graphic characters, and the bot¬
printing a short test tom third includes special symbols and foreign letters.
document with the special
To use one of these characters, simply place the cursor on it and
characters you want to use.
select it. It is pasted in the place where the cursor was in the last win¬
dow that was active.
For example, if you are typing a document and come to a point
where you need a foreign character, simply leave the cursor at that
point, select Special Characters from the System menu, and select
the character you want. When you close the Special Characters win¬
dow and return to the document, the character will be there.
For this process to work, the window where you are placing the
character must be open and must be a type of window where you can
normally use the Paste option of the Edit menu. If you have trouble
THE FOXPRO FILER AND DESKTOP UTILITIES 551

making the special character appear, try holding down the Shift key
while you select it from the Special Characters window.

THE ASCII CHART


Selecting ASCII Chart from the System menu calls up the ASCII
chart shown in Figure B.23.

System 1 l !e 1 (lit Database Record Program Window


1 ASCi l' Char t

0 00 NUL
1 01 'A SOH
12 'B STX
17 'C ETX
U "D EOT
15 “E ENQ
06 T ACK
07 'G BEL

Figure B.23: The ASCII chart.

The first column shows the ASCII number of the character in deci¬
mal notation. The second column shows the same ASCII number in
hexadecimal (base 16) notation: if you do not know hexadecimal
notation, you can simply ignore this column, as it is not needed for
FoxPro programming. The third column shows the graphic repre¬
sentation of the character. (Most characters are shown as they are
printed, but the lower-number ASCII characters are control charac¬
ters, which are not printed, so they are represented by graphics—
such as a face.) The fourth column shows the Control-key combination
(if there is one) for the character. The fifth column represents the mean¬
ing of control characters (lower-number ASCII characters) in an
552 MASTERING FOXPRO

APP. B

abbreviated form: for example, you learned that ASCII character 7


makes the computer beep, and you can see that its name is BEL.
If you select an ASCII character from this chart, its graphic repre¬
sentation from column three is pasted in the location where the cursor
was before you opened the ASCII chart window—just as characters
from the Special Characters window are.

THE CAPTURE UTILITY


Selecting Capture from the System menu lets you use the Capture
utility to copy text from all or a part of the screen into the clipboard,
so that you can paste it into an editing window. Graphic characters,
such as the borders of windows, cannot be captured.
After you select Capture from the menu, a message appears telling
you to select the top left corner. You then begin to select the text
that you want to capture. Thus, using the mouse, move the pointer
to the upper left corner of the area you want to select, and press the
mouse button. A message appears saying that you should select
the bottom right corner. Drag to the lower right corner of the area
you want to select and release the mouse button to capture the text in
the selected area.
If you are using the keyboard, use the arrow keys to move the cursor
to the upper left comer of the area you want to select, and press Enter. A
message appears saying that you should select the bottom right comer.
Move the cursor to the lower right comer of the area you want to select
and press Enter to capture the text in the selected area.
A message saying “Captured and placed on the clipboard”
appears when you have finished capturing the text. Once it is on the
clipboard, you can select Paste from the Edit menu to paste it in a
document.
554 MASTERING FOXPRO

APP. C

DURING THE COURSE OF THIS BOOK, I DECIDED IT


was best to leave out many details of some of the commands and
functions that were discussed. For example, when you were first
being introduced to BROWSE, you needed to learn the differences
between BROWSE and CHANGE and to learn the basic ways of
using the Browse/Change window. A long discussion of extra options
and advanced features of the command would have been a distrac¬
tion. Likewise, some commands that are fairly common in program¬
ming were left out of the main text for the sake of readability. For
example, in addition to the DO WHILE loop, FoxPro includes a FOR
loop and a SCAN WHILE loop, but covering them would have dis¬
tracted from the general discussion of structured control flow.
Now that you have learned all the basics of using and program¬
ming FoxPro, though, one of the best ways to become a more ad¬
vanced user or programmer is by browsing through references that
discuss commands and functions.
This appendix is meant as a bridge to take you from what you have
learned in the main text of this book to the point where you will profit
from browsing through more advanced reference books. You can use
it to look up commands and functions and you can browse through it
to expand your knowledge of the FoxPro commands that you need
most, without being swamped by entries for commands and func¬
tions that you do not need at this point.
Most reference works, including the Commands and Functions man¬
ual that comes with FoxPro, contain more than an intermediate user
wants to wade through: they have many commands and functions
(such as low-level file I/O commands) that only the most advanced
programmers would want to use, and even some essential commands
are explained with more technical details than you need at this stage.
FoxPro and other dBASE compatible languages have so many
commands and functions available that nobody uses them all. Even
people who have been programming for years can read through ref¬
erence books and find new capabilities of the dBASE standard that
they had not noticed before and that could make their jobs easier.
This appendix contains most the commands and functions used in
this book plus a selection of the other commands and functions that
intermediate programmers will most find most useful, including
ESSENTIAL COMMANDS AND FUNCTIONS 555

• virtually all the capabilities of commands and functions (such


as BROWSE) that you have already learned but which were
discussed in the main text in an abbreviated way, for the sake
of readability—though in some cases, it leaves out very tech¬
nical issues that an intermediate reader should not be both¬
ered with.

• the most useful of the commands and functions that were not
discussed in the text, such as the commands DECLARE and
DIMENSION, which are used for creating arrays, and the
function IIF(), which is used to build an IF statement into an
expression.

• the FoxPro/dBASE file-management commands, such as


DELETE FILE, which are similar to DOS commands.
These commands were introduced in early versions of
dBASE, and now it is easier in most cases to use RUN plus a
DOS command or to use the FoxPro filer utility to manage
files. Given how much ground we had to cover in the text,
these commands were omitted: we used RUN plus a DOS
command instead to save the time of learning these extra
FoxPro commands. However, these commands are found
rather frequently in dBASE compatible programs, and it is
good to be familiar with them.

The appendix uses conventions that are standard in references


describing FoxPro commands and functions:

• Capital letters are used for key words. If a word is capitalized,


you type it just as it appears in this book.

• Optional clauses are put in square brackets. Any part of the


command that is surrounded by square brackets may be
included or not when you are actually using the command.

• Alternatives are separated by a vertical line (|). If two clauses


are separated by a vertical line, you may use one or the other
but not both when you are actually using the command.

• Words whose value you must fill in are written in lowercase


letters in angle brackets. For example, if a command includes
<file name>, it indicates that you must fill in a real file name in
556 MASTERING FOXPRO

APP. C

that place when you are actually using the command. As


usual, do not type the brackets themselves.

COMMANDS _
* | && | NOTE
These commands are used to indicate a comment in a program:
text following them is ignored by FoxPro and is used to make the pro¬
gram easier for a programmer to understand.
* or NOTE must be at the far left of a line of text, and comments
must be to their right. Nothing else may be on the line except these
commands and comments.
&& may be anywhere on a line of the text: anything to its right is a
comment. Actual program code may be to its left.

.P |i ..pp

[ < expl > ]

[PICTURE <char expl > ]

[FUNCTION <char exp2 > | V< num exp > ]

[AT < num exp >

[, <.exp2> ...]

This command evaluates and displays an expression.


In the basic form of the command, ? <expl > displays the value of
the expression on a new line, one line below the current location
of the cursor. ?? <exp> displays the expression at the current loca¬
tion of the cursor, without moving to a new line.
? used without an expression simply moves the cursor to the
following line.
If CONSOLE is SET ON and PRINT is SET OFF (the default
environment settings), then the evaluated expression is displayed on
the screen. If PRINT has been SET ON, it is sent to the printer. If
CONSOLE has been SET OFF, it is not displayed on the screen.
(For more information, see SET CONSOLE and SET PRINT.)
ESSENTIAL COMMANDS AND FUNCTIONS 55 7

The basic command can also be used with an optional PICTURE,


FUNCTION or AT clause. Chapter 10 includes more information
on these clauses and tables, listing all the picture and function tem¬
plates that are available.

• PICTURE: The command can specify the format in which


the expression is displayed by including the optional PIC¬
TURE clause and a picture template or function. For
example, the clause PICTURE @\ will display the expression
in all capitals.

• FUNCTION: The optional FUNCTION clause is like a


PICTURE clause but can be used only with picture func¬
tions which apply to the entire expression. The FUNCTION
clause lets you use a picture function without including the @
first. For example, the clause FUNCTION ! will display the
expression in all capitals, just like the clause PICTURE @!.

• V <num exp>: As you can see if you look at the full com¬
mand, a FUNCTION clause can contain either an ordinary
function template (which is a character expression) or the let¬
ter V followed by a number or numeric expression. V can be
used to limit the number of spaces on a line that the expres¬
sion occupies and to stretch it vertically instead. The numeric
expression is the maximum number of columns on a single
line that the expression can occupy: if it is longer, it will con¬
tinue on successive lines.

• AT: The optional AT clause lets you specify the column


where the expression is displayed. It must be followed by a
number or numeric expression. The row where the expres¬
sion is displayed, of course, is either the row where the cursor
is (if you use ??) or the following row (if you use ?). This is
useful if you are producing a tabular report, where columns
need to be lined up.

Notice also that in the full command, another expression can be


used following the first, separated from it by a comma. The ellipsis
indicates that the second expression can be followed by any of the
optional clauses and by more expressions and optional clauses.
558 MASTERING FOXPRO

APP. C

??? < char exp >


Sends characters directly to the printer. This command can be
used to print a line of ordinary text characters, but it is most powerful
when it is used with printer codes. Because it sends characters
directly to the printer, without going through the printer driver, it
lets you use printer control codes that are not supported by the
printer driver. Printer control codes let you change type sizes and
styles, for example. When you use them with ???, enclose control
codes in {} (curly brackets).
Using printer control codes is a rather exacting technical task.
Codes are listed in your printer’s manual.

@ <row, col>

[SAY <expl > [PICTURE <char exp 1> j FUNCTION

< char exp2 > ] ]

[GET < variable>] [PICTURE <char exp3 >] [FUNCTION


< char exp4 > ] ]

[RANGE [<exp2'>][,<exp3'>]\

[VALID Klog expiy \ <Cnum expl> [ERROR

<Lchar exp5 > ] ]

[WHEN <log exp2>]

[DEFAULT <exp2>]

[MESSAGE Kchar exp6>

[[OPEN] WINDOW Kchar exp7>]

[COLOR [<standard>][,<enhanced>] \ COLOR SCHEME


< num exp4 > ]

In its basic form, @ <row,col> [SAY <exp>] [GET <variable>], this


command is used for formatted input/output. The cursor is placed
on the row and column of the screen or active window defined by the
<row> and <ro/> numbers following the @ sign. (Rows are num¬
bered from 0, at the top of the screen, to 24 at the bottom on
standard-size screens; and columns are numbered from 0 at the left
ESSENTIAL COMMANDS AND FUNCTIONS 559

edge of the screen to 79 at the right.) The expression following SAY is


displayed on the screen in this location, and the variable following
GET is displayed in reverse video immediately after it.
If the command SET DEVICE TO PRINT has been used previ¬
ously, the output is sent to the printer; then the maximum row and
column lengths depend on the size of the paper. SET DEVICE TO
SCREEN returns to the default setting, with output sent to the screen.
The value of the variable must be defined before this command is
used. If this command (or a series of these commands) is followed by
the command READ, the user can change the value of the variable.
In general, the expression following SAY is used to prompt the user
about what to enter in the GET clause. The command can be used
with just a SAY or just a GET clause, to display just a message or just
a variable.
As you can see from the full form of the command, either the
expression following SAY or the variable following GET can be for¬
matted using a picture template or function code. For example, PIC¬
TURE @! after the SAY clause will cause the expression to be dis¬
played in all capitals, and PICTURE @! after the GET clause will
cause the variable that the user enters to be read as capitals.
A FUNCTION clause lets you use the picture functions that can be
used following an @ in a PICTURE clause, but without including the
@ symbol. For example, FUNCTION ! after the SAY clause will
cause the expression to be displayed in all capitals; and FUNCTION !
after the GET clause will cause the variable that the user enters to be
read as capitals.
Chapter 10 includes more information on these clauses and tables,
listing all the picture templates and functions that are available.
The GET clause can also be followed by a number of other qualify¬
ing clauses:

• RANCE [ < exp2 > ] [, < exp3 > ] can be u sed to specify a ran ge
of values within which character, numeric, or date input
must fall. The data type of the expressions used here depends
on the data type of the variable following GET. If the user
enters a value that does not fall between the two values in the
RANGE clause, an alert is displayed which includes
the required range. Either of the two expressions following
RANGE may be omitted and the clause will check only for
560 MASTERING FOXPRO

APP. C

values that are too low or high; if the single expression follow¬
ing it is preceded by a comma, it is read as the upper bound
of the range.

• VALID <log expl> \ <num exp3> [ERROR <char exp5>]


can be used to validate input. Generally it must be used with
expressions based on user-defined functions that were
designed specifically to test this input. If VALID is used with
a logical expression, the input is considered valid if the ex¬
pression is true; the ERROR clause may be used to display a
custom error message if the expression is false. If VALID is
used with a numeric expression, then a zero indicates an
error, a positive number indicates how many GET fields the
cursor should move forward before the next input, and a neg¬
ative number indicates how many GET fields the cursor
should move backward before the next input.

• WHEN < log exp2> can be used to allow or prevent editing of


the field depending on the value of the logical function. If it
evaluates as .F., the cursor skips to the next GET field.

• DEFAULT <exp2> can be used to specify a value that appears


in the GET field by default. It must be the same data type as the
variable that follows GET, and it overrides the value of that vari¬
able as the default choice that appears in the field.

• MESSAGE <char exp6> can be used to display a message on


the last line of the window when the user puts the cursor in
that GET field.

• [OPEN] WINDOW <char exp7> can be used to let the user


edit a memo field in a window. The window must be defined i
first, and the character expression here is the name of the
window. If the optional OPEN is included, the window is
opened automatically, but the user must press Ctrl-Home to
enter it and Ctrl-End to leave it. If OPEN is omitted, the user
must press Ctrl-Home to open it.

[COLOR [<standard>][,<enhanced>] j COLOR SCHEME


<num exp4>] may be used to change the color attributes used by
both the SAY and GET clause. The standard color is used following
SAY and the enhanced color following GET. Both are defined by
1 f>
f'AJ£ >7 £■- Jr). £,p t..- w

ESSENTIAL COMMANDS AND FUNCTIONS 561


/? £>/r SC-ft&i&N (!$*• $*£.!£. A-'
jT^W * «*> h>//£&t js 4
■* / /*% /S C/M
«^s. A-._1 jpAm m wkm
using a pair of color codes separated by a slash. If you use COLOR
£7£
a^iiH 4?’ . ,-x •W &*<■/< SCHEME instead, you can use a predefined color scheme you refer
to by number (or by a numeric expression).

@ <rowl <coll >, <row2>, <col2 > BOX

[ < char exp > ]

This command draws a box with < rowl >, Kcoll > as its upper left
corner and <row2>, <col2> as its lower right corner. Of course,
these all must be numeric expressions.
If rowl equals row2, a horizontal line is drawn. If coll equals col2,
a vertical line is drawn.
The optional character expression at the end lets you specify what
characters are used to draw the box. It consists of up to nine characters.
The first eight represent the upper left comer, top, upper right comer,
right edge, lower right comer, bottom, lower left comer, and left edge
of the box. (Notice that they begin with the upper left and move around
the box clockwise.) If a ninth character is added, it is used to fill the box.
You may specify these characters by ASCII number, using the CHRQ
function; alternately, the Special Characters window, described in
Appendix B, gives you an easy way of including actual extended DOS
line-drawing characters in your programs.
If the final character expression is omitted, the box is drawn with a
single line.

@ < rowl >,< coll > CLEAR

[TO <row2>, <ro/2>]

This command is used to clear part of the screen or active window.


KRowiy, <coll> is the upper left comer of the rectangle to be
cleared.
If the optional TO clause is included, <row2'>, <rc/2> define the
lower right corner of the rectangular area to be cleared. If it is not
included, the rectangle that is cleared extends to the lower right cor¬
ner of the screen or active window.
562 MASTERING FOXPRO

APP. C

A CCEPT [< char exp >] TO < memvar >

This command gets character input without requiring the user to


use quotation marks or any of the other character-string delimiters,
as the INPUT command does.
When this command is executed, the program pauses until the
user presses Enter. Any keystrokes typed in before Enter is pressed
are assigned to the memory variable following the word TO. This
command can create the memory variable: it does not have to be
defined in advance.
If the optional character expression is included, it is displayed as a
prompt for the user.

APPEND

[BLANK]

This command lets you add data to the end of the current database
file. First you must open the file with the command USE <jile
name>. If you use this command when no file is open, the Open File
dialog box appears to let you choose a database file.
APPEND by itself opens a Browse/Change window, displaying a
blank record added at the end of the database file that is open in the
current work area, and moves the pointer to that record. If data is
entered in the record, that record becomes permanent and a new
blank record is added. An indefinite number of records are added as
needed.
APPEND BLANK adds a single blank record to the end of the
database file that is open in the current work area and moves the
pointer to that record. Character fields are initialized with spaces.
Numeric fields are initialized with zero. Date fields are initialized
with three pairs of spaces, for month, day, and year (or some permu¬
tation thereof), each separated with a slash. Logical fields are initial¬
ized with .F.
APPEND BLANK does not open a Browse/Change window.
Because the field values are initialized, they can be used in programs
as the basis of the variables in a series of @ <row >,<col> SAY <exp >
GET <variable> commands, and they can be filled using a series of
REPLACE commands.
ESSENTIAL COMMANDS AND FUNCTIONS 563

(It is possible to open a Browse/Change window and edit these


fields directly by using the command BROWSE, CHANGE, or EDIT
immediately after the command APPEND BLANK; but this proce¬
dure has no advantage over simply using the command APPEND.)

APPEND FROM <data file> j ?

[FIELDS <fieldlist>]

[FOR <log exp >]

[TYPE SDF | DELIMITED [WITH

<character> | BLANK | TAB]]

This command lets you add data from another file to the end of the
database file that is open in the currently selected work area.
In the simplest form of the command, the data is appended from
another database file with a .DBF extension. You can specify the
name of the data file; FoxPro assumes a .DBF extension if none is
entered (unless a TYPE clause is included). Or you can use the ?
option, and FoxPro will display the Open File dialog box and let the
user select the file to Append from.
Several optional clauses offer other capabilities:
FIELDS <jield list> lets you select which fields in the database file
will have data appended to them.
FOR <log exp> lets you select which records in the other file will
be added to the database file that is currently open. Only records for
which the logical expression is evaluated as true are added.
TYPE SDF i DELIMITED [WITH <character> |BLANK|TAB]
lets you append data to the database file that is currently open from
files that are not FoxPro compatible database hies. The types of hies
you can append data from are

• SDF files: ASCII text hies where records have a fixed length
and a carriage return and line feed at the end.

• DELIMITED files: ASCII text hies where helds are sepa¬


rated by some delimiter (usually a comma), character helds
are delimited by quotation marks, and there is a carriage
return and line feed at the end of each record.
If none of the options is used following DELIMITED, FoxPro
assumes commas between fields. The options let you specify that a
blank, a tab, or any character be used as the delimiter between fields.
When a TYPE clause is used, FoxPro assumes that the hie has a
.TXT extension if none is entered.
For more information on how FIELDS and FOR clauses work, see
Chapter 5.

AVERAGE

[ < num exp list > ]

[ < scope > ]

[FOR <logexp>]

[WHILE <logexp>]

[TO < memvar list> | TO ARRAY <C array

This command computes the average (arithmetic mean) of num¬


eric expressions. By default, all the numeric expressions in the data¬
base that is open in the current work area are averaged.
If an expression list is included, only the numeric expressions that
are listed are averaged.
All records are included in the average unless a scope, FOR, or
WHILE clause is included to restrict the records that are considered.
(See Chapter 5 for a discussion of how these clauses are used.)
If the optional TO clause is included, the results are stored in the
specified list of menory variables. Alternately, if a TO ARRAY clause is
included, the results are stored in the array that is specified; the array
must have been created before this command is used. (Arrays were not
covered in the main body of this book, but they are discussed in the
entries on DECLARE and DIMENSION in this appendix.)

BROWSE

[FIELDS <field list > ]

[FORMAT]

[FREEZE Kfield name'>\


ESSENTIAL COMMANDS AND FUNCTIONS 565

[LAST]

[NOAPPEND]

[NOGLEAR]

[NODELETE]

[NOEDIT | NOMODIFY]

[NOFOLLOW]

[NOMENU]

[NORMAL]

[NOWAIT]

[PREFERENCE = <char exp >]

[SAVE]

[WIDTH < num exp > ]

[WINDOW <window name">\

Used by itself, BROWSE opens the Browse/Change window in its


standard Browse configuration, with each record on one line,
its fields arranged from right to left.
You can edit existing records or use the Browse menu to add a new
record. If you click the close box, press Ctrl-W or Ctrl-End, or select
Close from the File menu, you can close the Browse window and save
any changes you made. If you press Ctrl-Q, you can close the Browse
window and discard any changes you made. To edit memo fields,
double-click the field with the mouse or move the cursor to it and press
Ctrl-PgDn to open the Memo window. When you enter the com¬
mand, a Browse popup appears, which lets you partition the window,
toggle the window to Change mode, delete or recall a record, and
otherwise alter the window.
Selecting Browse from the Database menu generates the command
BROWSE LAST, which opens the Browse/Change window in its last
configuration rather than in the default configuration described in the
first paragraph.
Many of the options that can be used with BROWSE are useful pri¬
marily in programming, where you want to limit what the user can do.
566 MASTERING FOXPRO

APP. C

FIELDS <field list> makes the Browse window contain only the
fields mentioned in the field list. The field list may be made up of field
expressions as well as field names, so it may also include calculated
fields.
FORMAT lets you use a format file with an .FMT extension to
control the way the fields are displayed. The format hie must first be
made active with the command SET FORMAT TO <file name >.
FREEZE <field name> allows changes to be made only to the one
held that is mentioned, though all the helds are displayed.
LAST opens the Browse/Change window in the same configura¬
tion in which it was last used.
NOAPPEND makes it impossible to add new records to the hie.
NOCLEAR leaves the Browse/Change window visible on the
screen after you are done using it. (By default, the window disap¬
pears when you are done.)
NODELETE makes it impossible to mark records for deletion.
NOEDIT J NOMODIFY makes it impossible to make any changes
in the data.
NOFOLLOW makes the pointer stay where it is in the database
when you modify the held that the database is indexed on. (By
default, the pointer stays on the record, following that record to the
new position that it moves to because its key held was modihed.)
NOMENU makes the Browse/Change window open without the
Browse menu pad being added to the menu bar, so that the user can¬
not access the Browse menu popup.
NORMAL makes the Browse/Change window open with its nor¬
mal attributes even if it is opened in a user window. If this option is
not used, it takes its attributes, such as its colors and whether it can
grow or not, from the user window it is opened in.
NOWAIT makes a program continue without any pause after the
Browse/Change window is opened. If BROWSE is used in a program
without this option, the Browse/Change window is opened and the
program is suspended until it is closed.
PREFERENCE = <char exp> lets you save and reuse the attrib¬
utes of Browse windows. Unlike the LAST option, which only reuses
t e previous configuration, this option can reuse any configuration
used in the past. The first time BROWSE ,s used with this option with
a given character expression, the PREFERENCE referred to by that
name is created. When the window is closed, that PREFERENCE is
ESSENTIAL COMMANDS AND FUNCTIONS 567

updated. Any time in the future that the window is opened with that
PREFERENCE, it keeps the same configuration.
SAVE keeps the Browse/Change window (and an associated Memo
window, if one is open) on the screen after the user has exited from it.
This option can only be used in programs.
WIDTH <num exp> limits the width of the display of all fields.
Only the display is affected, not the actual data. You may use the
arrow fields to scroll through a field and see all its data. WINDOW
<window name> opens the Browse/Change within another window,
whose name is specified in the command. That window must first be
defined using the DEFINE WINDOW command. This option of the
BROWSE command activates that window and opens the Browse
window in it.
6-0 -Tc> f ‘ jTEiki Ke/ Vj?#3 '
J7l£/P/ J<£'/ '
CALCULA TE [< scope >y < math expr list >

[FOR <log expl>]

[WHILE <logexp2>]

[TO Kmemvar list> | TO ARRAY <array >]

This command lets you perform a number of mathematical oper¬


ations on database fields or field expressions, depending on what
functions the math expression list uses.
The available functions and the type of field or field expression that
may be used with each, are

• AVG(<nwm exp>) computes the average (arithmetic mean)


value for a numeric field or field expression.

• CNT() computes the total number of records (and so it does


not use a field name or expression).
• MAX( <£*/>>) finds the maximum value for a field or field
expression.

• MIN(<Yx/>>) finds the minimum value for a field or field


expression.
• NPV(<rami expl>, <exp> [,<num exp2>]) calculated the
Net Present Value of series of payments over time discounted
at some constant interest rate. The interest rate, expressed as
a decimal, is entered as < num expl >. The series of payments
is represented by <2^cxp'^, which must be the name of a field,
a field expression, or a numeric expression. Optionally, an
initial investment may be represented by <num exp2 >

• STD(<num exp>) calculates the standard deviation for the


values in a numeric field or field expression.

• SUM(<n«m exp>) calculates the sum of the values in a num¬


eric field or field expression.

• VAR(<num exp>) calculates the variance from the average


for a numeric field or field expression. This is equal to the
square root of the standard deviation.

All records are included in any of these calculations unless a scope,


FOR, or WHILE clause is included to restrict the records that are
considered. If an optional scope, FOR, or WHILE clause is used, only
the records included in the specified scope, or only the records for
which the logical expression following the FOR or WHILE is evalu¬
ated as true, are included in the calculation. For more information on
how these clauses work, see Chapter 5.
Records that are marked for deletion are included in the calcula¬
tion unless the command SET DELETED ON has been used.
If the optional TO clause is included, the results are stored in the spe¬
cified list of memory variables. Alternately, if a TO ARRAY clause is
included, the results are stored in the array that is specified; the array
must have been created before this command is used. (Arrays were not
covered in the main body of this book, but they are discussed in the
entry on DECLARE and DIMENSION in this appendix.)

CHANGE

[NOAPPEND]

[NOCLEAR]

[NODELETE]

[NOEDIT]

[NOFOLLOW]
ESSENTIAL COMMANDS AND FUNCTIONS 569

[NOMENU]

[FIELDS <field list >]

[ < scope > ]

[FOR </o£ expl >]

[WHILE < log exp2 > ]

CHANGE opens the Browse/Change window in its standard


Change configuration, with each field on one line. The commands
CHANGE and EDIT are identical: EDIT was more common in ear¬
lier dBASE compatible programs, and CHANGE is more common
in FoxPro.
You can edit existing records or use the Browse menu to add a new
record. If you click the close box, press Ctrl-W or Ctrl-End, or select
Close from the File menu, you can close the Browse/Change window
and save any changes you made. If you press Ctrl-Q, you can close
the Browse/Change window and discard any changes you made. To
edit memo fields, double-click the field with the mouse or move the
cursor to it and press Ctrl-PgDn to open the Memo window. When
you enter the command, a Browse popup appears, which lets you
partition the window, toggle the window to Browse mode, delete or
recall a record, and otherwise alter the window.
Many of the options that can be used with CHANGE are useful pri¬
marily in programming, where you want to limit what the user
can do.
NO APPEND makes it impossible to add new records to the file.
NOCLEAR leaves the Browse/Change window visible on the screen
after you are done using it. (By default, the window disappears when
you are done.)
NODELETE makes it impossible to mark records for deletion.
NOEDIT makes it impossible to make any changes in the data.
NOFOLLOW makes the pointer stay where it is in the database
when you modify the field that the database is indexed on. (By
default, the pointer stays on the record, following that record to the
new position that it moves to because its key field was modified.)
NOMENU makes the Browse/Change window open without the
Browse menu pad being added to the menu bar, so that the user can¬
not access the Browse menu popup.
570 MASTERING FOXPRO
APP. C

You may restrict the number of fields available to be edited by


using a FIELDS, scope, FOR, or WHILE clause.
FIELDS <jield list> makes the Browse/Change window display
only the fields mentioned in the field list. A scope clause makes the
Browse/Change window display only the records that fall in the spe¬
cified scope. A FOR or WHILE clause makes the Browse/Change
window display only the records that meet some logical criterion. See
Chapter 5 for more discussion of how these clauses work.

CLEAR
This command clears the screen or the current output window,
leaving it blank.

CLEAR ALL
This command has four main effects:

• It releases all memory variables and arrays.

• It closes any open database files, index files, format files, and
memo hies.

• It selects Work Area A as the current work area.

• It releases active menus or popups.

It does not have any effect on system variables or active windows.

cjt,Mt< rizLUS

releases Sd^f C With°Ut 3 field list’ this command


, r. W y, dlSpla>'that was created using the SET FIELDS TO
field list> command. The command SET FIELDS OFF then is
automatically executed.
This command differs from SET FTFT riQ l • ,
the held list, in .11 i FIELDS TO because it releases
me neicl lists m all work areas, while SET FTFT riQ xr* 1
in the current work area. °S ° WOrks Just
ESSENTIAL COMMANDS AND FUNCTIONS 5 71

CLOSE

ALL |

ALTERNATE|

DATABASES |

FORMAT |

INDEX |

MEMO < memo field list > |

MEMO ALL |

PROCEDURE

This command closes various types of files. The command must be


used with one of the alternatives listed after it.
ALL closes all file types and selects work area A.
ALTERNATE closes an Alternate file used to capture output in a
text file. For more information on this type of file, see SET ALTER¬
NATE TO.
DATABASES closes all database, index, and format files and
selects work area A.
FORMAT closes a format file that is open in the current work area.
INDEX closes all index files in the current work area.
MEMO < memo field list> closes the memo fields that are listed.
The names in the memo field list must be separated by commas if it
contains more than one name.
MEMO ALL closes all memo fields in all work areas.
PROCEDURE closes procedure files.

COMPILE <file name>


This command compiles the source code in a program file and
creates an object file. If the source code has a .PRG extension, the
object file will be given an .FPX extension. If the source code has an
.FMT file, the object file will be given a .PRX extension.
Text files may be compiled even if they do not have a .PRG or
.FMT extension: the compiler assumes a .PRG extension. The file
must be a plain ASCII text file.
572 MASTERING FOXPRO

APP. C

CONTINUE
This command finds the next record that matches the criterion of a
LOCATE FOR <logexp> command that has been used previously—
that is, the next record in the database file for which the logical
expression in the LOCATE FOR command is evaluated as true. If a
record is not found, EOF() is given the value of .T.
CONTINUE may be used repeatedly, until you reach the end of
the database hie (or the end of the LOCATE scope, if a scope clause
was used with the original LOCATE command).

COPY FILE <file namel> TO <file name2>


This command makes an exact copy of the first hie named. If the
second hie does not exist, it creates it. If the hrst hie exists, it gives a
warning before overwriting it, if SAFETY is ON, or overwrites it
without giving a warning if SAFETY is OFF.
You must use both the name and extension of both hies.
This FoxPro command is similar to the DOS command COPY,
but it has the advantage of giving a warning before overwriting a hie.

COPY STRUCTURE TO <file name>

[FIELDS <field list> ]

This command creates a new database with the same structure as


t e database hie that is open in the current work area.
If a FIELDS clause is included, the new file has only the fields that

COPY TO < file name>

[ < scope > ]

[FIELDS <field list > ]

[FOR <log expl >]

[WHILE <,logexp2>\

[TYPE: SDF ! DELIMITED [WITH < charter> | BLANK

c opy 7b ££L/Mt TtV . !tTty m


Tax X -X'
ESSENTIAL COMMANDS AND FUNCTIONS 5 73

This command copies the records in the database hie that is open
in the current work area, to the hie whose name is specihed.
In the simplest form of the command, the data is copied to another
database hie with a .DBF extension. You can specify the name of
the data hie; FoxPro assumes a .DBF extension if none is entered
(unless a TYPE clause is included).
Several optional clauses offer other capabilities:
<scope> lets you select which records will be copied: only records
in the specihed scope will be copied. If this clause is omitted, the
default scope is ALL.
FIELDS <field list> lets you select which helds in the database hie
will be copied.
FOR <logexp> or WHILE <logexp> let you select which records
will be copied. Only records for which the logical expression is evalu¬
ated as true are copied.
TYPE SDF | DELIMITED [WITH <character> |BLANK|TAB]
lets you copy data from the database hie that is currently open to hies
that are not FoxPro compatible database hies. The types of hies to
which you can copy data are

• SDF files: ASCII text hies where records have a fixed length
and a carriage return and line feed at the end.

• DELIMITED files: ASCII text hies where helds are sepa¬


rated by some delimiter (usually a comma), character helds
are delimited by quotation marks, and there is a carriage
return and line feed at the end of each record.

If none of the options is used following DELIMITED, FoxPro


assumes commas between helds. The options let you specify that a
blank, a tab, or any character be used as the delimiter between helds.
For more information on how scope, FIELDS, FOR, and WHILE
clauses work, see Chapter 5.

COUNT

[ < scope > ]


[FOR Klog expiy]
574 MASTERING FOXPRO

APP. C

[WHILE < log exp2 > ]

[TO Kmemvar >]

This command counts the total number of records in the database


hie that is open in the current work area.
If an optional scope, FOR, or WHILE clause is used, only the
records included in the specified scope, or only the records for which
the logical expression following the FOR or WHILE is evaluated as
true, are included in the count. For more information on how these
clauses work, see Chapter 5.
Records that are marked for deletion are included in the count
unless the command SET DELETED ON has been used.
If the optional TO clause is included, the result is stored in the speci¬
fied memory variable.
0]C ,v // o v ; y . /r)(J P/\J0'rE \

COl/ajT fit/? P/DPTY (tiorf $ )


CREA TE f/VD PfilAy /W/faty Qf- // 7; u? /
//#*/£ M07W/4/& /a/

[ <file name> \ ?]

This command lets you define the structure of a new database hie.
If you do not specify a hie name, the new hie will be named
UN III LED.DBF until you save it by selecting
File menu popup.
If you specify a file name, FoxPro assumes a .DBF extension.
If you use the ? option, FoxPro displays a dialog box that lets the
user enter the name of the new hie to be created
For more information on defining the structure of a database file,
see Chapter 2.

CREA TE LABEL

[Pfile namey- ] ?]

»e™U7“”d °P“ labd ■» >“ ™ a

it Zrf UNTULED LBX 7, 7* ,h' 'ab"


S,ve A. f„m ,he Fife J"u Un'‘l >™ ”” » “>^8
ESSENTIAL COMMANDS AND FUNCTIONS 575

If you specify a file name, FoxPro assumes an .LBX extension.


If you use the ? option, FoxPro displays a dialog box that lets the
user enter the name of the new file to be created.
For more information on creating label forms, see Chapter 6.

CREATE REPORT

[ Kfile name> | ?]

This command opens the report layout window to let you create a
new report form.
If you do not specify a file name, the new file that holds the label
form will be named UNTITLED.FRX until you save it by selecting
Save As from the File menu popup.
If you specify a file name, FoxPro assumes an .FRX extension.
If you use the ? option, FoxPro displays a dialog box that lets the
user enter the name of the new file to be created.
For more information on creating label forms, see Chapter 6.

CREA TE VIEW <file name >


This command opens the View window to let you create a view,
which is saved in file with the extension .VUE, and can then be used
at any time by entering the command SET VIEW TO <file name > or
by selecting Open from the File menu.
Chapter 7 includes a comprehensive discussion of the features of
the working environment that can be saved in a .VUE file.

DECLARE < array 1 > <numexpl>

[, < num exp2 > ]


[ < array2 > < num exp3 > [, < num exp4 > ] ]
t... 1
This command is used to create an array. It is identical to the
DIMENSION command.
An array is a series of memory variables which have the same
name but are distinguished by their index numbers (also called their
subscripts).
576 MASTERING FOXPRO

APP. C

For example, if you have ten different interest rates that you need
Aknay AS
to use in a program, it could be confusing to give each a separate
7 7 * ** C ^ name. You might find it easier to create an array to hold them. I he

AiArf
/t'/rrr
command

DECLARE int_rate(10)
/fK/K '
~\ <A creates ten memory variables, named int_rate(l), int_rate(2),
INN
int_rate(3), and so on. You can then initialize these variables as you
ft) : ,6
do any memory variable: for example,

int_rate(1) = .1
/?7'/V
Pp
_
uses ten percent as the first interest rate.
tv
The data type of each variable in the array is determined when it is
fj\bx
H7/< t 9> initialized.
P
C/ y
n
l) A si r ) i
r If you add the optional second numeric expression following the
array, you will create a two-dimensional array that is referred to by
A
two index numbers. Let’s say that you have ten different interest
fj\£TVfih
rates for each month. You could use the command

AV DECLARE int_rate(12,10)

to create 120 memory variables. Then you could use the variable
int_rate( 1,1) to hold the lowest interest rate for January, the vari¬
able int_rate(l ,2) to hold the second interest rate for January, and so on
through int_rate(l, 10), which holds the highest interest rate for January.
Likewise, you could use the variable int_rate(2,1) to hold the low¬
est interest rate for February, the variable int_rate(2,2) to hold the
second interest rate for February, and so on through int_rate(2,10),
which holds the highest interest rate for February.
Arrays are particularly powerful because you can use variables
as the index number and access the entire array by altering the value
of the variable. If you use a DO WHILE loop to change the value of
the index number, you can print out hundreds of variables using just
a few lines of code.
ESSENTIAL COMMANDS AND FUNCTIONS 5 77

DELETE

[ < scope > ]


[FOR <log expl>\

[WHILE < log exp2 > ]

This command marks a record for deletion. In its simplest form, it


marks only the current record (the record where the pointer is—in
the database file open in the current work area) for deletion.
If an optional scope, FOR, or WHILE clause is used, all the records
included in the specified scope, or all the records for which the logical
expression following the FOR or WHILE is evaluated as true, are
included and marked for deletion. For more information on how
these clauses work, see Chapter 5.
Records that are marked for deletion are not removed from the
database until the command PACK is used, and they are used like
other records. For information on how to make commands omit
records marked for deletion, see Chapter 5.

DELETE FILE <file name> | ?


This command deletes the file whose name is specified (or, if the ?
option is used, displays a dialog box that lets the user choose which
file to delete). The file name must include an extension, and it may
include a drive letter and path name, as in DOS.
Even if SAFETY is ON, the hie will be deleted without any warning.
This command is identical to the FoxPro ERASE command.
It is similar to the DOS commands DEL and ERASE, but it does
not support wild-card characters.

DIMENSION < array 1> <numexpl>

[, < num exp2 > ]


[ < array2 > < num exp3 > [, < num exp4 > ]
[... 1
This command is used to create an array. It is identical to the
DECLARE command.
578 MASTERING FOXPRO

APP. C

An array is a series of memory variables which have the same


p/n£tt$io(8 a[& ) name but are distinguished by their index numbers (also called their

(, is -Tm af subscripts).
For cxa.rn.plc, if you have ten different interest rates that you need
i oAi^et&S t* MAAY A
7 to use in a program, it could be confusing to give each a separate
•T?j£ l£to(ZTH »F TftE name. You might find it easier to create an array to hold them. The
C60LP SF 6& • command

DIMENSION int_rate(10)
to

f\io A)(Tf flACM - creates ten memory variables, named int_rate(l), int_rate(2),
A )f
int_rate(3), and so on. You can then initialize these variables as you
U k£ ^U~. do any memory variable: for example,

VSlot* ST&7&M&H ) int_rate(1) = .1

n££ A7& ArY W lf uses ten percent as the first interest rate. The data type of each vari¬
able in the array is determined when it is initialized.
If you add the optional second numeric expression following the
array, you will create a two-dimensional array that is referred to by
two index numbers. Let’s say that you have ten different interest
rates for each month. You could use the command

DIMENSION int_rate( 12,10)

to create 120 different memory variables. Then you could use the vari¬
able int_rate( 1,1) to hold the lowest interest rate for January, the
variable int_rate(l ,2) to hold the second interest rate for January, and so
on through int_rate(l,10), which holds the highest interest rate for Jan¬
uary. mice wise, you could use the variable int_rate(2,1) to hold the low¬
est interest rate for February, the variable int_rate(2,2) to hold the
second interest rate for February, and so on through int_rate(2,10),
which holds the highest interest rate for February.
Arrays are particularly powerful because you can use variables as
the index number and access the entire array by altering the value
of the variable. If you use a DO WHILE loop to change the value of
the index number, you can print out hundreds of variables using just
a few lines of code.
ESSENTIAL COMMANDS AND FUNCTIONS 579

DIR | DIRECTORY

[[ON] <drive: >]

[[LIKE] [<path>] [<skeleton>]\

[TO PRINT | TO FILE <fde narm>\

In its simplest form, this command displays the names of all data¬
base files in the current directory, the number of records in each, the
date each was last modified, and the size of each in bytes.
If the command is used with a skeleton, though, it is more like the
DOS command DIR, displaying all the files specified by the skeleton. A
skeleton can be made up of literals and the two wild-card characters, *
which stands for any word, and ? which stands for any character. For
example, DIR *.* will list a directory of all files in the current subdirec¬
tory, and DIR *.TXT will list a directory of all files in the current direc¬
tory that have the .TXT extension.
The optional ON and LIKE clauses let you specify the drive or the
path name that you want a directory for, so that you can get a direc¬
tory that is not for the current drive and subdirectory. The words ON
and LIKE themselves are optional in these clauses.
The optional TO PRINT or TO FILE <file name> clause lets you
send the directory listing to the printer or to the text file whose name
is specified.

DISPLA Y

[ < scope > ]


[FIELDS <field expr list > ]

[FOR < log expl > ]

[WHILE < log exp2 >}

[OFF]

[TO PRINT | TO FILE <file name>]

In its simplest form, this command displays the contents of the cur¬
rent record on the screen.
580 MASTERING FOXPRO

APP. C

If an optional scope clause is used, all the records included in the


specified scope will be displayed on the screen. If they require more
than one screen, they will be displayed one screen at a time, and the
user will be told to press any key to see the next screen.
If a FOR or WHILE clause is used, all the records included in the
specified scope for which the logical expression following the FOR or
WHILE is evaluated as true are displayed on the screen.
If an optional FIELDS clause is used, only the fields (or field
expressions) listed are displayed on the screen. For more information
on how these clauses work, see Chapter 5.
If the optional OFF clause is used, the record number is not dis¬
played.
The optional TO PRINT or TO FILE <file name> clause lets
you send the display to the printer or to the text file whose name is
specified.

DISPLA Y STRUCTURE

[IN <alias>]

[TO PRINT | TO FILE <JUe name >]

This command displays the structure of a database on the screen,


along with the number of records in that database and the date it was
last modified.
Ordinarily, it displays the structure of the database that is open in
the current work area. The optional IN <ahas> clause can be used
to make it display the structure of a database in another work area
The optional TO PRINT or TO FILE <file name> clause lets you
send the display of the structure to the printer or to the text file whose
name is specified.

DO < program file name>

[WITH <parameter list > ]

Thls command executes a program. If the program is not yet com


piled or if the source code has been modified since it was last compiled
ESSENTIAL COMMANDS AND FUNCTIONS 581

this command will automatically compile the program before run¬


ning it.
The optional parameter list can be used to pass parameters to the
program that is being executed. The program must include a
PARAMETER command that lists the variables that are parameters.
These variables are assigned the values in the parameter list of the
DO command. For more information, see PARAMETER.

DO CASE

CASE < log expl >

CASE < log exp2 >

[OTHERWISE

... ]

ENDCASE

This command lets a program select between a number of possible


courses of actions.
If the logical expression following the first CASE is evaluated as
true, the program executes the commands following it and then pro¬
ceeds to execute the commands following ENDCASE. Likewise, if the
logical expression following any succeeding CASE is evaluated as
true, the program executes the commands following it and then
moves to the commands following ENDCASE. The command may
include any number of CASEs, but it will only execute the first one for
which the logical expression is true.
Commands following the optional OTHERWISE statement are exe¬
cuted if none of the logical expressions in the CASE statements are true.

DO WHILE < log exp>

ENDO
This command lets you execute a block of program code repeat¬
edly. The code between DO WHILE and ENDDO will be executed
as long as the logical expression is true. This is called a loop.
If the expression is untrue when the program first reached the DO
WHILE statement, the program will simply skip all these lines of
code and continue with the line that follows the ENDDO. If the
expression is true, the program will execute all these lines of code.
When it reaches ENDDO, it will go back to the DO WHILE state¬
ment and check again to see if the condition is true. If so, it will exe¬
cute the code again; if not, it will continue with the line following
ENDDO
Normally you would have some code within the loop that ulti¬
mately makes the logical expression false, so that the code is executed
a finite number of times. Alternately, you can use the command
EXIT to break out of the loop. An infinite loop is a common pro¬
gramming error.
The command EXIT or LOOP may be used at any point within
the DO WHILE . . . ENDDO command. EXIT causes the program
to proceed with the next line following ENDDO. LOOP causes the
program to return immediately to the DO WHILE statement and to
evaluate the logical condition there to determine whether or not to go
through the loop again.

EDIT

[NOAPPEND]

[NOCLEAR]

[NODELETE]

[NOEDIT]

[NOFOLLOW]

[NOMENU]

[FIELDS <field list > ]

[ < scope > ]

[FOR Clog expl

[WHILE Clog exp2>]


ESSENTIAL COMMANDS AND FUNCTIONS 583

EDIT opens the Browse/Change window in its standard Change


configuration, with each held on one line. The commands EDIT and
CHANGE are identical: EDIT was more common in earlier dBASE
compatible programs, and CHANGE is more common in FoxPro.
You can edit existing records or use the Browse menu to add a new
record. If you click the close box, press Ctrl-W or Ctrl-End, or select
Close from the File menu, you can close the Browse/Change window
and save any changes you made. If you press Ctrl-Q, you can close
the Browse/Change window and discard any changes you made. To
edit memo fields, double-click the held with the mouse or move the
cursor to it and press Ctrl-PgDn to open the Memo window. When
you enter the command, a Browse popup appears, which lets you
partition the window, toggle the window to Browse mode, delete or
recall a record, and otherwise alter the window.
Many of the options that can be used with EDIT are useful primar¬
ily in programming, where you want to limit what the user can do.
NOAPPEND makes it impossible to add new records to the hie.
NOCLEAR leaves the Browse/Change window visible on the
screen after you are done using it. (By default, the window disap¬
pears when you are done.)
NODELETE makes it impossible to mark records for deletion.
NOEDIT makes it impossible to make any changes in the data.
NOFOLLOW makes the pointer stay where it is in the database
when you modify the held that the database in indexed on. (By
default, the pointer stays on the record, following that record to the
new position that it moves to because its key held was modihed.)
NOMENU makes the Browse/Change window open without the
Browse menu pad being added to the menu bar, so that the user can¬
not access the Browse menu popup.
You may restrict the number of helds available to be edited by
using a FIELDS, scope, FOR, or WHILE clause.
FIELDS <Jieldlist> makes the Browse/Change window display only
the helds mentioned in the held list. A scope clause makes the Browse/
Change window display only the records that fall in the specihed scope.
A FOR or WHILE clause makes the Browse/Change window display
only the records that meet some logical criterion. See Chapter 5 for
more discussion of how these clauses work.
584 MASTERING FOXPRO

APP. C

ERASE <file name> | ?


This command deletes the file whose name is specified (or, if the ?
option is used, displays a dialog box that lets the user choose which
hie to delete). The hie name must include an extension, and it may
include a drive letter and path name, as in DOS.
Even if you have set SAFETY ON, the hie will be deleted without
any warning.
This command is identical to the FoxPro DELETE FILE command.
It is similar to the DOS commands DEL and ERASE, but it does
not support wild-card characters.

EXIT
This command can only be used within a DO WHILE loop, a FOR
loop or a SCAN WHILE loop. It makes the program continue by exe¬
cuting the code that immediately follows ENDDO, ENDFOR or
ENDSCAN.

FIND < literal >


This command hnds the hrst record for which the expression that
is the basis of the the main index matches the literal.
It is similar to the SEEK command, except that it requires a literal
as the basis of its search and cannot search for expressions that use
functions or variables. (It can search for a variable if the macro sub-
sitution character, &, is used before the variable name, so that it
reads it as the contents of the variable rather than searching for the
letters in the variable’s name. If the literal is a character string, it does
not have to be enclosed in quotation marks unless it includes leading
blanks.

FOR <memvar> = < num expl > TO < num exp2 >

[STEP < num exp3 > ]

ENDFOR
ESSENTIAL COMMANDS AND FUNCTIONS 585

This command lets you repeatedly execute a series of lines in a pro¬


gram. The code between FOR and ENDFOR will be executed until
the memory variable is equal to the second numeric expression.
When the FOR statement is first encountered, FoxPro creates a
memory variable with the name of Kmemvary and assigns it the ini¬
tial value < num expl >. Then it executes the program until it reaches
ENDFOR. It then increments the value of <.merrwar> by 1 and loops
back to the FOR statement to check again whether <memvar> is
equal to Knum exp2>. It executes the code in the loop repeatedly
until <memvar> is equal to <num exp2>, and then it continues with
the code following ENDFOR.
If the optional STEP clause is included in the command, Kmem-
var> is incremented by the number that it specifies each time
through the loop—instead of being incremented by 1.
The command EXIT or LOOP may be used at any point within
the FOR . . . ENDFOR command. EXIT causes the program to pro¬
ceed with the next line following ENDFOR. LOOP causes the
program to return immediately to the FOR statement.

FUNCTION < name >

This command is used within a program or a procedure file to


mark the beginning of a procedure or a user-defined function. If it is
in a program file, the program may call it by using the DO command
followed by its name. If it is in a procedure file, you may call it by
using the DO command from a program or from the Command win¬
dow only after you have used the SET PROCEDURE TO command.
It can receive parameters from the DO command that calls it: for
more information, see PARAMETER
After all the code in a procedure is executed, control returns to the
line following the line that called it (or to the Command window).
Alternately, control can be returned to that point by using the com¬
mand RETURN. To return a value, a user-defined function must use
RETURN followed by an expression.
The command FUNCTION is identical to the command PROCE¬
DURE, but it is best stylistically to use FUNCTION for user-defined
functions and PROCEDURE for procedures that do not return a value.
A program file may contain up to 1,170 procedures and functions.
586 MASTERING FOXPRO

APP. C

GO \GOTO

[RECORD] Knumexpy \

TOP |

BOTTOM |

[IN <alias>]

This command lets you move the pointer within a database hie.
If it is used with a record number, it moves the pointer to that
record; the word RECORD is optional before the number.
If it is used with TOP or BOTTOM, it moves the pointer to the first
or last record of the database hie.
By default, this command works on the database hie that is open in
the current work area, but the optional IN <alias> clause can be used
to specify another work area.

HELP

This command displays the FoxPro Help window, which lets you
look up FoxPro commands and functions. For more information on
FoxPro help, see Chapter 1.

IF <log exp>

[ELSE

. . . ]
ENDIF

This command determines whether or not program code is exe-


cuted on the basis of some logical expression. If the logical expression
ol the IF statement is true, the code following it is executed.
An optional ELSE statement can include code that is executed if
the logical expression of the IF is evaluated as false. If no ELSE state-
mel^M^1Urdeud’ *he.ProSram simply proceeds with the code follow¬
ing ENDIF if this logical expression is evaluated as false.
ESSENTIAL COMMANDS AND FUNCTIONS 58 7

INDEX ON < field exp > TO < file name >

[FOR <log exp>]

[UNIQUE]

This command creates an index file for the database that is open in
the current work area. The index arranges records in an apparent
order based on the field expression; the actual order of the records in
the database file does not change. The field expression may not use
memo fields.
The index’s name is the file name that is specified. FoxPro as¬
sumes an .IDX extension for the index file, but this default may be
overridden by specifying a name that includes a different extension.
After this command is used, the index that has just been created is
open and sets the order of the records in the file. The index will be
updated automatically if it is open when the database file is modified,
or it may be updated using the REINDEX command.
The optional FOR clause makes the index include only records for
which the logical expression is true. When the file is modified, the
index is updated so that it always includes all the records in the file for
which the logical expression is true.
The optional word UNIQUE will make the index include only the
record with first occurrence of a given value for the field expression
that the index is based on. If this expression has the same value for
more than one record, all but the first will not be included in the index
and will not be accessible when the database file is used with this
index as the main index.

INPUT [< char exp >J TO < memvar >


This command lets a program get input from the user and stores
this input in the memory variable that is specified. The data type of
the user’s input determines the data type of the memory variable that
is created; for this reason, it is often preferable to use ACCEPT to get
data that is not numeric.
If the optional character expression is included, it is displayed as a
prompt for the user.
588 MASTERING FOXPRO

APP. C

LABEL FORM <file namel > | .p

[ENVIRONMENT]

[ < scope > ]

[WHILE <log expl>]

[FOR < log exp2 >]

[SAMPLE]

[TO PRINT | TO FILE <file name2>]

This command creates mailing labels for the database file that is
open in the currently selected work area. If CONSOLE has not been
SET OFF, the labels are displayed on the screen. They can also be
sent to the printer or to a text file.
Before this command is used, the label form must have been cre¬
ated and saved in a file. The command CREATE LABEL lets you
design these mailing label forms using the label layout window. The
default extension for these files is .LBX.
An existing form may be specified as Kfile namel > of the com¬
mand (or, if the ? option is used, FoxPro will display a scrollable list
allowing you to choose among available label forms).
The ENVIRONMENT option may be used if the environment was
saved when the label form was created. It automatically uses the same
environment—including, for example, an index file to set the order in
which labels are printed.
By default, labels are produced for all records in the database. A scope
clause makes the command produce labels only for the records that fall
in the specified scope. A FOR or WHILE clause makes the command
produce labels only for the records that meet some logical criterion. See
Chapter 5 for more discussion of how these clauses work.
The optional word SAMPLE makes the command produce a
single label as a sample, so you can test the alignment of the labels in
the printer. FoxPro will ask if you want another sample printed, so
you can do repeated tests until the alignment is right.
The optional TO PRINT or TO FILE <file name> clause lets you
send the labels to the printer or to the text file whose name is
specified.
ESSENTIAL COMMANDS AND FUNCTIONS 589

LIST

[ < scope > ]

[FIELDS <field expr list > ]

[FOR < log expl > ]

[WHILE <logexp2>]

[OFF]

[TO PRINT | TO FILE <file narm>\

In its simplest form, this command displays the contents of all


records in the current database file on the screen. If they require
more than one screen, they will scroll by until the end of the file is
reached.
If an optional scope clause is used, all the records included in the
specified scope will be displayed on the screen. If a FOR or WHILE
clause is used, all the records included in the specified scope for which
the logical expression following the FOR or WHILE is evaluated as
true are displayed on the screen.
If an optional FIELDS clause is used, only the fields (or field
expressions) listed are displayed on the screen. For more information
on how these clauses work, see Chapter 5.
If the optional OFF clause is used, the record number is not
displayed.
The optional TO PRINT or TO FILE <file namey clause lets you
send the display to the printer or to the text file whose name is
specified.

LOCATE FOR <log expl >

[ < scope > ]

[WHILE < log exp2 > ]

This command searches the database file that is open in the cur¬
rent work area from its beginning, until it finds the first record where
the logical expression following FOR is evaluated as true. The logical
expression can make use of any field of the database file, and the
590 MASTERING FOXPRO

APR C

database does not need to be indexed. This command is slower than


SEEK, which does an indexed search.
If LOCATE finds a matching record, it places the pointer on that
record. It may be followed by the command CONTINUE, which
finds the next record for which the logical expression is true.
If LOCATE does not find a matching record, the function EOF( ) is
made true.
By default, LOCATE searches the entire database file. If you add
an optional scope or WHILE clause, the search only continues until
the end of the scope is reached or until the logical expression following
WHILE is no longer true.

LOOP

This command can only be used within a DO WHILE loop, a FOR


loop or a SCAN WHILE loop. It makes the program return directly to
the beginning of the loop. If the condition there is true, it executes
code in the loop again, if not, it continues by executing the code that
immediately follows ENDDO, ENDFOR, or ENDSCAN.

MODIFY COMMAND

[ Kfile name > ]

This command opens an editing window to let you create a new


program file or modify an existing one. A program file is a plain
ASCII text file. When this command is used, the editor has the
default preferences that are most convenient for creating program
files for example, automatic indenting is turned on and word wrap
is turned off.
If the file name is used, it will be given an extension of .PRG by
name ‘S omitted- the program will be named
UNTITLED.PRG until it is named by selecting Save As from the

MODIFY FILE

\ <file name > ]


ESSENTIAL COMMANDS AND FUNCTIONS 591

This command opens an editing window to let you create a new


ASCII text file or modify an existing one. When this command is
used, the editor has the default preferences that are most convenient
for creating text files—for example, automatic indenting is turned off
and word wrap is turned on.
If the file name is used, it will be given an extension of .TXT by
default. If the file name is omitted, the program will be named
UNTITLED.TXT until it is named by selecting Save As from the
File menu.

MODIFY LABEL <file name> | ?


This command lets you modify an existing label form. You may
specify its name or use the ? option to display a dialog box that lets
you select it from a scrollable list of existing label files.
For more information on label forms, see the command CREATE
LABEL, which is used to create them.

MODIFY MEMO Cmemo field 1 >

[, < memo field2 > . . .

[NOWAIT]

This command opens a memo window to let you edit the memo
field of the current record of the database file that is open in the cur¬
rent work area. If a record has more than one memo field, you may
use the optional added memo field names to open more than one
memo window at a time—though all memo fields that are displayed
at one time must be from the same record.
By default, when this command is used in a program, the Memo
window is opened and the program does not continue until the user
closes it. The NOW AIT option continues running the program with¬
out waiting for the user to close the Memo window.

MODIFY REPORT <file name> | ?


This command lets you modify an existing report form. You may
specify its name or use the ? option to display a dialog box that lets
you select it from a scrollable list of existing Report files.
592 MASTERING FOXPRO

APP. C

For more information on label forms, see the command CREATE


REPORT, which is used to create them.

MODIFY STR UCTURE


This lets you modify the structure of the database that is open in
the currently selected work area. It calls the Structure dialog box,
which specifies the current structure of the database. By changing its
specifications, you can change the structure of the database-—for
example, by adding, deleting, or changing the length of fields.
Because this can lead to a loss of data, FoxPro automatically backs
up a database file when you modify its structure. The backup for the
.DBF file has the same name, but the extension .BAK. The backup
for the memo file has the same name but the extension .TBK.

PARAMETERS < parameter list >

This command lets a program or procedure receive the values of


variables from the command line or from a calling program.
It must be the first line of code (excluding comments) in the program
or procedure where it is used. The parameter list is a list of memory vari¬
ables separated by commas. These memory variables can be assigned
values by using a DO WITH <parameter list > command that was used
to call the program or procedure or, if they are in a user-defined func¬
tion, by putting the parameter list in the parentheses following the com¬
mand that calls it. In either case, the expressions in the parameter list of
the calling command or function are assigned to the variables in the
parameter list following the command PARAMETER. If there are more
memory variables in the list of the PARAMETERS command than in
the list of the DO WITH command, extras are initialized with the value
of .F.

PEA YMACRO < macro name >

This command lets you play back the keystrokes that were saved in
the macro whose name is specified. If it is used in a program, the
macro is not played back until there is an opportunity to use the key¬
strokes as input. If more than one PLAY MACRO command has
been used in a program without there being an opportunity for input
ESSENTIAL COMMANDS AND FUNCTIONS 593

(so that several are waiting to execute), they are used in reverse
order: the last command that was used is the first macro that is
played.

PRIVATE < memvar list > | ALL [LIKE < skeleton >
| EXCEPT < skeleton >]
This command allows you to create memory variables that are
accessible only to the program or procedure where they are defined,
so that more than one program or procedure can have memory vari¬
ables of the same name. PRIVATE may be used only in programs and
has no effect if it is used from the Command window.
If a memory variable is defined as PRIVATE, any memory variables
from other programs or procedures that have the same name are tempo¬
rarily hidden while the program or procedure where they are defined is
executed; after it is done, they become active again.
You can use PRIVATE with a list of all the memory variables that
you want to be private, or use ALL to make all memory variables pri¬
vate. If ALL is followed by LIKE <skeleton>, all variables that
match the skeleton will be private. If ALL is followed by EXCEPT
<skeleton>, all variables that do not match the skeleton will be pri¬
vate. Skeletons may be created using literals and the wild-card
characters, ? and *.

PROCEDURE < name >

This command is used within a program or a procedure file to


mark the beginning of a procedure or a user-defined function. If it is
in a program file, the program may call it by using the DO command
followed by its name. If it is in a procedure file, you may call it by
using the DO command from a program or from the Command win¬
dow only after you have used the SET PROCEDURE TO command.
A proceedure can receive parameters from the DO command that
calls it: for more information, see PARAMETER.
After all the code in a procedure is executed, control returns to the
line following the line that called it (or to the Command window).
Alternately, control can be returned to that point by using the com¬
mand RETURN. To return a value, a user-defined function must use
RETURN followed by an expression.
594 MASTERING FOXPRO

APP. C

The command PROCEDURE is identical to the command FUNC¬


TION, but it is best stylistically to use FUNCTION for user-defined
functions and PROCEDURE for procedures that do not return a value.
A program file may contain up to 1,170 procedures and functions.

PUBLIC [ARRA Y] < memvar list >


This command lets memory variables be used by any program or
procedure. This sort of variable is called a global variable.
A memory variable must be declared as PUBLIC before it is
assigned a value. When it is first created by the PUBLIC command
itself, the variable is assigned the temporary value of .F. (The only
exception is the variable FOX, an advanced feature that lets a Fox¬
Pro program use external commands and functions, which is auto¬
matically initialized as .T.) It can then be assigned any value.
Elements of arrays can also be made global variables. They should
simply be listed following the word PUBLIC like any other variable.
The list must include their names and index numbers. When array
elements are being declared as public, the command may include or
omit the optional key word ARRAY.

QUIT
This command terminates FoxPro and returns the user to the op¬
erating system. It can be used in programs as well as from the Com¬
mand window. To avoid possible loss of data, you should always enter
this command before turning off the computer.

READ

[SAVE]

This command lets the user edit the variables of all active @ . . .
GET commands.
In general @ . . . GET commands remain active until the com-
mand CLEAR, CLEAR GETS, CLEAR ALL, or READ is executed.
II the SAVE option is used, though, the READ command leaves
the @ . . . GET commands active, so they can be used again bv
another READ command.
ESSENTIAL COMMANDS AND FUNCTIONS 595

RECALL

[ < scope > ]

[FOR <logexpl'>\

[WHILE < log exp2 > ]

This command unmarks a record that has been marked for dele¬
tion. In its simplest form, it unmarks only the current record (the
record where the pointer is in the database file open in the current
work area).
If an optional scope, FOR, or WHILE clause is used, all the records
included in the specified scope, or all the records for which the logical
expression following the FOR or WHILE is evaluated as true, are
unmarked. For more information on how these clauses work, see
Chapter 5.
Records can be marked for deletion using the DELETE com¬
mand. See this command for more information.

REINDEX
This command rebuilds all index files that are open in the current
work area. For information on how to open indexes, see the com¬
mand USE in this appendix or see Chapter 4.
This command is necessary only if an index file was not open when
its file was being modified, so that it has not been updated to reflect
changes in the file.

RENAME < file name 1 > TO < file name 2 >


This command gives a new name to a disk file. The file that had
been named Kfile name 7 > is named Kfile name 2 > instead. The full
path name of files may be used.
When this command is used, there must already be a file named
<file name 1> and it must not be open. There must not be a file
already named <file name 2 >.
This command is similar to the DOS command RENAME.
REPLACE [<scope >] <field 1 > WITH <expl >

[ADDITIVE]

[ <field.2> WITH <exp2> . . . ]

[FOR <logexpl\

[WHILE <logexp2>]

In its simplest form, this command puts new data in a field of the
record where the pointer is, in the database file that is open in the cur¬
rently selected work area. The current data in the field is replaced
with < expl >.
The command may also be used with additional fields and expres¬
sions to replace the data in all of the fields that are listed.
If an optional scope, FOR, or WHILE clause is used, all the records
included in the specified scope, or all the records for which the logical
expression following the FOR or WHILE is evaluated as true, will have
the specified fields replaced with the specified expressions. For more
information on how these clauses work, see Chapter 5. REPLACE can¬
not be used with one of these options on the key field of the active index:
if it is, the replacement may not occur in all the fields specified.
The ADDITIVE option may be used only with memo fields. If it is
used, the data currently in the memo field remains there, and the
data specified in the expression is added to the end of the memo field.

REPOR T FORM < file name 1 > | ?

[ENVIRONMENT]

[ < scope > ]

[WHILE < log expl > ]

[FOR < log exp2 > ]

[PLAIN | HEADING Kchar expy-]

[NO EJECT]

[TO PRINT | TO FILE <file name2 > ]

This command produces reports on the database file that is open in


the currently selected work area. If CONSOLE has not been SET
ESSENTIAL COMMANDS AND FUNCTIONS 597

OFF, the reports are displayed on the screen. They can also be sent to
the printer or to a text file.
Before this command is used, the report form must have been cre¬
ated and saved in a file. The command CREATE REPORT lets you
design these report forms using the report layout window. The
default extension for these files is .FRX.
An existing form may be specified as Kfile namel > of the com¬
mand, or if the ? option is used, FoxPro will display a scrollable list
allowing you to choose among available report forms.
The ENVIRONMENT option may be used if the environment was
saved when the report form was created. It automatically uses the
same environment—including, for example, an index file to set
the order in which reports are printed.
By default, reports are produced for all records in the database. A
scope clause makes the command produce reports only for the
records that fall in the specified scope. A FOR or WHILE clause
makes the command produce reports only for the records that meet
some logical criterion. See Chapter 5 for more discussion of how
these clauses work.
The PLAIN option suppresses the printing of the heading at the top of
each page. The HEADING <charexp> option prints the specified char¬
acter expression as the heading at the top of each page.
The NOEJECT option prevents the printer from ejecting a page
before it prints the report. By default, this command sends a form
feed to the printer before beginning its first page.
The optional TO PRINT or TO FILE <file name> clause lets
you send the reports to the printer or to the text file whose name is
specified.

RETURN

[ TO MASTER | <exp> j TO <procedure name> ]

This command returns program control from the current program


or procedure to the program or procedure that called it (or to the
Command window or operating system, if it was called from there).
RETURN is optional at the end of a program or procedure: control
returns to the calling program or procedure automatically.
598 MASTERING FOXPRO

APP. C

The TO MASTER option returns control to the highest level


calling program or procedure instead of to the program or procedure
that called the current one. The TO <procedure name> option
returns control to the procedure that is named instead of to the pro¬
gram or procedure that called the current one.
RETURN must be followed by the <exp> option when it is used in
a user-defined function. It then returns the value specified by the
expression to the calling program or procedure.

RUN <command> \ ! <command >


This command lets you ran a DOS command or any external com¬
mand that can be used at the DOS prompt from the FoxPro command
window. Of course, FoxPro takes up some of your computer’s memory,
so you may not be able to run commands that require extensive mem¬
ory from within FoxPro.

SCAN

[ < scope > ]

[FOR <log expl > ]

[WHILE Klog exp2>]

ENDSCAN

This command creates a loop that is something like a DO WHILE


loop except that it is used for going through ail the records in a data¬
base hie and performing the statements between SCAN and ENDS-
CAN on all of them.
/ —— — otaiciucmb are penormed tor all the records. A scope
c ause makes the statements apply only to the records that fall in the
specified scope. A FOR or WHILE clause makes the statements apply
on y o the records that meet some logical criterion. See Chapter 5 for
more discussion of how these clauses work

°r LOOP may ^ used at any point within


the SCAN ENDSCAN command. EXIT causes the program to
proceed with the next line following ENDSCAN. LOOP causes the
program to return immediately to the SCAN statement.
ESSENTIAL COMMANDS AND FUNCTIONS 599

SELECT <work area> ALSo


This command lets you choose the current work area.
FoxPro lets you open database files in up to ten work areas. By
default, commands apply to the file in the current work area. You begin
in work area 1, but can change work area by using this command.
When you are using this command, you may refer to the work
area by using one of three names:

• the name of the file that is open in it, if any

• a number from 1 through 10

• a letter from A through J

You may also refer to work area 0, and FoxPro automatically


interprets the number to mean the lowest numbered work area in
which no database file is currently open.

SET ALTERNATE ON j OFF

Used with ON, this command saves screen output in a text file.
Used with OFF, it stops sending screen output to the text file.
Before this command is used, the text file must be designated using
the command SET ALTERNATE TO <file name^.
The default value setting is OFF, so after the file is designated, SET
ALTERNATE ON must be entered before output is sent to it.

SET AL TERNA TE TO

[ Kfile namey [ADDITIVE]]

If it is used with a file name, this command designates a text file to


which you can send screen output by using the command SET
ALTERNATE ON.
If it is used without any file name, it cancels a previous designation
of this sort of file, so that you can no longer save screen output in a
text file.
The ADDITIVE option adds screen output to any text that is cur¬
rently in this file. By default, the SET ALTERNATE TO command
overwrites any text in the file, if it already exists—but using SET
ALTERNATE ON | OFF repeatedly afterwards will continue to add
text to the designated file and not overwrite what is in it.

SET BELL ON \ OFF


Used with OFF, this command prevents FoxPro from beeping
during data entry when you reach the end of a field or enter invalid
data. Used with ON, it causes FoxPro to beep again in these situa¬
tions. The default setting is ON.

SET BELL TO

[ < frequency >, < duration > ]

This command lets you change the pitch and duration of the beep
that occurs during data entry.
The number that designates the frequency can be between 19 and
10,000 hertz. The number that controls how long the beep lasts may
be between 1 and 19.
Used without these optional numbers, the command returns the
beep to the default settings, which are 512 hertz and a duration of 2.

SET CARRY ON \ OFF

Used with ON, this command carries forward the data that is
entered in each record while you are appending data, so that it
appears as the default entry in the next record. Used with OFF, it dis¬
ables this feature.
This command is useful if you must do repetitive data entry.
The default setting for CARRY is OFF.

SET CARRY TO

[ <field list > [ADDITIVE]]

Used with a field list, this command determines what fields will be
earned forward when SET CARRY ON is used. Only the listed fields
will appear in the next record as default entries.
ESSENTIAL COMMANDS AND FUNCTIONS SO 1

The ADDITIVE option adds the fields that are listed to the fields
listed in a previous SET CARRY TO command that is still active.
Without this option, only the fields listed in the most recent SET
CARRY TO command are carried forward.
Used without a field list, this command returns to the default set¬
ting, in which all fields are carried forward if a SET CARRY ON is
entered.

SET CENTUR Y ON j OFF


Used with ON, this command makes dates appear with all four
digits of the year displayed. SET CENTURY OFF makes dates
appear with only the last two digits of the year displayed.
The default setting for century is OFF.

SET CONSOLE ON j OFF


Used with OFF, this command stops output to the screen. Used
with ON, it makes output appear on the screen. The default setting
for CONSOLE is ON.

SET DEFAULT TO <path name>


This command lets you change the current drive or directory,
where FoxPro looks for files by default. The path name used may be
a disk drive designation (a letter followed by a colon). It may be a disk
drive and DOS path name (a letter followed by a colon followed by a
backslash and a subdirectory name or names separated by back¬
slashes). Or it may consist just of subdirectories separated by
backslashes, if the path is on the current drive.
For more information on DOS path names, see Chapter 2.

SET DELETED ON j OFF


This command determines whether FoxPro commands disregard
records that are marked for deletion. Used with ON, it will make com¬
mands ignore records marked for deletion. The default for DELETED is
OFF: by default, commands use records that are marked for deletion.
602 MASTERING FOXPRO

APP. C

This setting does not affect the commands INDEX and RE¬
INDEX, which always act on all records, regardless of whether they
are marked for deletion.

SET DEVICE TO SCREEN \ PRINTER | FILE <file name >


This command controls where FoxPro sends the output of @ . . .
SAY commands.
The default is SCREEN, which displays the output on the moni¬
tor. This command can be used to send the output to the printer or
the text file whose name is specified.
The output of @ . . . SAY commands cannot be redirected using
SET CONSOLE, SET PRINT, or SET ALTERNATE. Thus, SET
DEVICE makes up for this deficiency of these commands.

SET ECHO ON \ OFF


This command controls the Trace window, which is useful for
debugging programs. When it is used with ON, the source code
for your program is displayed in the Trace window as it runs, and the
line that is currently being executed is highlighted.
The default setting is OFF.

SET ESCAPE ON \ OFF


This command controls whether the Esc key can be used to inter¬
rupt the program. If it is used with OFF, the Esc key has no effect and
the program continues to execute. If ESCAPE is ON, pressing the Esc
key makes FoxPro display a dialog box with the choices Cancel
(which stops program execution), Suspend (which stops program
execution temporarily, until the command RESUME is used)^ and
Ignore (which continues program execution as if Esc had not been
pressed).
The default setting is ON. It is best not to add the command SET
ESCAPE OFF until a program is thoroughly tested and debugged.

SET EXACT ON \ OFF


This command determines whether strings that are compared
using the - operator must be identical for there to be a match. If
ESSENTIAL COMMANDS AND FUNCTIONS 603

EXACT is ON, then there will only be a match if the strings are the
same length and have the same characters. If EXACT is OFF, there
can be a match as long as all characters are identical up to the point
where one string comes to an end.
The default setting is OFF.

SET FIELDS ON j OFF


This command determines whether the fields list in a previously
used SET FIELDS TO command will determine which fields of the
database are accessible. If it is used with OFF, all fields will be dis¬
played. If it is used with ON, only fields listed in the SET FIELDS TO
command will be displayed.
The default setting is OFF, but when the commands SET FIELDS
TO is used, the setting is automatically changed to ON, so that a sepa¬
rate SET FIELDS ON command does not have to be used.

SET FIELDS TO

[ Kfield list > | ALL]

If this command is used with a field list, only the fields that are
listed will be accessible to the user or to other commands. For
example, if the user opens a Browse/Change window, it will only
include these fields.
When it is used with a field list, this command is additive. If it is
used a second time, the fields that are listed are added to the fields
that are already accessible because they were listed in the first SET
FIELDS TO command.
When it is used with ALL, the command makes all fields accessible
once again.
Using SET FIELDS TO without a field list or ALL cancels the
fields that have been listed by earlier uses of this command, so a new
SET FIELDS TO <fieldlist> can then be used without being additive.
The command SET FIELDS OFF temporarily disables the restric¬
tions imposed by this command, and the command SET FIELDS ON
enables them again. When SET FIELDS TO is executed, FIELDS
also are automatically set ON.
604 MASTERING FOXPRO

APP. C

SET FILTER TO

[ < log exp > ]

After this command is used with a logical expression, only the


records of the currently selected database for which the logical expres¬
sion is evaluated as true are accessible.
Using it without a logical expression removes the filter, so that all
records are accessible once again.

SET FORMAT TO

[ <file name > | ? ]

This command lets you use a format file, so that the format in this
hie will be used rather than the ordinary Browse/Change window
when the command APPEND, BROWSE, CHANGE, EDIT, or
INSERT is used.
A format hie consists of @ . . . SAY . . . GET statements that
determine how the screen is arranged. The program hie has an
.FMT extension, and the compiled hie is given a .PRX extension.
SET FORMAT TO may be used with the name of the format hie
that will be used or with the ? option, which makes FoxPro display a
dialog box that lets you choose from a scrollable list of available for¬
mat hies.
If SET FORMAT TO is used alone, a format hie used previously is
deactivated, and FoxPro uses the ordinary Browse/Change window
again.

SET INDEX TO

[ < indexfile list > | ?]

This command opens one or more index hies. (Tht maximum


allowed is 21.) The hies must already have been created for the data¬
base hie that is active in the current work area.
If you include a list of index hies, the hrst index in the list is the
master index that sets the order of the hle’s records.
ESSENTIAL COMMANDS AND FUNCTIONS 605

If you use the ? option, FoxPro displays a dialog box that lets you
choose from a scrollable list of available index files.
If SET INDEX TO is used alone, any indexes that are open in the
current work area are closed.

SET NEAR ON j OFF


This command determines where the pointer is after an unsuccess¬
ful indexed search using the SEEK or FIND command.
If it is used with ON, the pointer is left at the record nearest to a
match if the search is unsuccessful, so that the user can browse
through nearby records. If NEAR is OFF, the pointer is left at the end
of the database file if the search is unsuccessful.
The default for NEAR is OFF.

SET ORDER TO

[ < num exp > ]

This command can be used to change the index which is the mas¬
ter index that determines the order of the records if a database file is
in use with a number of indexes active.
The numerical expression refers to the order that the indexes were
in when they were first opened with a USE command or a SET
INDEX TO command. The first index listed in any of these com¬
mands is made the master index. But the SET ORDER TO command
changes the index whose position in the list is specified by the numeri¬
cal expression into the master index instead.
If SET ORDER is used with no numeric expression or with the
number 0, the indexes remain open but none sets the order of
the records. The records are displayed in the actual order in which
they appear in the hie.

SET PRINTER ON \ OFF


When it is used with ON, this command sends screen output to the
printer. The default is OFF.
This command does not work with screen output that is formatted
using the @ . . . SAY command. To send that output to the printer,
see SET DEVICE TO
SET PROCEDURE TO

[<file>]

When it is used with a file name, this command activates the pro¬
cedure hie that is specified, so that procedures and user defined
funtions in it may be used. If the hie name does not include an exten
sion, FoxPro assumes the extension .PRG.
If you use this command without a hie name, this command closes
an open procedure hie.

SET RELATION TO

[ <expl> INTO <alias> [ADDITIVE]]


[, <exp2> INTO <alias> [ADDITIVE]]
[...]

This command lets you relate two hies, and its most important use
is in creating relational databases.
To create a relational database, Kexpl > must be a held expression
based on the database hie that is open in the currently selected work
area. <Alias> must refer to an indexed hie that is open in another
work area; it must refer to it either by its name, by the letter or num¬
ber of its work area, or by an alias that you gave it when you opened
the hie. When the command is used in this way, FoxPro looks for the
record in the second hie whose index key expression matches
Kexpiy: as you move the pointer in the hrst hie, it automatically
moves the pointer to the corresponding held in the second hie. Thus,
you can set up a database based on a one-to-one or one-to-many rela¬
tionship between two hies.
lhis command can also be used with an unindexed <alias> hie.
In this case, Kexpl > must be a numeric expression. As you move the
pointer through this hie, the pointer automatically moves to the
record in the alias hie whose record number is equal to the value of
this expression. For example, this version of the command can be
used with the function RECNOQ as Kexpl >, so that the pointer will
move to the record in the alias hie that has the same record number as
the current record in the hrst hie.
ESSENTIAL COMMANDS AND FUNCTIONS 60 7

In either case, if there is no corresponding record in the second file,


the pointer moves to the end of file and the function EOF() becomes
true; thus, you can use this function for error trapping when you are
programming a relational database.
The optional second <exp2> INTO < alias > and . . . indicate
that you can set more than one relation between the two files with a
single command.
The optional ADDITIVE adds the relations that you are creating
to any current relations that exist. By default, the relations you create
replace any existing ones.
SET RELATION TO used by itself removes any existing relations.

SET STEP ON | OFF


Used with ON, this command lets you execute a program one line
of code at a time, to make debugging easier. When you use this com¬
mand, the Trace window is automatically opened and displays the
program with each line of code highlighted as it is run. You may
select the Resume text button to execute the next line of code or the
Cancel text button to stop executing the program.
The default setting for STEP is OFF.

SET TALK ON j OFF


Used with OFF, this command lets you disable the FoxPro “talk.”
Talk refers to the messages that scroll on the screen (behind any open
windows that happen be in the way) when you perform certain func¬
tions. For example, if you move the pointer through a database file, the
talk will tell you the number of the current record, and if you copy or
pack a file, the talk will tell you how many records have been copied.
The default setting for TALK is ON. It is best not to SET TALK OFF
when you are using FoxPro. The command is useful in programs,
where you do not want the end user to be confused by the talk.

SET TYPEAHEAD TO <num exp>


This command controls how many characters will be stored in the
keyboard buffer.
608 MASTERING FOXPRO
APR C

If you type more quickly than FoxPro can react, it stores, by


default, as many as 20 keystrokes in a part of memory called the key¬
board buffer: as soon as FoxPro has reacted to earlier commands and
is ready for more keystrokes, it will use the keystrokes stored in the
buffer as if you had just typed them.
You can use this command to set the keyboard buffer so that it
stores up to 128 characters. This is useful if you are a good typist and
have a slow computer.
FoxPro uses a very brief beep when the keyboard buffer is full, to
let you know that the keystrokes that you are entering will not be
stored and used.

SET VIEW ON j OFF

This command opens and closes the View window, to let you set
up a working environment. Entering SET VIEW ON is equivalent to
selecting View from the Window menu; entering SET VIEW OFF is
equivalent to closing the window by pressing Esc or clicking the close
box. For more information on views, see Chapter 7.

SET VIEW TO <file name > j ?

This command lets you use a working environment (or View) that
you have previously saved in a .VUE file. You may specify the file
name or use the ? option to select it from a scrollable list of available
•VFJE files. For more information on views, see Chapter 7.

SKIP

[ <num exp>] [IN <alias>]

This command moves the pointer in a database hie, changing the


record that is the current record, which is affected by commands such
as DELETE or CHANGE
se by itself, SKIP moves the pointer to the next record in the
atabase file; that is, it moves the pointer forward one record. It can
also be used with a number or numeric expression to move the
pointer forward any number of records. If it is used with a negative
ESSENTIAL COMMANDS AND FUNCTIONS 609

number, it moves the pointer back that number of records. For


example, SKIP - I would move the pointer to the previous record.
If you try to use this command to move the pointer to a location
that is beyond the last record, the function EOFQ is given the value
.T. If you use it to move to a location that is before the first record,
the function BOFQ is given the value .T.

SORT TO <file name> ON <fieldl >

[/A] [/G] [/D]

[,<Jield2> [/A] [/C] [/D] . . . ]


[ASCENDING | DESCENDING]

[ < scope > ]

[FOR <logexpl >]


[WHILE <log exp2 > ]
[FIELDS <field list > ]

In its simplest form, this command sorts the hie that is open in the
current work area, based on the held that is specihed, and in ascend¬
ing order. It also puts the result in the hie that is specihed.
The option [/A] lets you specify ascending order explicitly, though
it is done by default if it is not specihed. The option [/D] lets you sort
in descending order. The option [/C] makes the sort ignore the case of
a character held; if it is not included, the sort will be in ASCII order,
with uppercase before lowercase letters.
If you specify more than one held to sort on, subsequent helds will
be used as tie-breakers, in case the values in the hrst held are identi¬
cal. You can use the [/A], [/C], or [/D] options separately for any of
the helds.
The ASCENDING and DESCENDING options apply only to helds
that do not include the [/A] or [/D] options, and determine whether
these helds will be sorted in ascending or descending order.
By default, all the records in the currently open hie are sorted into
a new hie. If a scope clause is used, only the records that fall in the
specihed scope are sorted into the new hie. If a FOR or WHILE clause
is used, only the records that meet some logical criterion are sorted
610 MASTERING FOXPRO

APP. C

into the new file. If a FIELDS clause is used, only the fields that are
listed are included m the new file. See Chapter 5 for more discussion
of how these clauses work.
The SORT command, in addition to creating a new output file,
uses temporary work files, and so it uses up to three times as much
disk space as the space occupied by the original file. If this disk space
is not available, FoxPro can terminate abnormally, causing a possible
loss of data.

STORE <exp> TO <memvarl> [,memvar2 . . . ]


| <memvar> — <exp>
If the specified memory variable does not yet exist, this command
creates it and assigns it the specified value. If the specified memory
variable does exist, it replaces its current value with the specified
value.
If you use STORE, you can assign values to (and, if necessary, create)
a list of memory variables with a single command. If you use = , you
can only assign a value to (and create) one memory variable at a time.

SUM

[ < scope > ]

[TO Kmemvar list> j TO ARRAY Karray name^>]


[FOR < log expl >]

[WHILE <logexp2>]

In its simplest form, this command adds the values in all numeric
fields of all records in the database file that is open in the currently
selected work area. If the command SET TALK OFF has not been
used, the total for each field is displayed as FoxPro “talk.”
The option TO Kmemvar list> \ TO ARRAY <array rmme> lets you
store the results in memory variables. FoxPro creates the memory vari¬
ables specified, if they do not already exist. The array must be declared
with the DIMENSION or DECLARE command before using this com¬
mand. The order in which values are assigned to the memory variable
ESSENTIAL COMMANDS AND FUNCTIONS 611

list or to the elements in the array depends on the order in which the
numeric fields appear in the database.
By default, all the records in the currently open file are added. If a
scope clause is used, only the records that fall in the specified scope are
added. If a FOR or WHILE clause is used, only the records that meet
some logical criterion are added.

TEXT

ENDTEXT

This command displays text to the screen or to the frontmost win¬


dow. If the command SET PRINTER ON has been used, the text will
also be sent to the printer. If the command SET CONSOLE OFF has
been used, the text will not be displayed on the screen.

TOTAL TO <file name> ON <key field>

[ < scope > ]

[FIELDS <field list > ]


[FOR <log expl>]
[WHILE < log exp2 >]

This command lets you create a new database file that contains
totals of the numeric fields of the database that is open in the cur¬
rently active work area.
By default, the totals are given for all records that have the same
value in the key field that is specified. For example, if you total on
STATE (assuming there is a STATE field in the database), the new
file you create will have a record for each state in the original file, and
that record will include the totals of all the numeric fields in the origi¬
nal file’s records from that state.
For this command to work properly, the file must be sorted on the
key field or must be indexed on the key field and in use with that
612 MASTERING FOXPRO

APP. C

index as the major index that determines the order of the records.
If a scope clause is used, only the records that fall in the specified
scope are included in the totals. If a FOR or WHILE clause is used,
only the records that meet some logical criterion are included in the
totals.

TYPE <filel>

[TO PRINT j TO FILE <file2>]


[NUMBER]

This command displays the contents of a text hie on the screen or


in the frontmost output window. The file’s full name, including its
extension, must be used.
Using the TO PRINT option sends the contents of the hie to the
printer, and using the TO FILE <file2> option sends it to the hie
whose name is specihed.
The NUMBER option adds a line number at the beginning of each
line of the output. By using it in combination with TO FILE
<file2>, you can create a second hie that is identical to the hrst
except that its lines are numbered.
This command is similar to to the DOS command TYPE.

USE

[ < database file > | ? ]

[IN < work area >]


[INDEX < index file list > ]
[ALIAS <alias >]
[NOUPDATE]

In its basic form, this command opens the specihed database hie in
the current work area; if a hie is open in the work area already, that
hie is closed.
If it is used with a ? instead of with a hie name, this command dis¬
plays a scrollable list to let the user choose an available database hie.
The command USE by itself simply closes any database hie that is
already open in the current work area without opening a new one.
ESSENTIAL COMMANDS AND FUNCTIONS 613

The option IN < work area > opens the database hie in the work
area that is specified instead of in the current work area.
The option INDEX <indexfile list> opens the specified index hies
as well as the database hie. These index hies must have been created
previously. The hrst index hie in the list is the main index, which sets
the order of the records, and all index hies in the list are updated to
f

reflect changes made in the database hie.


The ALIAS <alias> option lets you give the hie a second name. If
it has an alias name, the hie can be referred to by this alias as well as
by its name or by the letter or number of its work area.
The NOUPDATE option prevents the user from making any
changes to the database hie.

WAIT

[ < char exp > ] [TO < memvar >]

Used by itself, the command WAIT displays the message “Press


any key to continue ...” and causes program execution to pause
until the user presses a key.
If the optional character expression is included, that expression is
used as the prompt instead of the default message mentioned above.
If the option TO <memvar> is used, the key that the user presses is
stored in the memory variable that is specihed. Thus, the user can
input a keystroke without having to press Enter afterwards.
If this memory variable does not already exist, FoxPro creates it. If
the user presses Enter or a nonprintable character, the memory vari¬
able is assigned the NULL character (ASCII character 0).

ZAP
This command removes all records from a database, leaving only
the database structure; this data cannot be recovered. It is equivalent
to entering the command DELETE ALL and then the command
PACK, except that it works more quickly. If SAFETY is SET OFF, it
will not warn you before deleting all your data permanently.
Needless to say, it should be used with great caution—if at all.
614 MASTERING FOXPRO

APP. C

FUNCTIONS

& < char memvar >

[. < char exp > ]

& is the macro substitution function. When it precedes the name of


a character variable, FoxPro reads this expression as if it were the lit¬
eral characters stored in the variable, rather than a variable re¬
presenting those characters. This is important because there are
places within FoxPro commands where you cannot use variables: by
making a macro substitution, you can trick the command into think¬
ing that a variable is the literal that it needs. The variable must hold
no more than 1,024 characters.
The optional part of the command can be used to add more char¬
acters to those in the variable. The dot operator combines the charac¬
ter expression that follows it with the characters in the variable, as if
they were a single character literal.

ALLTRIM(< char exp >)


This function returns the character expression with all leading and
trailing blanks removed.

BETWEEN(<expl >, <exp2 >, <exp3 >)

This function returns .T. if the value of expl falls between the
values of exp2 and exp3—or, more precisely, if expl is greater than or
equal to exp2 and expl is less than or equal to exp3. Otherwise, it
returns .F.

BOF([ < alias > ])

This function indicates the beginning of the hie. It returns .T. if


you attempt to move the pointer to a position before the first record of
the database.
Ordinarily, it is used for the hie that is open in the current work
area. If the <alias> option is used, though, it applies to the file that is
open in the work area whose letter, number or alias name is specified.
ESSENTIAL COMMANDS AND FUNCTIONS 615

CDOW(< date exp >)


This function returns the day of the week in character form for the
date specified.

CMONTH(< date exp >)


This function returns the month in character form for the date
specified.

DATEQ
This function returns the current system date—the date on your
computer’s clock/calendar or the date that you entered when you
started your computer.

DAY(< date exp >)


This function returns the day of the month of the specified date
expression in number form. If the date expression is 12/10/90, for
example, it will return 10.

DELETED([< alias >])


This function indicates whether the current record is marked for
deletion. If it is, DELETED( ) returns .T.; if not, it returns .F.
By default, this function applies to the record where the pointer is,
in whatever database file is open in the current work area. If the
<alias> option is used, though, it applies to the record where
the pointer is in whatever database file is open in the work area indi¬
cated by the number, letter, or alias name that is specified.

DTOC(<date exp > [,1])


This function returns the specified date expression as a character
string.
The optional ,1 returns the character string in a form that can be
used directly in an index.
616 MASTERING FOXPRO

APP. C

EOF([< alias >])


This function returns .T. if the end of the hie is reached. This con¬
dition occurs if a database hie has no records in it, or if you try to
move the pointer to a record beyond the end of the hie, or if the com¬
mand SEEK, LOCATE, CONTINUE, or FIND was unsuccessful.
By default, this function applies to the database hie open in the
current work area, but the <alias> option lets you specify another
work area, by using the letter or number of the work area or the name
or alias of the hie open there.

FO UND(f< alias >])


This function returns .T. if a record is found by the command
SEEK, LOCATE, CONTINUE, or FIND, or an .F. if the search was
unsuccessful. Thus, its value after a search is just the opposite of the
value of EOF( ). Some programmers prefer using this function to test
for the success of a search.
By default, this function applies to the database hie open in the
current work area, but the <alias > option lets you specify another
work area, by using the letter or number of the work area or the name
or alias of the hie open there.

IIF(<\og exp>, <expl >, <exp2 >)


This function, “the immediate if,” returns the value of the hrst ex¬
pression if the logical expression is true, or the value of the second
expression if the logical expression is false.
Thus, it lets you build an IF into expressions. For example, you
could use an IIF( ) on a mailing label to print one string expression
for people who have paid their membership dues and another expres¬
sion for those who have not.

LEN( < char exp > J

This function returns the length of the specihed character expres¬


sion. The expression may be a literal, a memory variable, the name
of a character held, or the name of a memo held.
ESSENTIAL COMMANDS AND FUNCTIONS 617

LOWER(<char exp>)
This function returns the specified character expression with all its let¬
ters converted to lowercase. It does not affect non-alphabetic characters.

LTRIM(<. char exp >)


This function returns the specified character expression with all
leading blanks removed.

PROPER(< char exp >)


This function returns the specified character expression with the
initial letter of each word converted to uppercase and the other letters
converted to lowercase. It does not affect non-alphabetic characters.

RECNO([< alias >])


This function returns the record number of the current record (the
record where the pointer is located).
By default, this function applies to the database file open in the
currently selected work area, but the <alias > option lets you specify
another work area, by using the letter or number of the work area or
the name or alias of the hie open there.
If the database hie has no records in it, or if you attempt to place
the pointer before the hrst record, RECNO( ) returns 1. You can dis¬
tinguish the hrst from a hie where the pointer is on record number 1,
because EOF( ) returns .T., and the second from a hie where the
pointer is on record number 1, because BOF( ) returns .T.
The option RECNO(O) can be used in combination with a SEEK
command. If the SEEK is unsuccessful, RECNO(O) returns the num¬
ber of the record that comes closest to matching, or, if no record
comes close to matching, returns 0. .

SOUNDEX(< char exp >;


This function returns a four-character string that is considered a
phonetic representation of the character expression. By comparing
the SOUNDEX( ) of a character expression that the user enters
to the SOUNDEXQ of the contents of your database, you can hnd
data that sounds similar to what the user enters, even if ( ) the spell¬
ing is totally different. The user can enter a name beginning with
a K, for example, and still find the record for a person whose
name begins with Q. For faster searches, you can index on the
SOUNDEX( ) of some field and then SEEK the SOUNDEX( ) of
the user’s entry.

SPACE(< num exp >)


This function returns a character string made up of a number of
blank spaces equal to the numeric expression specified. The maxi¬
mum length of this string is 65,504 spaces.

ST/?(<num expl > /,<num exp2 > [, <num exp3 >]])


This function returns the value of the numeric expression that is
specified as a character string.
The optional <num exp2> specifies the length of the string that is
returned. If the length you specify is longer than you need, the string
is padded with leading spaces. If the length is shorter than you need
to hold the integer value, the function returns a series of asterisks to
indicate an error.
The optional <num exp3> specifies the number of decimal places
that will be included. Any decimal places beyond the number speci¬
fied are simply truncated.

SUBSTR(<char exp>, <num expl >/, <num exp2 >])


This function returns a substring of the specified character expres¬
sion that begins with the character indicated by the first numeric
expression. If the optional second numeric expression is included, it
determines the length of the substring; if it is not included, the sub¬
string continues to the end of the original string.

TRIM( < char exp > J

This function returns the specified character expression with trail¬


ing blanks removed.
ESSENTIAL COMMANDS AND FUNCTIONS 619

UPPER( < char exp >)


This function returns the specified character expression with all
alphabetic characters capitalized. Non-alphabetic characters are not
affected.

VAL(< char exp >)


This function returns the specified character expression in the
numeric data type, so it can be used in calculations. It reads the char¬
acter expression from left to right, ignoring leading blanks, and con¬
tinues to read it until it reaches a character that is not numeric: thus,
it returns the value of the number to the left of any non-numeric
character in the expression. If the first character of the expression,
apart from leading blanks, is non-numeric, it returns 0.
Index

SYMBOLS @ . . . CLEAR command, 400, 561


@ . . . GET command, 400
; (semicolon)
@ . . . SAY command, 439, 400
to avoid blank lines in labels, 247
for menu program, 430
to read two program lines as one, 383
output of, 602
! (exclamation mark), in templates, 397
@ . . . SAY . . . GET command, 394-395, 484, 488,
! (not) symbol, 167, 170
492, 558-561
? (question mark) command, 124, 384, 385-386,
RANGE and PICTURE clauses in, 396-397
556-557
- (subtraction) operator, 135
? (question mark) wild-card characters, 204
\ (backslash) symbol, for root directory, 58
?? command, 386, 556-557
??? command, 386, 558
. . . (ellipsis) A
in commands, 386, 401, 557
in menu options, 8 abstract, title band as, 223
() (grouping) operator, 135-136 ACCEPT command, 391, 392, 562
/ (division) operator, 135 activation key, 515
$ (dollar sign) Add Line (Report menu), 234
as included-in operator, 190 adding records, 76
for substring search, 168 ADVANCED template, 335
in templates, 397, 399 alerts, 33, 69, 139, 384
+ (addition) operator, 135 blank fields and, 456
* (asterisk) color for, 328
in templates, 397 ALIAS, 264, 342
as wild-card character, 204 in File View, 351, 352
* (asterisk) command, 383, 556 in Fox View, 347
* (multiplication) operator, 135 in USE command, 613
** (exponentiation) operator, 135 ALL scope, 200, 325
~ (exponentiation) operator, 135, 399 for Replace, 325
(Ctrl-Z), as end-of-file mark, 474 ALLTRIMQ function, 129, 614
< < > > (double angle brackets), for default settings, alphabetizing, index for, 115, 141-148
19 Alt key, to move cursor to menu bar, 9
< > (not equal to) symbol, 167 Alternate, in Files panel, 286
= (equal sign) operator, 166-167, 403 American Standard Code for Information Interchange,
= = operator, 284
121-122. See also ASCII
vs. = symbol, 169 ampersand (&) function, 614
- > (arrow operator), 264, 265 ampersands (&&) command, 383, 556
> > sign, 83-84, 85
.AND. operator, 170, 171-172
* (not equal to) symbol, 167 angle brackets, 340, 555-556
* (pound sign), in templates, 397
double (< < > >), for default settings, 19
& (ampersand) function, 614 Answer file, 183
&& (ampersands) command, 383, 556
APPEND BLANK command, 94, 483, 485, 487, 562
@ (at sign), function with, 355
APPEND command, 342, 562-563
@ . . . BOX command, 561
vs. Browse or Change, 84
INDEX 621

Append File, in FoxView, 348 and marked text, 27


APPEND FROM command, 314-316, 563-564 ,BAK file name extensions, 71, 313
Append option (Record menu), 14, 80-90 bands in report layout window, 216
appending data, with Browse display, 88-90 adding lines to, 234
application generation, 333, 367-371 for groups, 238
author and copyright notice for, 349 BASIC programming language, 379, 380
main menu in, 429-433 .BAT files, running, 343
applications, naming, 370 beep, 386
APPS1 template, 335 adjusting pitch and length of, 289
arithmetic operators, 135 on errors, 430
arrays ®p&C>C&7>L,8£ CPU for full data-entry field, 83, 85, 492
creating, 575-576, 577-578 turning off, 285
global variables in, 594 BETWEEN() function, 614
arrow operator ( ->), 264, 265 blank lines
artificial intelligence, 382 avoiding in labels, 247
ASC() function, 132 printing, 386
ASCII characters blank records, 83
extended, 550 saving, 93
printing, 386 blank spaces
ASCII chart (System menu), 551-552 character string of, 618
ASCII format, for date, 49 initializing memory variables with, 484
ASCII order, for indexes, 121-122 in program code, 383
ASCII text files removing, 114, 129, 614, 617, 618
creating, 107 Blink check box, 328
programs as, 382 BOF() function, 614
saving report output to, 206 Bottom, in Goto dialog box, 104
Ashton-Tate, xxiii-xxiv bottom margin, 220
assembly language, 379 Box (Report menu), 224
assignment, 403 Box dialog box,, 224-225
asterisk (*) Box String, in FoxView, 350
for program comments, 383, 556 boxes, 561
in templates, 397 adding to reports, 210, 217, 237
as wild-card characters, 204 command for, 400
AT clause, in ? command, 557 in data-entry screen, 362
Attr (Filer utility), 534-535 default settings for, 350
attributes, of files, 524-525 expanding vertically, 226
author, for generated programs, 349 brackets
Auto Indent (Preferences dialog box), 313 angle (<>), 340, 555-556
AUTOEXEC.BAT file, 514, 518-520 curly ({}), 123, 558
average, 232, 320-321, 323, 564, 567 double angle (< < >>), 19
AVG() function, 323, 567 BROWSE command, 564-567
with related files, 259
BROWSE FIELDS command, for related files 5

272-273
BROWSE LAST command, 94, 110, 565
backup copies, 283 Browse menu, 13, 79, 92, 94-99, 119
attribute for, 534 Goto option, 99
automatic during structure modification, 592 Grid On option, 96
backslash (\) symbol, for root directory, 58 Seek option, 99
Backspace, 25 Toggle Delete option, 99
Browse window, 78, 79, 269 converting to upper or lower case, 127

appending data with, 88-90 special, 549-551

color for, 328 Chdir (Filer utility), 539

danger to key fields in, 282 check box, 19, 20


NOEDIT option, 109 child directory, 58, 524
CHRQ function, 132-133, 561
vs. Append, 84
buffer for keyboard, 289, 607-608 CLEAR ALL command, 570
I cl
c
p*v 7 ^
bullets, to mark records for deletion, 99 CLEAR command, 30, 33, 66, 385, 432, 570
CLEAR FIELDS command, 570
Clear option (Edit menu), 308
C Clear option (Window menu), 16
Calc column, in Table View, 356 clipboard, capturing text for, 552
CALCULATE command, 567-568 clock, adjusting, 288-289
calculations, with memory variables, 318-325 CLOSE command, 571
calculator, 544-547 Close option (File menu), 11, 63, 90
Calendar/Diary, 547-549 closing database file, 41
cancel, user option to, 447 closing windows
Cancel (Program menu), 498 and cursor position, 91
capitalization, 617, 619 with keyboard, 25
changing, 114 and saving changes, 81, 90
converting to, 127-128 vs. closing database, 90
in data entry, 363 CLS, in Shell, 341
in Find operation, 309 CMONTHQ function, 132, 615
in programs, 388, 431 CNT() function, 323, 567
with PROPER() function, 238 COBOL programming language, 379
Capture utility (System menu), 552 Codd, E.F., xxii
caret (A), for exponentiation, 135, 399 COLOR, for @ . . . GET . . . SAY command,
case differences, in searches, 84 560-561 @/Wrg
CD (Change directory), 59 colors, 327-328
CDAY() function, 132 columns
CDOW() function, 132, 615 for expression display, 557
centering objects, 234 in quick report, 235
central processing unit, 379 Tab to move between, 52
century, setting display of, 288 .COM files, running, 343
.CFG file name extensions, 344 comma-delimited files, adding records from, 316
CHANGE command, 568-569 command history, 340
vs. Append, 84 Command window, 5, 6, 7, 23, 29-32, 62
vs. EDIT command, 91 copying file structure in, 66
Change mode, 93 creating indexes from, 121
appending data with, 82-88 creating labels from, 244
for editing records, 80 database file creation with, 40
to view data, 78 editing commands in, 12
Change option (Record menu), 14, 79, 90-94 filters from, 196
character constants, in expressions, 123 FoxView in, 336
Character data type, 48, 227, 228 to manipulate files, 43
converting date data to, 130
producing report from, 215
converting to numeric data, 129-130, 619
shortcuts using, 106-110
characters. See also strings
commands, 556-613. See also specific commands
case of, and alphabetizing, 142
abbreviating, 67, 107
changing to lower case, 617
copying from Help window, 35-37
INDEX 623

editing, 31-32 Ctrl-cornbination keys, 26


file-management, 555 Ctrl-Z Sensitive (Preferences dialog box), 313
for related files, 259 curly brackets ({}), 123, 558
in macros, 301 currency, setting display of, 288
reentering in Fox View, 340 current macro, 303
comments, 376, 383-384, 475, 497 cursor, 7
commercial program development, 422 placement for input/output, 394
COMPILE command, 571 position after closing window, 91
compiling, xxiv, 366, 368 cursor movement, 26
automatic, 313 with Goto Line, 308
compression, of files, 516 cut and paste operation (Edit menu), 28
computed fields, 230-232 Cycle option (Window menu), 22
computer programming, 378-417. See also structured
programming
concatenation of strings, 137-138
CONFIG utility, in FoxView, 344
D
Console Off radio button, 215 data
constants grouping in reports, 210
blank space as, 138 preventing changes in, 109
in expressions, 123-124 data entry
CONTINUE command, 162, 178, 194, 445, 572 accepting default values in, 492
control characters, 121 appending and editing by user, 420-421
search for, 309 and danger of modifying key fields, 282
control flow, 381, 401-416 including instructions for, 361-362
selection for, 407-412 invalid, 85
Trace window and, 499 limiting values for, 356
Control-key shortcuts, 7 to memo field, 86-87
controlling files, 266, 281 to related fields, errors in, 275
controls, in dialog boxes, 17-19 repetitive, 600
Copy (Filer utility), 529-531, 540 upper or lower case in, 433
copy and paste operation (Edit menu), 28 data-entry form, 488
COPY command, 464 customizing, 333
query with, 169 generating in FoxView, 356-367
in Shell, 341 layout of, 357-362
COPY FILE command, 572 setting up, 353
COPY STRUCTURE command, 188-189, 572 template for, 335
Copy To (Database menu), 187 Data Grouping (Report menu), 221-223
COPY TO command, 572-573 data integrity, 486
copyright, 349, 429 data manipulation, 314-327
count data security, 471, 484
of fields, 231 data types, 48-51, 226-227
of number of records, 567 consistency of, in functions, 138-140
Count (Database menu), 321-322 converting, 114-115, 129-131
COUNT command, 573-574 defaults for, 47
cover letter, title band as, 223 and GET clause, 394
CREATE, in FoxView, 342 menu for names of, 53
CREATE command, 44, 574 and queries, 189-192
CREATE LABEL command, 244, 574-575 relational operators and, 167
CREATE REPORT command, 212, 575 selecting, 40
CREATE VIEW command, 575 and sorting, 51
CTOC() function, 130 of user input, 390
B&r<e P0f? fits* C0#m? fo foxm P&p r'ff
4 pg,frse tv/rff fo* Oyps WrrO v/A
data validation, 333, 355, 363-364 dBASE
database files indexes from, 121 ^ ' 'A? /

active, and screen appearance, 62


adding data to, 562 as standard, xxv

from another file, 295, 315 dBASE II, xxiii-xxiv

backup of, 71-72 dBASE III, 417


closing, 41, 62-65 memory variables in, 477

vs. closing windows, 90 .DBF file name extensions, 44, 50, 71, 82, 342

creating, 40, 42-92, 52-56, 342 .DBT file name extensions, 50

editing, 12 debugging, 15, 381, 387, 388, 390, 607. See also Trace

form modification and, 359 window


installing samples, 517 DEC, in Structure dialog box, 45
looping through, 406-407 decimals
in programming analysis, 423 on calculator, 547 p) y.,., PtCfOtiB
opening, 41, 62-65, 612 changing, 137
relational, 258 number of spaces for, 45, 47-48, 55
save process for, 41, 56-62 DECLARE command, 575-576
structure of, 41, 42, 574 DEFAULT, for GET clause, 560
View window to set relation between, 265-270 default settings
viewing, 76, 78-80 angle brackets to indicate, 19
Database menu, 13, 16 for boxes, 350
Append From, 314-316 for calculator, 546-547
Average, 320-321 for configuring Fox View, 348
Browse option, 119 for data type width, 53
Calculate, 323-325 for data types, 47
Copy To, 187 for drive in Files panel, 285
Count, 321-322 for environment variables, 430-431
Pack option, 102 for labels, 250
Reindex option, 150-151, 151-153 for macros, 294, 298, 304
Setup option, 68, 151, 194 for Page Length, 218
Sort option, 156 for Preferences, 311
Sum, 322-323 for scope of DELETE, 200
Total, 316-318 for variable value, 394
Database screen, in File View, 351, 352 default values, accepting in data entry, 492
databases DEFAULT.FKY file, 298, 304
advantages of, xxi DEL (DOS command), 72
defining, xix-xxiii Del key, 25, 27
date constants, in expressions, 123 delaying loops, 404, 499
date data type, 49, 227, 229 Delete (Filer utility), 532-533, 542-543
converting to character data, 130 DELETE ALL command, 201
Date Delimiter, changing, 288 DELETE command, 577
DATEQ function, 126, 131, 615 default scope for, 200
Date menu, in expression dialog box, 124 pointer and, 103
date operators, 137 Delete dialog box, 101
dates
DELETE FILE command, 577
functions for, 115
Delete option (Record menu), 100, 102
selecting format, 287-288 Deleted check box, 283-284
year display in, 601 deleted records
DAY() function, 131,615 packing and, 102

OlZf-tNE F&POp - l Ocff££ /AJ


INDEX 625

in problem analysis, 424-425 DO CASE . . . ENDCASE command, 377, 407,


and queries, 192-193 411-412, 430, 439, 581
DELETEDQ function, 193, 615 DO command, 369, 473, 580-581
deletion with IF/ELSE statement, 409
and calculations, 321 in program, 416
of fields, 46, 69 to run program, 384
of files, 72, 584 Do option (Program menu), 15
of objects, 217, 218 Do Program File dialog box, 388
of records, 77, 99-103 DO WHILE loop, 401, 430, 494, 581-582
T)PUmrrgz> delimited text files nesting, 404-406
w-'tH j appending data from, 315-316, 563 DO WHILE .T. loop, 490
—- /?r> rJ/n-r , copying data to, 464, 573 DO WITH command, 478
delimiters dollar sign ($)
for constants in expressions, 123 for substring search, 168
for date, 288 in templates, 397, 399
dot, 166, 170 DOS batch file, for running program, 500
demo version, 515 DOS commands
descending order, indexes in, 149-150 CD (Change directory), 59
desktop utilities, 544-552 DEL, 72
detail band, in report layout window, 216 directory for, 58
dialog boxes, 17-22. See also specific types MD (Make Directory), 59
cancelling, 21 RD (Remove Directory), 59
color for, 328 running, 598
controls for, 4, 17-19 within FoxPro, 30
exiting from, 20-22 DOS directory structure, 57-59
FOR and WHILE check boxes in, 174 DOS end-of-file marker, in .PRG file, 474
indicator for, 8 DOS operating system
moving, 20, 21-22 filer for functions of, 522
digitized sound, memo data type for, 49 FoxView Shell and, 337
DIMENSION command, 577-578 running programs from, 500
DIR (Directory) command, 341, 579 temporary exit to, 346
directories unexpected return to, 514
changing, 82, 341, 539, 601 DOS prompt, 346
copying files to, 530 DOS subdirectories, 41
in DOS, 57-59 creating, 43
Filer for moving among, 524-525 DOS text files, creating, 107
for FoxPro, 514, 515-516 dot delimiters, 166, 170
parent and child, 58, 524 dot prompt, xxiv
removing, 542 DOW() function, 131
structure of, and Tree panel, 537 drives, changing, 525, 601
tagging, 538 DTOC() function, 130, 615
disk letter, in directory list, 58 dummy memory variable, 390
Disk menu, in FoxView, 345-346 duplicate values, printing once, 232
disk space
display of, 344 E
field width and, 49 Echo (Program menu), 498-499
DISPLAY command, 106, 107, 579-580 Edit (Filer utility), 534
default scope for, 200-201 EDIT command, 582-583
DISPLAY STRUCTURE command, 63 vs. CHANGE command, 91
Edit menu, 12-13, 28-29, 308-314 exiting FoxPro, 72
exporting data, 316
Paste option, and special characters, 550
for mail merge, 464-466
editing
memo field, 92 to text files, 421
Expr text button, for expression builder, 143
objects, 217
expression builder, 122, 142-143, 145
partitioned windows and, 97
saving changes from, 81 for calculations, 323
LOCATE FOR command and, 178
editor, 25-29
advanced techniques in, 304-314 logical functions and operators in, 166

macros for customizing, 297 problems with, 148


EJECT utility, in Fox View, 344 and related files, 270
ellipsis (...) and report layout window, 226
in commands, 386, 401, 557 for Seek, 182
in menu options, 8 expressions, 117, 121-141
End key, 26 checking validity of, 144
End of File() function, 166 creating, 114
ENDCASE statement, 581 elements of, 123
ENDDO statement, 401 evaluation and display of, 556
entry. See data entry for grouping, 222
environment, 420, 608 in indexes, 141-150
for mailing labels, 244, 588 in labels, 247
for report, 213, 214, 597 modifying for index, 155
in report menu generation, 451 overlapping, 234
settings for, 283-290, 429 extended ASCII, 122
default, 430-431
saving, 243
View window to control, 260
F
EOF() function, 166, 445, 616 Field (Report menu), 226
in DO WHILE loop, 406 field expressions
equal sign ( =), 166-167, 403 in labels, 211
ERASE command, 341, 584 in report bands, 216
error messages, on variables not located, 123 in reports, 211
Esc key, 32-33 field labels, in data-entry form, 358
to cancel dialog box, 21 field names, 46-47
to close window, 25 entering, 52
disabling, 34 in expressions, 123
to interrupt printing, 215 as variables, 318
to return to menus, 10 Field options, for sort, 156-157
to stop program, 384 field picker, in Sort dialog box, 156
European format for date, 49 fields, xix
Exact, and SEEK command, 284 adding from other databases, 347
exclamation mark (!)
in Append window, 83
as NOT symbol, 167, 170
centering on label forms, 456
in templates, 397 computed, 230-232
.EXE file, running, 343
deleting from Forms View, 359
EXIT command, 413-416, 433, 584
displaying specific, 106
in FOR command, 585
in EDIT command, 583
in FoxView, 344
formatting, 226-230
Exit to DOS, in FoxView menu, 346
index based on single, 117
INDEX 627

inserting or deleting, 46, 69 Mkdir, 539


key, 261, 262, 273 Move, 531-532, 540-541
moving, 69 Rename, 535-536
from multiple files, 258 Size, 543
naming, 40 Sort, 533-534
necessity of, 52 tagging files in, 525-527
new data in, 596 files, xx
in quick report, 235 attributes of, 524-525, 534
rearranging, 77 beginning of, 614
replacing value of, 295 closing, 571
in report bands, 216 compressed, 516
resizing and changing order of, 95 controlling, 266
selecting from Browse menu, 94 copying, 572
type style for, 230 creating program or text, 305-306
user access to, 603 deleting, 72, 341,584
as variable, 385 determining which are open, 63
vertical lines separating, 99 eliminating all records from, 103
width of, 40, 49 filer utility for moving among, 524-525
Fields check box hidden, 535
for queries, 199 modification of, and lost data, 70-71
for relation, 277-280 moving through, 77, 81
FIELDS clause opening multiple, 258, 263
in APPEND FROM command, 563 overwriting, 341, 531
in BROWSE command, 566 printing, 306-308
in CHANGE command, 570 Read Only, 534
in COPY command, 573 renaming, 342
in DISPLAY command, 580 restricting user access to, 181
in LIST command, 589 saving changes to, 76
to restrict commands, 202-204 screen display of, 342
Fields menu (FoxView), 349-350 sending reports to, 242
fifth-generation languages, 382 setting relation between, 258-259
file-management commands, 555 sorting fields from multiple, 157
File menu, 10-12, 16 tagging in filer utility, 525-527
Close option, 63, 90 temporary, 31, 523
new index from, 143 Files (Filer utility), 543
New option, 10-11, 43-44, 212 Files Like text box, 525
Open option, 62, 82, 236 Files panel (View window), 285-287
file name extensions. See specific extensions Fill Char, in FoxView, 349
file names. See also ALIAS filter, 169, 194-196, 604
for indexes, 117 Find (Edit tnenu), 309-310
new, 595 Find (Filer utility), 527-529
File panel (Filer), 522, 523-537 Find Again (Edit menu), 310
File View (FoxView), 332, 336, 351-352 FIND command, 584
Filer utility, 43, 522-543 .FKY file name extensions, 303
Chdir, 539 flags, display of, 344
Copy, 529-531, 540 Float As Band Stretches box, 226, 233
Delete, 532-533, 542-543 float data type, 48
Edit, 534 .FMT file name extensions, 343, 357, 396, 437, 571,
Find, 527-529 604
for moving among directories and files, 524-525 fonts, proportional, 206
footers FoxGraph, 15

for data group, 221 FOXHELP.DBF file, 287

group, 239 FoxPro


for page, 240 Commands and Functions manual, 501, 554

in report layout window, 216 DOS commands within, 30

totals in, 232 exiting, 72


For check box, 174 hard disk requirements for, 514

for Delete, 100 installing, 514-520

in Index dialog box, 196 licensing agreement for, 515

to limit records averaged, 321 menu structure for, 6-17

in Replace, 326 programming language with, xxvi

FOR clause, 162, 174, 175-176 quitting, 5, 37, 594


in APPEND FROM command, 563 as standard, xxvi
in CALCULATE command, 568 starting, 7, 43
in CHANGE command, 570 unexpected return to DOS, 514
in commands, 163 FOXUSER.DBF file, 287
in COPY command, 573 Fox View, 15
in DISPLAY command, 580 basics of, 336-356
in EDIT command, 583 default configuration for, 348
in INDEX ON command, 587 Gen menu, 348-349, 368
in LA.BEL FORM command, 588 generating data-entry form in, 356-367
in LIST command, 204-206, 589 installing, 517
in queries, 194 interface for, 336-337
in REPLACE command, 596 Load menu, 347-348
in REPORT FORM command, 215 utilities for, 344-345
in SUM command, 611 Fox View code generator, 334-336
for unindexed multi-record queries, 184-185 Fox View screen generator, 430
vs. WHILE clause, 176 FoxView Shell, 332, 337-345
FOR command, 584-585 FOXVIEW.CFG file, 344
For text button, in Index On dialog box, 120 .FPT file name extensions, 50, 71
Form layout, in quick report, 235 .FPX file name extensions, 571
Form radio button, 305 FREEZE, in BROWSE command, 566
FORMAT, in BROWSE command, 566 .FRM file name extensions, 214
format files, 604 .FRV file name extensions, 213, 214
need to close, 440 .FRX file name extensions, 213, 575, 597
format programs, 396 full field, and beeps, 83, 85, 492
format templates. See templates FUNCTION clause
formatted input/output, 376, 385, 394-400, 558 in ? command, 557
forms, xx in @ . . . GET . . . SAY command, 559
modifying, 454
FUNCTION command, 470, 480, 585
for reports, 212, 214, 575 function keys
Forms View (FoxView), 332, 337, 353-356
default macro values for, 298
FORMS1 template, 335
macro assignment to, 297
FOUNDQ function, 616
to move to menu bar, 9
fourth-generation languages, 382, 386
function symbols, 397-399
Fox Software, xxv
function templates, 355
FoxBase, xxv
functions, 125-134, 614-619
FoxBind utility, 474
for calculations, 323-325
FoxCode, 334
in expressions, 124
FoxDoc, 15
in FoxPro calculator, 545
INDEX 629

within function, 133-134 high-level language, 379-380


Help window for, 148 Highest, of field values, 232
logical, 166 home directory, 515
numeric calculations in, 115 Home key, 26
user-defined, 471, 480-483 hot keys, 21, 24, 69
.FV file name extensions, 365

I
G
IBMBIO.COM file, 535
Gen menu (FoxView), 348-349, 368 IBMDOS.COM file, 535
GET command, 394, 433 .IDX file name extensions, 121, 587
global variables, 594 IF command, 377, 586
GO BOTTOM command, 445 IF ELSE ladder, 411-412
GO command, 586 IF . . . ELSE . . . ENDIF command, 408-410, 448
GOTO command, 105, 380, 586 combined with DO loop, 409
Goto Line (Edit menu), 308 IF .NOT. EOF() STATEMENT, 491
Goto option, 99, 103 IIF() (immediate if) function, 616
Grid On] Off option, 96, 99 IMPORT, in FoxView, 342-343
group bands, 238 Import Format, in FoxView, 348
group footer, 239 importing data, 314-316
group header, as page header, 222 included-in operator ($), 190
Group text button, 222 indentation in program code, 383, 450
grouped data for DO WHILE loop, 402
calculations for each, 232 of nested loops, 406
with header and footer, 216 INDEX ON command, 587
grouping macros in sets, 303 Index On dialog box, 117
groups of files, tagging, 526 INDEX option, in USE command, 613
Index radio button, 236
indexes, 173-176
H
advantages of, 116
hard disk, FoxPro space needs on, 514 alphabetizing by name, 141-148
headers changing, 605
for data group, 221 creating, 114, 236, 587
for pages, 237 for data groupings, 223
in report layout window, 216 in descending order, 149-150
Heading option, for printing, 215 expressions in, 141-150
help file name for, 117
adding on-screen, 362 on key field, 265
for FoxView, 337, 355 listing, 343
installing files for, 517 main, 174, 182, 425, 427, 605
specifying file for, 287 maintaining, 150-156
HELP command, 586 maintaining multiple, 115
Help window, 34-37 for multi-record queries, 185-187
for commands using scope clause, 200 opening, 144-145, 604-605
for functions, 148 opening multiple, 150-151
in Shell, 337 overwriting, 147
hidden files, 535 programming analysis and, 423, 425
hidden windows, 22 queries using, 162, 181-183
Hide All option (Window menu), 23 query built into, 169, 196-199
Hide option (Window menu), 16 rebuilding, 595
630 MASTERING FOXPRO

for relational database files, 269 label layout window, 246-247


for reports, 212 labels. See also mailing labels
simple, 116-121 for fields in data-entry form, 358
and TOTAL command, 316, 611 LAST, in BROWSE command, 566
infinite loops, 401-402, 582 .LBV file name extensions, 243
deliberate, 413-414, 432 .LBX file name extensions, 244, 575, 588
Init column, in Table View, 356 leading blanks, 129
INITCAP() function, 481 left margin, 220
input, 387 LENQ function, 496, 616
command to get, 562 libraries of functions and procedures, 473, 493
formatted, 376, 394-400, 558 and scope of memory variables, 477
programming for, 384-400 licensing agreement, 515
unformatted, 385-393 Line Feeds (Preferences dialog box), 313
validating, 560 Line Numbers check box, 308
Input box, for sort, 157 lines
INPUT command, 390, 587 adding, 224
Ins key, 25 per page, 218
Insert Pause text button (macros), 302 in report bands, 217
inserting fields, 46, 69 linked partitions, 96-99
installation of FoxPro, 514-520 LIST command, 106, 107, 163, 589
instruction set, of central processing unit, 379 default scope for, 200-201
interpreted programming language, xxiv-xxv with FOR clause, 204-206
Invert option, in tagging files, 526 in FoxView, 343
iteration control flow, 381 OFF with, 205
LIST HISTORY command, 340

J LIST STATUS, in FoxView, 344


LIST TO FILE command, 107, 206
justification, 239-240, 313 literals, 123. See also constants
in templates, 229
K LOAD
in FoxView, 343
key fields, 261, 262, 273 in IMPORT, 343
danger in modifying, 282
Load menu (FoxView), 347-348
index on, 265
Load Table, in FoxView, 347
and TOTAL command, 611
LOCATE ALL command, 179
keyboard, menu selection with, 4, 9
LOCATE command, 194, 445
keyboard buffer, size of, 289, 607-608
LOCATE FOR command, 162, 177-181, 589-590
Keyboard Macros dialog box, Restore, 304
Logical data type, 48-49, 227, 229
logical expressions, 162
L order of precedence for, 172-173
parentheses for complex, 172
Label dialog box, 245
in query, 165-173
LABEL FORM command, 451, 588
logical fields, 55, 190
label forms, 211, 243, 456-459
logical functions, 126, 166
creating, 574-575
logical operators, 170-173
default, 460-462
Logical menu, 124, 179
fitting fields in, 421, 455-456
Look For text box, 309
modifying, 591
LOOKUP program module, 437, 440-442, 445-450
saving, 250
LOOP command, 413-416, 449, 590
standard, 246
in FOR command, 585
INDEX 631

loops, 377, 381, 401-407, 582. See also infinite loop main menu, 7
delaying, 404 in application generation, 429-433
DO WHILE, 494 in structure diagram, 425
DO WHILE .T., 490 main module of program, 475
LOWEF.() function, 127, 617 Make Backup (Preferences dialog box), 313
lowercase characters, converting, 127 many-to-many relationship, 262
Lowest, of field values, 232 MAP
LTRIMQ function, 129, 140, 239, 617 in Fox View, 343
in IMPORT, 343
MAP Datafile, in Fox View, 347
M margins
machine language, 379 left and right, 220
macro substitution function, 614 and printed lines per page, 218
macros, 297-304 top and bottom, 220
clearing, 304 master index, 605. See also main index
creating, 294, 298-303 Match Words check box, in Find, 529
current vs. saved, 303-304 Math menu, in expression dialog box, 124
default settings for, 298 MAX() function, 323, 567
grouping in sets, 303 MD (Make directory), 59, 341
maximum keystrokes in, 297 memo data type, 49
saving, 294 memo fields, 81
mail-merge, exporting for, 464-466 changing, 76
Mail Power! program data entry to, 86-87
data exporting module for, 465-466 editing, 92
data submenu for, 437-450 inability to sort on, 156
database file structure for, 435 as separate file, 50
GETDATA procedure for, 489-490 substring search in, 190
label menu for, 459-464 width of, 55
LOOKUP module for, 445-450 memo window
main menu, 431-432 closing and saving, 81
preliminary testing of, 444 opening for edit, 591
report menu for, 451-459 memory variables, 349, 385, 492
screen format for, 442 calculations with, 295, 318-325
SCRNHEAD, 478-480 creating, 562
structured form of, 502-511 in dBASE III, 477
mailing label program. See also Mail Power! program in expressions, 123
mailing labels, 211, 243-251, 421. See also label forms and FOR command, 585
avoiding blank lines in, 247 private, 593
creating, 588 public, 594
default settings for, 250 STORE command and, 610
deleting blanks from, 129 for user input, 387, 483-492
field expressions in, 211 memory, of calculator, 546
programming for, 450-464 menu bar, 7
using related files, 281 color for, 328
mailing list application, creating, 422-466 moving to, 9
main index, 427, 605 Report menu pad in, 213
determining, 425 menu-driven applications, creating, 367
and Seek, 182 menu structure, 6-17
WHILE clause to search with, 174 menu style, 368
632 MASTERING FOXPRO

menu system, 332 N


creating, 420
in FoxView, 336, 345-351 names
seek using, 182 of fields, 40, 46-47

menus, 6, 7, 8 of files, 117, 595. See also ALIAS

color for, 328 .NDX file name extensions, 121

control in, 18-19, 20, 21 Near, and SEEK command, 284

to create database file, 40 nesting, DO WHILE loops, 404-406

mouse for selecting, 4 net present value, 324, 567-568


returning to from options, 10 NEW, in FoxView, 343
selecting from, 8-10 New Config, in FoxView, 348
messages, 607 new files
system, 70 copying structure for, 66
to users, 441 creating, 43
MIN() function, 324, 567 new line, as program command delimiter, 382
Misc panel (View window), 287-289 New option (File menu), 10-11, 43-44, 212
Mkdir (Filer utility), 539 NEXT, in scope clause, 200
modified files No Eject printing option, 215
attribute for, 534 NOAPPEND, 566, 569, 583
and lost data, 70-71 NOCLEAR, 566, 569, 583
MODIFY FILE command, 305, 590-591 NODELETE, 566, 569, 583
MODIFY LABEL command, 591 NOEDIT, 109, 566, 569, 583
MODIFY MEMO command, 591 NOFOLLOW, 566, 569, 583
MODIFY REPORT command, 591-592 NOMENU, 566, 569, 583
MODIFY STRUCTURE command, 592 NORMAL, in BROWSE command, 566
Modify text button, 155 normalization of data, 261, 423
modules, 369, 381, 416, 473 “not equal to” symbols, 167
combining in single file, 470 .NOT. operator, 170, 172
determining need for, 426 NOTE command, 383, 556
main, 475 NOWAIT, in BROWSE command, 566
main menu and, 425 NPV() function, 324, 567-568
passing values between, 470, 478 null character, 48
run-time, 500-501 number constants, in expressions, 124
testing, 434-437, 444 numeric calculations, in functions, 115
MONTFI() function, 131 Numeric data type, 48, 227, 228-229
mouse converting character data to, 129-130
to change field order, 95-96 converting to character, 130
to change window appearance, 5 numeric expression, as character string, 618
for dialog box, 20 numeric held, Width column of, 55
manipulating objects with, 217 NumLock key, and calculator, 546-547
marking text with, 26
menu selection with, 4, 8
for partitioning, 97
O
to rearrange fields, 77 objects
setting sensitivity of, 289 boxes or lines as, 226
tagging files with, 526 centering, 234
window controls for, 23-24
field expression as, 232
Move (Filer utility), 531-532, 540-541 in Form View, 353
multiple files, opening, 258, 263
line of text as, 233
INDEX 633

manipulation of, 217-218, 353 in functions, 126, 133


report layout components as, 217 unbalanced, 140
On/Off panel (View window), 283-285 partitioning windows, 96-99
one-to-many relationship, 262, 263, 265, 266 password procedure, 493-497
one-to-one relationship, 352 Paste option (Edit menu), and special characters, 550
Open Index File dialog box, 155, 269 path (Files panel), 285-286
Open option (File menu), 11, 62, 82, 236 PATH command, 341, 518-520
open windows, adding, 270 percent operator, in calculator, 545
opening periods (..), for parent directory, 59
database files, 41, 612 PICTURE clause, 396-397, 557
indexes, 144-145, 604-605 Picture column (FoxView), 355
multiple files, 258, 263 picture templates, 355, 363-364, 559
views, 277 symbols for, 397
operating system. See DOS operating system Plain printing, 215
operators, 134-140 PLAY MACRO command, 592-593
in expressions, 124 pointers, 91, 492
logical, 170-173 location after search, 605
relational, 166-170 moving, 103-106, 586, 608-609
.OR. operator, 170, 171-172 position of, and WHILE clause, 176
order of fields, 95 in related files, 266
order of precedence, for logical expressions, 172-173 pop-up menus. See menus
output pound sign (#), in templates, 397
formatted, 376, 394-400, 558 precedence of operations, 135
programming for, 384-400 PREFERENCE, in BROWSE command, 566
unformatted, 385-393 Preferences (Edit menu), 311-314
Output box, for sort, 157 .PRG file name extensions, 343, 357, 388, 396, 416,
overlapping expressions, 234 472, 474, 571, 590
overwriting files, 531 converting to procedures, 475
overwriting indexes, 147 printer
control codes for, 558
ejecting page from, 344
sending text to, 386, 558, 580, 605
P settings on, 284, 306-308
PACK command, 102, 193, 424, 441 Shell output to, 345
Pack option (Database menu), 102 Printer Indent, 220
page breaks, 107 printing
page ejection, from printer, 344 page preview before, 217
Page Layout (Report menu), 218-220 reports, 215, 242
page numbers, in reports, 452 suppression of duplicate values, 232
Page Preview, 217, 220, 240 PRIVATE command, 470, 477, 593
pages problem analysis, in programming, 423-429
footers for, 240 Procedure, in Files panel, 286
headers for, 237 PROCEDURE command, 470, 473, 474, 593-594
lines per, 218 procedures, 473. See also modules
new, group on, 222 in Command window, 29
PARAMETER command, 470, 478, 481, 490, 494, converting .PRG file to, 475
592 , fofTf many VfirR ‘f-is creating, 473-477
parent directory, 58, 524 SCRNHEAD, 478-480

parentheses separate file for, 470


in complex logical expressions, 172 vs. user-defined functions, 481
deleted records and, 192-193
program code
compiling, 313, 571 indexed, 162

creating, 305-306, 364-365, 376 multi-record, 185-187

creating or modifying, 590 single record, 181-183

display during running, 471, 498 logical expressions in, 165-173, 190

protecting, 501 for multiple records, 183-189

repeated execution of, 377 restricting, 199-206

selecting between two blocks of, 377 unindexed, 162

for user-defined functions, 481 multi-record, 184-185


Program menu, 15, 497-501 single record, 177-181
programming. See also structured programming question mark (? [??) command, 124, 384, 385-386,

analysis in, 420 556-557


control flow in, 401-416 question-mark (?) wild-card characters, 204
for input/output, 384-400 Quick Report (Report menu), 163, 234-235
problem analysis in, 423-429 QUIT command, 500, 594
stub testing in, 420 in FoxView, 344, 346
programming languages, 379, 380 placement in program, 433
in dBASE, xxiii quitting FoxPro, 5, 37, 594
with FoxPro, xxvi quotation marks, as character constant delimiters, 123
template, 334
programs
calling from within another program, 416
R
capitalization in, 431 radio buttons, 19, 20
control flow of, 380. See also control flow RANGE clause, in @ . . . SAY . . . GET command,
DO command for running, 384 396-397, 559-560
executing, 580-581 Range column, in Table View, 356
executing one line at a time, 607 RD (Remove directory), 59, 342
format, 396 READ command, 394-395, 594
from Fox View, 357 Read Only files, 534
interrupting, 602 Recall (Record menu), 77, 100-102
running, 15 scope for, 202
running in FoxView, 344 RECALL command, 99, 595
semicolon to read two lines as one, 383 RECNOQ function, 617
stopping, 384 RECOPvD, in scope clause, 200
Prompt Lines, in FoxView, 350 Record menu, 14-15, 16
PROPER() function, 127, 140, 238, 249, 617 Append option, 80-90
proportional fonts, 206 Continue option, 178
.PRX file name extensions, 571, 604 Delete option, 100, 102
pseudocode, 429 Page Preview, 220
pseudo-compiler, xxv Recall option, 77, 102
PUBLIC command, 477, 478, 594 Replace, 325-327
public-domain software, 335 Seek option, 182
record numbers, 103, 200
records, xx
adding, 76
Q adding from another file, 295, 314-316
queries, 169
blank, 83
building into indexes, 196-199
Change mode for viewing, 78
data types and, 189-192
creating new, 79-80
INDEX 635

editing, 80, 93 report layout window, 216-218


in Goto dialog box, 104 adding bands to, 210
indexed queries for single, 181-183 color for, 328
keeping track of current, 103 Report menu, 216, 218-235
look up module for, 421 Add Line, 234
number of current, 617 Box, 224
queries for multiple, 183-189 Data Grouping, 221-223
recovering deleted, 77 Field, 226
removing all, 613 Page Preview, 240
saving blank, 93 Remove Line, 234
screen display of, 579-580 Title/Summary, 223
search for, 162-163, 169, 584 Report radio button, 212
selecting for report inclusion, 214 reports, 212-243
unindexed queries for single, 177-181 adding boxes to, 210
viewing, 76 creating, 210, 236-243
records marked for deletion, 77, 99-103, 615 field expressions in, 211
commands and, 601-602 grouping data in, 210
and queries, 192-193 indexes for, 213
recall of, 595 modifying, 214, 591-592
Redo option (Edit menu), 29 page numbers in, 452
REINDEX command, 595 printing options for, 215
Reindex option (Database menu), 150-153 programming for, 450-464
relational databases, xxi, 261-283 quick, 163, 234-235
browsing related files in, 259, 272-277 sending to screen, printer or file, 242
creating, 258, 606-607 summary of, 240
reports using, 259, 280-281 Text in, 232-233
setting up, 263-272 user created, 421
structure for, 268 using relational databases, 259, 280-281
using, 272-283 Reset popup control (Total dialog box), 232
View window and, 260 resizing of objects, 217, 218
relational operators, 166-170 resource file, setting, 287
and data types, 167 REST, in scope clause, 200
Remove Line (Report menu), 234 Resume (Program menu), 498
Remove text button, 155 RETURN command, 416, 441, 471, 474, 481, 585,
REN (Rename), in Shell, 342 597-598
Rename (Filer utility), 535-536, 538-539 placement in program, 433
RENAME command, 595 RETURN TO MASTER command, 416
repetition, avoidance of, xxi-xxii Revert option (File menu), 12
Replace (Record menu), 325-327 right margin, 220
Replace All (Edit menu), 311 root directory, 58, 60
Replace and Find Again (Edit menu), 311 rounding errors, data type and, 48
REPLACE command, 484, 485, 596 RUN command, 30, 475, 598
Replace With text box, in Find, 310 in FoxView, 344
REPOl template, 335 Run Program, in FoxView menu, 346
Report Expression dialog box, 218, 238 run-time module, 500-501
REPORT FORM command, 215, 451, RUN utility, 43
596-597 running programs
report forms, 212, 214, 575 DO command for, 384
report generator, 335, 427 in FoxView, 344
screen display
s report on, 242

Sample check box, for printing labels, 245 saving, 344

sample databases, installing, 517 suppressing, 386

SAVCAP, in Fox View, 344 screen format module, 437

SAVE, in Fox View, 343 screen generator, 430, 442

Save As option (File menu), 11-12 screen output, saving to text file, 599

Save As text button, 157 scroll bar, 18, 24


Save option (File menu), 11 scrollable lists, 21
save process in dialog boxes, 18
for blank records, 93 with mouse, 20
for changes to file, 76 scrolling, 201
when closing window, 90 SDF files
for database file, 41, 56-62 appending data from, 316, 563
for editing changes, 81 copying data to, 464, 573
for label layouts, 250 search, 294
for macros, 294, 304 for control characters, 309
for tables, 365 with indexes, 174
for view, 276 for substring, 168-169
Save Report As dialog box, 241-243, 453 Search Subdirectories check box, 528
Save Table, in FoxView, 347 SEEK command, 163, 181, 284, 445, 448
Save View As dialog box, 276 for indexed search, 194
SAVTXT, in FoxView, 344 Seek option 99, 182
SAY clause, 394. See also @ . . . GET . . . SAY Select All option (Edit menu), 308
command Select Attribute, in FoxView, 350
SCAN command, 598 SELECT B command, 267
scanned images, memo data type for, 49 SELECT command, 264, 343, 599
Schemes, 328 Select From Template List, in FoxView, 368
scope Selecting Color (Window menu), 327
for CALCULATE command, 568 selecting text, 26
for CHANGE command, 570 selection control flow, 381, 407-412
of command, ALL as, 181 semicolon (;)
of COPY command, 573 to avoid blank lines in labels, 247
for DISPLAY command, 580 to read two program lines as one, 383
to limit records averaged, 321 sequence control flow, 381, 401
of queries, 200-202 SET, in commands, 283.See also commands, SET . .
for REPLACE command,, 596 Set Format dialog box, 366
of variables, 470, 477-480 Set Order text button, 155
Scope check box Set Resource To option, 287
for Delete, 100
sets, grouping macros in, 303
for queries, 199 Setup option (Database menu), 13, 68, 151, 194, 260
Scope clause, 177, 178 to manage indexes, 153-156
for LABEL FORM command, 588 Shadow check box, 328
for LIST command, 589 shareware, 335
for SUM command, 611 Shell, in FoxView, 336, 346
screen
Shift-combination keys, 26
clearing part of, 400, 561 Show All options (Window menu), 23
designing, 332 simple database, xix-xxi
location of messages on, 385
simple indexes, 116-121
output to, 601
SIMPLE template, 335
INDEX 637

Size (Filer utility), 536-537, 543 stub testing, 420, 434-437


size of fields, 95 of LOOKUP program, 442-444
size of windows, controlling, 24, 25 Style, in Text dialog box, 233
Skip, in Goto dialog box, 104 Style check box, 230
SKIP command, 445, 608-609 subdirectories, 57, 434
Sort (Database menu), 156-158 creating, 43, 341, 475, 539
Sort (Filer utility), 533-534 filer Tree panel for, 522
SORT command, 609-610 listing, 345
Sort Destination File dialog box, 157-158 moving between, 41
sort of database, for Total, 316 removing, 342, 542
SOUNDEXQ function, 617-618 searching in, 528
space bar submenu style, 368
to delete selected text, 27 subroutines, 473. See also modules
in dialog boxes, 21 SUBSTR() function, 454-456, 618
to tag utilities, 526 substrings, 618
SPACEQ function, 394, 496, 618 search for, 168-169, 190
spaces. See blank spaces Sum, of fields, 232
spaghetti code, 380 Sum (Database menu), 322-323
Special characters (System menu), 549-551 SUM command, 610-611
square brackets, for options, 555 SUM() function, 325, 568
square roots, 545 summary, 223
stand-alone applications, 500 printing, 215
standard deviation, 325, 568 of report, 240
starting FoxPro, 7, 43 in report form, 216
STD() function, 325, 568 Suppress Repeated Values check box, 232
Step (Program menu), 499 suppressing screen display, 386
STEP clause, in FOR command, 585 system clock, 288-289
Stop Recording dialog box (macros), 301 system data format file, exporting to, 464
stopping programs, 384 system date, 615
STORE command, 318, 610 system file, 525
STR() function, 130, 140, 238,319,618 system memory, display of, 344
string operators, 137-138 System menu, 10
String menus, 124, 178 ASCII chart, 551-552
strings, 391, 615 calculator, 544-547
comparison of, 168-170, 602-603 Calendar/Diary, 547-549
concatenation of, 137-138 Capture utility, 552
length of, 616 Special characters, 549-551
structure diagram, 423, 425-429 system messages, 33, 70
Structure dialog box, 44 system variables, 123
Structure menu, 46
structure of database, 42
breaking down data and, 51-52
T
copying and modifying, 66-72
defining, 45-52 Tab key, 20, 52
display of, 580 Tab Size box (Preferences), 313
modifying, 592 Table View (FoxView), 332, 353-356
for related databases, 268 editing screen in, 355
structured programming, 376, 378-382 in FoxView interface, 337
advanced techniques of, 473-483 toggle for, 361
features of, 381 tables, xx-xxi, 78
in Mail Power!, 502-511 saving, 365
638 MASTERING FOXPRO

Trace window, 471, 498, 499


tagged files, opening editing windows for, 534
SET STEP ON command and, 607
tagging directories, 538
trailing blanks, 129
Talk (Program menu), 498
Tree panel (Filer utility), 522, 537-543
“talk”, 33
TRIM() function, 129, 140, 618
adjusting, 289
and alphabetical indexes, 142
turning off and on, 34, 285, 607
shortcut for, 247
.TBK file name extensions, 71
two-dimensional arrays, 576
template language, 334
.TXT file name extensions, 591
templates, 335, 355, 483
TYPE command, 342, 612
for data types, 229
type style, for fields, 230
in FoxView, 348
typeahead option, 289
picture, 355, 363-364, 559
typeover mode, 26
symbols for, 230, 397
temporary files, 31, 523, 610
testing of program, 434, 444 U
stub, 434-437
text Undo option (Edit menu), 29
deletion of selected, 27 unformatted input/output, 384, 385-393
editing, 211, 232 UNIQUE, in INDEX ON command, 587
in reports, 232-233 Unique check box, in Index On dialog box, 120-121
searching files for specific, 528 UPPER() function, 125, 127, 142, 144, 145, 619
selecting, 26 uppercase characters, converting, 127
text box, 4, 19, 20, 21 USE command, 62, 67, 155, 612-613
text buttons, 19, 20 to close files, 63
TEXT . . . ENDTEXT command, 386, 611 in FoxView, 343, 348
text files in IMPORT, 343
creating, 305-306 user-defined functions, 480-483
display of, 612 passing values to, 471
exporting data to, 421 password procedure as, 493
sending display to, 286, 580 program file for, 481
third-generation languages, 380 user input, 387
thumb, 24 reading into memory variables, 483-492
title band, in report form, 216 WAIT command and, 613
title screen, program name and copyright on, 429 user windows, color for, 328
Title/Summary (Report menu), 223 users
titles input from, 587
adding box around, 237' restricting access to data, 181, 471, 483-492
in quick report, 235
TO ARRAY clause, in CALCULATE command, 568
TO clause, in AVERAGE command, 564
V
TO PRINT, in commands, 107, 386 VAL() function, 129-130, 619
Toggle Delete option (Browse menu), 99 VALID, for GET clause, 560
Top, in Goto dialog box, 104 Valid column, in Table View, 356
Top Margin, 220 validation of data, 363-364
Total dialog box, 230-231 value, returned by function, 125
TOTAL ON command, 317 VAR() function, 325, 568
TOTAL TO command, 611-612 variables
totals for database fields, 295, 316-318 database field names as, 318
in footers, 232 in GET clause, 394
INDEX 639

memory, 123 in REPORT FORM command, 215


passing value to module, 470, 478 problems with, 176
scope of, 470, 477-480 using SEEK before, 181
types of, 385 in SUM command, 611
variance, 325 WIDTH, in BROWSE command, 567
vertical line (|), for alternative, 555 wild-card characters, 204, 525
vertical lines separating fields, 99 in DIRECTORY command, 579
view Window menu, 15-16, 17, 267
creating, 258, 575 Command window from, 30
opening, 277 open window in, 270
saving, 276 Selecting Color, 327
VIEW FILE (FoxView), 343 window splitter, 97
VIEW FORMS (FoxView), 343 windows, 22-25
VIEW TABLE (FoxView), 343 adding open, 270
View window, 260, 266, 608 changing appearance of, 5
panels on, 283 clearing part of, 561
to set relation between database files, 265-270 closing, 24. See also closing windows
text buttons on, 263 color for, 328
.VUE rile name extensions, 258, 277, 290, 357, 575, controlling with keyboard, 24-25
608 editing memo field in, 560
hidden, 22

W moving with mouse, 24


opening for tagged files, 534
WAIT command, 392-393, 613 partitioning, 96-99
warning message, turning off and on, 345 zooming, 86
WHEN, for GET clause, 560 With text button, for Replace, 326
While check box word-wrap, 86, 311, 306
for Delete, 100 avoiding in programs, 382
in dialog boxes, 174, 196 work areas, 263, 264, 599
to limit records averaged, 321 Wrap Around, in Find, 310
in Replace, 326 Wrap Words (Preferences dialog box), 313
WHILE clause, 162, 174, 175-176
in AVERAGE command, 564 Y
in CALCULATE command, 568
in CHANGE command, 570 year, display of, 288
in commands, 163 YEAR() function, 131
in COPY command, 573
in DISPLAY command, 580 z
in EDIT command, 583
in LABEL FORM command, 588 ZAP command, 103, 613
in LIST command, 589 zip codes, data type for, 51
in queries, 194 zoom control, 24, 25
in REPLACE command, 596 zooming window, 86
, v /?/ MoAToa/
4,:
P P /fp/pPO

,pA / nv*'**
0 600 oO 'Jd . 6 J O 3 J 0 0(3
Q3 £p 0C&7 &A 02 0006 $ro£df & ! \ 0*°* c,t)d0A
___ .^_o$4%\0foc> 60 0 0

3 00 (0 (pooO naao OOO 0 I 4 f’ 60066 61 0^00 ; ■ J \


, 44
, * r r n? pw)
;.-7 • , M v

Af 00 oo 6 6 A rypo

A
Ur OtELV S/zr'i f f£
$\l£ Of
f\£u?

!* /)
4/(j 7" 4- yf?/^ /^/LE

%r rw<r

FSF JO/ES
i/j'f s
TW£ $TP.OCfVR<£r IAStPPPr ****** ~

Tfc- ftyup siwasi f/Wtt <70,08 PROMPT fPElP s/Z£ T'TIE ’fesr>
ACTIVATE PcofOE Etecaj

Pr wr
AL-! 7p /pi (a ->/kc ) To /H-LT/SfAA {_ j
/r Mt-tr ytetp \
a-> Azt oar s r ~ S, f- TJoil

Jo PATTo t>&2,06Sr£R. fPM


f l So To
<T£T &tt*Kf<XHT
} T$mJ(T THE CPt^SoR . "P<f> C-Tossr
THe Me for

-/ i/f &#£&K, ?7 . A %t> p<xr APP&A/iS 47 THe U/Js


SYBEX
TO JOIN THE SYBEX MAILING LIST OR ORDER BOOKS
PLEASE COMPLETE THIS FORM

NAME COMPANY

STREET CITY

STATE ZIP

□ PLEASE MAIL ME MORE INFORMATION ABOUT SYBEX TITLES

ORDER FORM (There is no obligation to order) SHIPPING AND HANDLING PLEASE ADD $2.00
PER BOOK VIA UPS
PLEASE SEND ME THE FOLLOWING: FOR OVERSEAS SURFACE ADD $5.25 PER
BOOK PLUS $4.40 REGISTRATION FEE
TITLE: QTY PRICE FOR OVERSEAS AIRMAIL ADD $18.25 PER
BOOK PLUS $4.40 REGISTRATION FEE
___ _ CALIFORNIA RESIDENTS PLEASE ADD
APPLICABLE SALES TAX
---- -- - TOTAL AMOUNT PAYABLE
_ _ _ □ CHECK ENCLOSED □ VISA
□ MASTERCARD □ AMERICAN EXPRESS
-—---- - - ACCOUNT NUMBER _

TOTAL BOOK ORDER _$_ EXPIR. DATE _ DAYTIME PHONE _

CUSTOMER SIGNATURE

CHECK AREA OF COMPUTER INTEREST: OTHER COMPUTER TITLES YOU WOULD LIKE
□ BUSINESS SOFTWARE
TO SEE IN PRINT:

□ TECHNICAL PROGRAMMING

□ OTHER:__

THE FACTOR THAT WAS MOST IMPORTANT IN OCCUPATION

YOUR SELECTION: □ PROGRAMMER □ TEACHER

□ THE SYBEX NAME □ SENIOR EXECUTIVE □ HOMEMAKER

□ QUALITY □ COMPUTER CONSULTANT □ RETIRED

□ PRICE □ SUPERVISOR □ STUDENT

□ EXTRA FEATURES □ MIDDLE MANAGEMENT □ OTHER:

□ COMPREHENSIVENESS □ ENGINEER/TECHNICAL

□ CLEAR WRITING □ CLERICAL/SERVICE

□ OTHER _ □ BUSINESS OWNER/SELF EMPLOYED


CHECK YOUR LEVEL OF COMPUTER USE OTHER COMMENTS:

□ NEW TO COMPUTERS

□ INFREQUENT COMPUTER USER

□ FREQUENT USER OF ONE SOFTWARE

PACKAGE:

NAME ______

□ FREQUENT USER OF MANY SOFTWARE

PACKAGES

□ PROFESSIONAL PROGRAMMER

PLEASE FOLD, SEAL, AND MAIL TO SYBEX

SYBEX, INC.
2021 CHALLENGER DR. #100
ALAMEDA, CALIFORNIA USA
94501

SYBEX

SEAL
SYBEX Computer Books
are different.
Here is why . . .
At SYBEX, each book is designed with you in mind. Every manuscript is
carefully selected and supervised by our editors, who are themselves
computer experts. We publish the best authors, whose technical expertise
is matched by an ability to write clearly and to communicate effectively.
Programs are thoroughly tested for accuracy by our technical staff. Our
computerized production department goes to great lengths to make
sure that each book is well-designed.

In the pursuit of timeliness, SYBEX has achieved many publishing firsts.


SYBEX was among the first to integrate personal computers used by
authors and staff into the publishing process. SYBEX was the first to
publish books on the CP/M operating system, microprocessor interfacing
techniques, word processing, and many more topics.

Expertise in computers and dedication to the highest quality product


have made SYBEX a world leader in computer book publishing. Trans¬
lated into fourteen languages, SYBEX books have helped millions of
people around the world to get the most from their computers. We hope
we have helped you, too.

For a complete catalog of our publications:


SYBEX, Inc. 2021 Challenger Drive, #100, Alameda, CA 94501
Tel: (415) 523-8233/(800) 227-2346 Telex: 336311
Fax: (415) 523-2373
Principal Database Management Operations Using FoxPro
(continues from first page)

Setting Up the
Current Work Area
The Setup dialog box lets you control the database file that is open in the cur¬
rently active work area. You can change the actual structure of the database,
and you can create, open, or modify indexes to control the order in which the
database, fields, and records are used. You can also define the format used for
editing and appending.

Database: EMPLIST
The Setup Structure: <ModifQ> Indexes: Index
dialog box
►FNAME C 15 0 •DATES |< Add. . . >1
LNAME C 20 0 NAMES <Modify...>
ADDRESS C 25 0 WAGES < Remove >
APT NO C 5 0 ZIPS <Set Order>

Fields: 11 Length: 117 Index expr:


Index filter:
[ ] Set Fields...
( ) offl (•) ogf
[ ] FiDter... « OK »
[ ] ForSJat.,.
Principal Database Management Operations Using FoxPro

Creating a View
The View window lets you create an entire working environment. You can
open and set up multiple databases at the same time, and you can set relations
among them to create relational databases. You cam also control simpler environ¬
ment variables. All these settings can be saved in a .VUE hie, and the entire
view can be used again simply by opening that hie.

View
The View ►< View > Work Areas < Relations >
window
<0n/0ff> ►WAGES
1—^ENPLIST
<Files >

< Misc >

<Setup >

< Browse >

< Open >

cClose > WAGES Records: 4-


Mastering Hook Level
Beginning
is Intermediate

FoxPro
Mastering FoxPro is a highly readable hands-on introduction to
database management, using the dBASE-compatible FoxPro system.
Perfect for beginning and intermediate users who want to build on a
solid base of skills, it covers everything from exploring the software’s
menus for the first time to creating full-featured custom database
applications.

Gain a clear, practical understanding of database fundamentals as you


learn step-by-step how to design and create a useful database; enter, edit,
and view data; and:

• organize your data for fast access using indexes


• set up and use both simple and complex queries
• design and produce customized reports and labels

Master the concepts of relational database management by learning with FastTmck Speed Notes
specific techniques for working with multiple database files. A realistic
employee recordkeeping system serves as a hands-on example.

Learn advanced skills through easy-to-follow tutorials. Topics include


About the Author
using the View Window to customize your work environment, tapping
powerful database commands, and: Charles Siegel is a computer
consultant who provides user training
• employing special techniques for editing and printing in MS-DOS applications and performs
custom database programming in C,
• creating macros to speed and automate routine tasks
dBASE and FoxPro. He is the author
• using FoxView to create custom data-entry screens and of two other books, including The
menu-driven applications ABC's of Paradox from SYBEX.

Get a concise introduction to structured programming while building a


complete professional mailing list management system. A special SYBEX books bring you skills —

in-depth tutorial, suitable for first-time programmers, shows exactly not just information.
how to plan, develop, test and debug a sophisticated custom FoxPro
application, using modular programming techniques.

Appendices include installation tips, a quick-reference guide to essential 90000


FoxPro commands and functions, and an introduction to using the
built-in desktop utilities.

fSYBEX COMPUTER BOOK SHELF CATEGORY


IBM/PCs: Databases
ISBN D-ATSAA-bTl-S U.S. $24.95

You might also like