jwcolby
jwcolby at colbyconsulting.com
Sat Aug 8 07:46:10 CDT 2009
Max, That is not exactly what he means. The database object contains a whole slew of things like .tabledefs() and .QueryDefs() collections etc. When you dim a database object and set a reference to a database instance using CurrentDb, it creates a snapshot of the state of the database at that instance in time. Suppose that you create TWO db variables, db1 and db2 and set each to currentdb. Now delete a table using the db1.tabledefs() object to do so. The db2.Tabledefs will continue to show all the table objects, even though one of them no longer exists because it was deleted by db1 object. Currentdb returns a SNAPSHOT of the database at a specific point in time. Currentdb APPARENTLY builds up a database object, populating all of the various collections (tabledefs(), QueryDefs() etc) with COPIES of the actual objects. To my knowledge the "copy" goes to the physical description, NOT the data contained in a table for example. Thus, for example, you could: dim db1 as dao.database set db1 = currentdb Now you could delete every table and query in the database and still use DB1 to see what they were and even dim recordsets for tables or queries that no longer exist, iterate said tables fields() collections, see what the data types for each field WERE etc. However you could not OPEN the table or query (attempt to see the data) because the actual table is now missing. The db object that you obtained with the currentdb object is a picture of the "skeleton" of the database, at the instant that the set statement occurred. The time to open a Currentdb object can be quite onerous. Try timing the set db = currentdb in a loop for a complex database and you will discover that it can take a long damned time, I have observed as much as a quarter of a second. The reason is obvious if you think about the above concept. The set statement has to somehow create the entire skeleton of the database (make a picture). OTOH DbEngine (0)(0) simply grabs a pointer to the actual database, no overhead at all. I used the following code to time the two methods: Const clngMaxLoop As Long = 1000 Function TimeCurrentDb() Dim db As DAO.Database Dim tmr As clsTimer Dim lng As Long Set tmr = New clsTimer tmr.StartTimer For lng = 1 To clngMaxLoop Set db = CurrentDb Next lng Debug.Print "CurrentDb:" & tmr.EndTimer End Function Function TimeDBEngine() Dim db As DAO.Database Dim tmr As clsTimer Dim lng As Long Set tmr = New clsTimer tmr.StartTimer For lng = 1 To clngMaxLoop Set db = DBEngine(0)(0) Next lng Debug.Print "DBEngine(0)(0):" & tmr.EndTimer End Function Class timer is: Option Compare Database Option Explicit Private Declare Function apiGetTime Lib "winmm.dll" _ Alias "timeGetTime" () As Long Dim lngStartTime As Long Private Sub Class_Initialize() StartTimer End Sub Function EndTimer() EndTimer = apiGetTime() - lngStartTime End Function Sub StartTimer() lngStartTime = apiGetTime() End Sub My results were: TimeCurrentDb CurrentDb:859 CurrentDb:878 CurrentDb:858 CurrentDb:886 CurrentDb:892 TimeDBEngine DBEngine(0)(0):1 I guess the lesson to take away from all this is that Currentdb is a pretty specialized construct that in general is not what we want to use for most things. DBEngine(0)(0) is a pointer to the ACTUAL database, live, current at all times. CurrentDB is exactly that, a pointer to the database at the CURRENT instant, not live, not current at all times. And expensive to get a pointer to to boot. John W. Colby www.ColbyConsulting.com Max Wanadoo wrote: > Very interesting AD. > > Any two instances of CurrentDb retrieved are not automatically in synch or > transparent to each other. The situation could be considered akin to two > different recordsets for the same data source. > << > > This is exactly what I would want and expect in most cases. I would not > want a second instance to have any bearing whatsoever on the first and I > would want/expect to close the second down without any effect on the first. > > Good summary - many thanks > > Max