Hacker’s Guide to Visual FoxPro
An irreverent look at how Visual FoxPro really works. Tells you the inside scoop on every command, function, property, event and method of Visual FoxPro.
This class lets forms and reports handle their own data—it’s another step on the way to full encapsulation. Unfortunately, it has some basic weaknesses that make it far less useful than it should be. Don’t confuse this base class with the nonexistent, but nonetheless documented, DataEnvironment Property
.
Every form created in the Form Designer has a data environment (DE) object added automatically. It just happens when you create the form. The data environment itself contains two kinds of objects, cursors and relations. Cursors are a general-purpose way of handling tables and views (from a form’s standpoint, the two are identical). Relations are descriptions of temporary relations to be established between cursors.
You set up the data environment in the Data Environment Designer (available via a myriad of techniques in the Form Designer, including the form’s context menu, the Form Designer toolbar, and the View menu when focus is on the form in the Designer). Each time you add a table in the DE Designer, a cursor object is added to the data environment. If the table has a persistent relationship with another table already in the DE, a relation object is created, too. You can add other relations by dragging from a field of one table to a tag of another.
The DE can be set to automatically open the tables and establish the relations when you run the form (or report). Even if you don’t do it automatically, you can explicitly open things with the DE’s OpenTables method. Whether or not you let the DE open and close things automatically, the ability to store all the data information needed for a form or report as an intelligent part of that object is terrific.
Weaknesses—did we say weaknesses? Yeah, we did. One of them is really a flaw of forms rather than of the DE itself. When you CREATE FORM
classes (that is, subclasses of the form base class), you can’t store a DE with them. So, you can’t do your data settings once and then inherit them over and over.
The other big flaw is that the data environment is another of Visual FoxPro’s “half-classed” objects. You can subclass it, but not visually, and like many other contained objects, you can’t visually add coded subclasses to the container—in this case, a form. We know a number of people (and at least one of the popular commercial frameworks) who are subclassing the DE anyway and swapping their custom DE class into forms at runtime.
VFP 7 addressed another, smaller, flaw in the data environment by adding the Objects collection. Until then, there was no easy way to find out what objects the data environment contained.
Property |
Value |
Purpose |
AutoCloseTables |
Logical |
Determines whether tables and views in the DE are automatically closed when the form shuts down. |
AutoOpenTables |
Logical |
Determines whether tables and views in the DE are automatically opened when the form starts. |
InitialSelectedAlias |
Character |
Determines which cursor in the DE is selected after the DE is fully initialized. |
OpenViews |
Numeric |
Determines which kinds of views are automatically opened when the form starts. |
Event |
Purpose |
AfterCloseTables |
Fires immediately after the tables are closed by CloseTables. |
BeforeOpenTables |
Fires just before the tables are opened by OpenTables. |
Method |
Purpose |
CloseTables |
Closes the tables listed in the DE. |
OpenTables |
Opens the tables and establishes the relations listed in the DE. |
The relationship among BeforeOpenTables, OpenTables and AutoOpenTables is complex. Check those topics for an explanation.
* Data environment settings are always established
* in the Properties Sheet, not at runtime.
* You might set:
AutoOpenTables = .T. && Open them up automatically
AutoCloseTables = .F. && Leave 'em open
AfterCloseTables, AutoCloseTables, AutoOpenTables, BeforeOpenTables, CloseTables, Cursor, DataEnvironment Property, InitialSelectedAlias, Objects, OpenTables, OpenViews, Relation