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.
CREATEOFFLINE()
, DROPOFFLINE()
These functions, added in VFP 5, let you create and destroy offline views.
<a name=Usage>lSuccess = CreateOffline( cViewName [, cPathAndFile ] )</a>
lSuccess = DropOffline( cViewName )
Parameter |
Value |
Meaning |
Character |
The name in the database of the view for which to create or drop an offline view. |
|
cPathAndFile |
Character |
The path and file name of the table to hold the offline view. Be careful to include the file name here. If you don't, you're likely to end up with a file that has the directory name you intended and is one directory level higher than you expect. |
Omitted |
The table is created in the current directory using the view name as the file name. |
|
lSuccess |
.T. |
The view was successfully taken offline or brought back online. |
.F. |
The view could not be taken offline or brought online. |
Offline views are one of those things that seemed like such a good idea when they were added to the product, but we don’t actually know anyone who’s using them in production applications. They’re VFP’s version of replication and, in typical FoxPro fashion, you have control over what happens, but the price is that you have to write a lot of code. (For the most part, it’s the same conflict resolution code you normally use. See GETFLDSTATE()
for a simple version of conflict resolution code.)
When you take a view offline, you get a physical copy of the data in the specified location. The original view is marked as read-only in the database, so anyone opening it actually gets the newly created table, not an on-the-spot query. If the offline view is created on or moved to a different drive, then no one else can touch that view. When you’re ready, you open the view online, resolve conflicts, and save the changed data. Then, you can bring the view back online (or drop the offline view) to make it behave like a regular view.
When would you use this strategy? Consider a sales force that’s mostly on the road at client sites. They need to be able to update data for their clients on the fly, without having to dial into a server or any such thing. When they come back, or maybe even when they get back to the hotel at night, they need to send the updated data to the server.
So what’s the problem? First, note that part about the original view being marked read-only. To make offline views work in this scenario, you have to provide each salesman with his own set of views for the relevant tables. Second, there’s that “resolve conflicts” part—it’s no easier in this setting than anywhere else. It still requires a bunch of good, solid code.
Nonetheless, we’re not exactly sure why no one’s using this technique. All the pieces seem to work, and there are settings where it seems just the ticket.
So, on to these two functions, which along with a couple of clauses in the USE command, are the key to offline views. As with so much of the good data-handling stuff in Visual FoxPro, SET MULTILOCKS
must be ON to either create or drop an offline view.
CREATEOFFLINE()
doesn’t actually create a new view. It takes an existing view, copies the data to the specified location, and tells the database about it.
A few complications. First, as we mentioned above, be careful to provide a path and file name, not just a path. We’ve ended up with a table called Offline.DBF more times than we care to admit while testing this.
If the view you specify is parameterized, VFP behaves as it normally does when you open a parameterized view. That is, if the parameter already exists, it just does the job. If the parameter doesn’t exist, you’re prompted for it.
Taking a view offline doesn’t leave it open, though it does leave the tables on which the view is based open.
When a view is offline, it’s really offline. The original, online version cannot be opened for viewing or maintenance, let alone to make changes. Attempts to open it actually open the offline view itself, if it’s physically present. (You can tell the difference by checking DBF()
for the view.) On the whole, it’s better to define one set of views for offline work and a separate set for ongoing business, though that does increase the likelihood of conflicts to be resolved down the road.
In all versions of VFP 5, if CreateOffline() fails, DBSetProp() still returns .T. for the Offline property. |
In VFP 7, if the database has Database Events
turned on, the BeforeCreateOffline and AfterCreateOffline events fire.
On to DROPOFFLINE()
. This one tells the database that its wandering view is home again. It deletes the table containing the offline view and updates the database so it knows to use the original, online version. The view must be closed before you can take it online.
DROPOFFLINE()
expects the original name of the view as a parameter, not the name of the table you stored it in. While this surprised us at first, in fact it does make sense. The view name is the database’s way of keeping track of the view; the name of the physical table in which it’s stored is incidental.
If you want to keep your changes, be sure to USE the view ONLINE, and issue appropriate TableUpdate()
calls before you drop the offline view. Once you drop it, it’s gone, gone, gone.
The BeforeDropOffline and AfterDropOffline events fire in VFP 7 for a database that has Database Events
turned on.
<a name=Example>* Take a view from TasTrade offline.</a>
* Give it a short file name.
? CreateOffline("Order History","OfflineViews\OrdHist")
* Now work with the offline view.
USE "Order History" ALIAS OrdHist
* Make changes as desired.
* When you're done:
USE "Order History" ONLINE EXCLUSIVE
* Commit changes.
? TableUpdate(.T.)
USE
* Put it away.
? DropOffline("Order History")
AfterCreateOffline, AfterDropOffline, BeforeCreateOffline, BeforeDropOffline, DBSetProp(), Create SQL View, GetFldState(), Set Multilocks, TableUpdate(), Use