OpenTables, CloseTables
These methods of the
Data environment open and close the tables listed there.
Usage
|
PROCEDURE oDEObject.OpenTables
PROCEDURE oDEObject.CloseTables
|
By default, OpenTables opens all the tables and views
listed in the Data environment and establishes the specified
relations among them, while CloseTables closes them. You can
override this behavior with your own code. However, opening and
closing tables and views is part of the default behavior for
these methods—that means they'll do it unless you put NODEFAULT
in your version of the method.OpenTables is sensitive to the
value of OpenViews. That property determines whether OpenTables
opens all views, no views, or just local or remote views.If
AutoOpenTables is .T., OpenTables is called implicitly at startup
of the object (form, formset, report or label). Similarly,
AutoCloseTables set to .T. means that CloseTables is called
automatically.You can also call OpenTables and CloseTables in
code.The firing order of OpenTables and BeforeOpenTables is
seriously confusing. Any custom code in OpenTables fires first,
then BeforeOpenTables fires, then the actual opening of tables
that's the default behavior of OpenTables occurs. We think
BeforeOpenTables is misnamed and should actually be called
BeforeAutoOpenTables, but we do see that 20 characters is just a
little long for a method name.What's going on here is that
OpenTables and CloseTables are really unique among all the events
and methods of Visual FoxPro. Technically, they're methods, but
in some ways they behave more like events. Having AutoOpenTables
set to .T. causes the OpenTable method to fire automatically like
an event and unlike any other methods. OpenTables and CloseTables
need to be in a special category all by themselves.The biggest
consequence of the relationship between OpenTables and
BeforeOpenTables is that there's not much reason ever to use
BeforeOpenTables. You can put the same code in OpenTables and
it'll run before the tables open.You might wonder when you'd want
to override the default behavior of these methods. The most
important case is to use a single form with different databases.
The Database property of a cursor in the Data environment has a
hard-coded path. You have to change it at runtime if you want to
refer to a different database than the one you used when you
created the DE. You can do that in code. But, if the choice of
database is based on something else in the form, say a parameter,
you can't make the change until after the form is initialized. In
that case, you can put code in OpenTables to change the database
property of each cursor (either specifically or by looping to
find them). In the Form's Init method, you can explicitly call
OpenTables. Your code to change the database reference executes
first, then the default of opening the tables occurs, using the
newly specified database. (Of course, you may prefer to put this
code in Init rather than OpenTables, so you can do it once in a
form class and be done with it.)
Example
|
* In a very simple version of the case described above,
* the form's Init method might be:
PARAMETER cWhichDBC
* WhichDBC is a custom property of the form
This.WhichDBC=cWhichDBC
ThisForm.DataEnvironment.OpenTables()
* If there are two tables in the DE,
* the OpenTables method might look like:
This.Cursor1.Database=ThisForm.WhichDBC
This.Cursor2.Database=ThisForm.WhichDBC
* Be sure to set AutoOpenTables to .F. in the Property Sheet
|
OpenTables doesn't need to include the USE or SET
RELATION commands because that happens automatically when the
method is called. A form with this structure can even be called
and told to use the open database by passing DBC() for the
parameter.In real code, you'd want to use AMEMBERS() and a loop
to change the cursor's database properties, rather than
hard-coding. Similarly, the Init would probably do some checking
on the parameter to make sure it refers to a real DBC and perhaps
even to ensure that the necessary tables exist in that
DBC.Another time to put code in OpenTables is to create indexes
on the fly for views. You can set things up so that the tables
and views open, and then you do some indexing. The code looks
like this:
* First, make the tables and views open right away
NODEFAULT && Prevent the table opening from running at the end of the method
DoDefault() && Make the table opening happen right now
SELECT SomeView
INDEX ON SomeField TAG SomeTag
You can use the same approach to do any other kind of thing
that should happen as soon as the tables have opened.
Back to Table of Contents
Copyright © 2002-2018 by Tamar E. Granor,
Ted Roche, Doug Hennig, and Della Martin. Click for license
.