When you write a program, you can store data and manipulate it with a series of instructions. Data and data storage containers are the basic building blocks in programs, and you use commands, functions, and operators to manipulate data and data storage containers.
Storing Data
The data that you work with can include amounts of time, money, and countable items, as well as dates, names, descriptions, and so on. Each piece of data is a certain type: it belongs to a category of data that you manipulate in similar ways. You could work directly with this data without storing it, but you would lose most of the flexibility and power of Visual FoxPro. Visual FoxPro provides numerous storage containers to extend your ability to easily manipulate data.
Data types determine how data is stored and how it can be used. You can multiply two numbers together, but you can't multiply characters. You can print characters in uppercase, but you can't print numbers in uppercase. Some of the primary data types in Visual FoxPro are listed in the following table.
Data Types
Type | Examples |
---|---|
123 3.1415 – 7 |
|
"Test String" "123" "01/01/98" |
|
.T. .F. |
|
{^1998-01-01} {^1998-01-01 12:30:00 p} |
Data Containers
Data containers allow you to perform the same operations on multiple pieces of data. For example, you add the hours an employee has worked, multiply them by the hourly wage, and then deduct the taxes to determine the amount of pay the employee has earned. You'll have to perform these operations for every employee and every pay period. If you store this information in containers, and perform the operations on the containers, you can just replace the old data with new data and run the same program again. This table lists some of the main containers for data in Visual FoxPro.
Type | Description |
---|---|
Single elements of data stored in your computer's RAM (Random Access Memory). |
|
Table Records |
Multiple rows of predetermined fields, each of which can contain a predefined piece of data. Tables are saved to disk. |
Multiple elements of data stored in RAM. |
Manipulating Data
Containers and data types give you the building blocks you need to manipulate data. The final pieces are operators, functions, and commands.
Using Operators
Operators tie data together. Here are the most common operators in Visual FoxPro.
Operator | Valid Data Types | Example | Result |
---|---|---|---|
= |
All |
|
Prints .T. if the value stored in the variable |
+ |
Numeric, Character, Date, DateTime |
|
Prints "FoxPro" |
! or |
Logical |
|
Prints .F. |
*, / |
Numeric |
|
Prints 25 Prints 5 |
Note: |
---|
A question mark (?) in front of an expression causes a new line character and the results of the expression to be printed in the active output window, which is usually the main Visual FoxPro window. |
Remember that you must use the same type of data with any one operator. The following statements store two numeric pieces of data to two variables. The variables have been given names that start with n
so we can tell at a glance that they contain numeric data, but you could name them with any combination of alphanumeric characters and underscores.
nFirst = 123
nSecond = 45
The following statements store two pieces of character data to two variables. The variables have been given names that start with c
to indicate that they contain character data.
cFirst = "123"
cSecond = "45"
The following two operations, addition and concatenation, yield different results because the type of data in the variables is different.
? nFirst + nSecond
? cFirst + cSecond
Output
168
12345
Because cFirst
is character data and nSecond
is numeric data, you get a data type mismatch error if you try the following command:
? cFirst + nSecond
You can avoid this problem by using conversion functions. For example, STR(В ) returns the character equivalent of a numeric value and VAL(В ) returns the numeric equivalent of a character string of numbers. These functions and LTRIM(В ), which removes leading spaces, enable you to perform the following operations:
? cFirst + LTRIM(STR(nSecond))
? VAL(cFirst) + nSecond
Output
12345
168
Using Commands
A command causes a certain action to be performed. Each command has a specific syntax, which indicates what must be included in order for the command to work. There are also optional clauses associated with commands that allow you to specify in more detail what you want.
For example, the USE command allows you to open and close tables.
USE Syntax | Description |
---|---|
Closes the table in the current work area. |
|
|
Opens the CUSTOMER table in the current work area, closing any table that was already open in the work area. |
|
Opens the CUSTOMER table in the next available work area. |
|
Opens the CUSTOMER table in the next available work area and assigns the work area an alias of |
The following table shows some examples of commands.
Command | Description |
---|---|
Marks specified records in a table for deletion. |
|
Replaces the value stored in record field with a new value. |
|
Positions the record pointer to a specific location in the table. |
Controlling Program Flow
Visual FoxPro includes a special category of commands that "wrap around" other commands and functions, determining when and how often the other commands and functions are executed. These commands allow conditional branching and looping, two very powerful programming tools. The following program illustrates conditional branches and loops. These concepts are described in more detail after the example.
Suppose that you had 10,000 employees and wanted to give everybody making $30,000 or more a 3 percent raise, and everybody making under $30,000 a 6 percent raise. The following sample program accomplishes this task.
This program assumes that a table with a numeric field named salary
is open in the current work area. For information about work areas, see "Using Multiple Tables" in Working with Tables.
Sample Program to Increase Employee Salaries
Code | Comments |
---|---|
|
The code between SCAN and ENDSCAN is executed as many times as there are records in the table. Each time the code is executed, the record pointer moves to the next record in the table. |
|
For each record, if the salary is greater than or equal to 30,000, replace this value with a new salary that is 3% higher. The semicolon (;) after WITH indicates that the command is continued on the next line. |
|
For each record, if the salary is not greater than or equal to 30,000, replace this value with a new salary that is 6% higher. |
|
End of the conditional IF statement. End of the code that is executed for each record in the table. |
This example uses both conditional branching and looping commands to control the flow of the program.
Conditional Branching
Conditional branching allows you to test conditions and then, depending on the results of that test, perform different operations. There are two commands in Visual FoxPro that allow conditional branching:
-
IF ... ELSE ... ENDIF
-
DO CASE ... ENDCASE
The code between the initial statement and the ENDIF or ENDCASE statement is executed only if a logical condition evaluates to true (.T.). In the example program, the IF command is used to distinguish between two states: either the salary is $30,000 or more, or it isn't. Different actions are taken depending on the state.
In the following example, if the value stored in the variable nWaterTemp
is less than 100, no action is taken:
В | Copy Code |
---|---|
* set a logical variable to true if a condition is met. IF nWaterTemp >= 100 lBoiling = .T. ENDIF |
Note: |
---|
An asterisk at the beginning of a line in a program indicates that the line is a comment. Comments help the programmer remember what each segment of code is designed to do, but are ignored by Visual FoxPro. |
If there are several possible conditions to check for, a DO CASE ... ENDCASE block can be more efficient and easier to keep track of than multiple IF statements.
Looping
Looping allows you to execute one or more lines of code as many times as you need to. There are three commands in Visual FoxPro that allow looping:
-
DO WHILE ... ENDDO
-
FOR ... ENDFOR
-
FOR EACH ... ENDFOR
-
SCAN ... ENDSCAN
Use SCAN when you are performing a series of actions for each record in a table, as in the example program just described. The SCAN loop enables you to write the code once and have it executed for each record as the record pointer moves through the table.
Use FOR when you know how many times the section of code needs to be executed. For example, you know there are a specific number of fields in a table. Because the Visual FoxPro function FCOUNT(В ) returns this number, you can use a FOR loop to print the names of all the fields in the table:
В | Copy Code |
---|---|
FOR nCnt = 1 TO FCOUNT( ) ? FIELD(nCnt) ENDFOR |
Use DO WHILE when you want to execute a section of code as long as a certain condition is met. You might not know how many times the code will have to execute, but you know when it should stop executing. For example, let's assume you have a table with people's names and initials, and you want to use the initials to look people up. You would have a problem the first time you tried to add a person who had the same initials as someone else already in your table.
To solve the problem, you could add a number to the initials. For example, Michael Suyama's identification code could be MS. The next person with the same initials, Margaret Sun, would be MS1. If you then added Michelle Smith to the table, her identification code would be MS2. A DO WHILE loop enables you to find the right number to append to the initials.
Sample Program with DO WHILE to Generate a Unique ID
Code | Comments |
---|---|
|
Save the location of the record. |
|
Get the person's initials from the first letters of the Establish a variable to hold the number to be added to the end of a person's initials if necessary. |
|
See if there is another person in the table with the same initials. |
|
If another record in the table has a person_id value that is the same as |
|
Prepare a fresh suffix and append it to the end of the initials. |
|
CONTINUE causes the last LOCATE command to be evaluated again. The program checks to see if the new value in |
|
End of the DO WHILE loop. |
|
Return to the record and store the unique identification code in the |
Because you don't know beforehand how many times you'll find matching identification codes already in use, you use the DO WHILE loop.