[AccessD] OpenRecordSet question

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




More information about the AccessD mailing list