Hi, Steve.
How does adding DBENGINE to the OpenDatabase method refer to a different
workspace? If anything it would be the same default workspace would it
not?
That would be true if the default Workspace object were the default member
of the DBEngine object. It isn't.
I'm confused on how using DBENGINE versus DBENGINE.OpenDatabase makes a
difference.
I think you mean OpenDatabase( ) vs. DBEngine.OpenDatabase( ), so I'll
explain in that context.
The DBEngine object's default member is the Workspaces Collection Property.
And the Workspaces Collection Property has no default member. Therefore,
when the DBEngine object is being referred to without an explicit Workspace
object defined, some logic must be executed to determine which Workspace
object to use implicitly. There are three choices: the default Workspace
object, another previously-defined Workspace object, or a newly created
Workspace object.
The most efficient use of resources dictates use of existing resources first
and then allocating memory for creating new objects only when necessary.
The default Workspace object is a bad choice, because it already has a
Database object defined. (I'll explain the implications of this in a
moment.) If a previously-defined Workspace object is available (i.e., the
Database object isn't assigned to a database), then it will be used for the
new Database object. If no Workspace object is currently available, then a
new one will be created for the new Database object.
We don't want to add a second Database object to the default Workspace
object because a Workspace object can only handle one Database object
exclusively. Using the OpenDatabase( ) method without explicitly or
implicitly referencing a Workspace object will usually create a Database
object in the default Workspace object, but not always. Even with the
latest service packs installed, this behavior is inconsistent and depends
upon whether another Workspace object is already open (and that Database
object is available for assignment), whether the database file has been
decompiled recently with the undocumented /Decompile command-line switch,
and whether the database file has been compacted and repaired even more
recently. This is why executing identical code that uses two or more
Database objects seemingly in the same scope will sometimes work, but
sometimes give one of the following errors:
"Error # 3734: The database has been placed in a state by user 'Admin' on
machine 'MyComputer' that prevents it from being opened or locked" or
"Error # 3045, "Could not use <FullPath\MyDB.mdb>; File already in use."
Clear as mud? Well, just so you don't have to memorize and explain this
trivia about how the DAO library works with the the Jet Workspace the next
time someone sees your code and asks, "Why are you using
DBEngine.OpenDatabase( ) instead of the simpler OpenDatabase( )?" you can
explicitly define a Workspace object to keep the Database objects separate,
and make sure that the Database object assigned to it is released when it
goes out of scope. The following code will work just fine:
'******* Start Code *******
Public Sub populate_qrylist()
On Error GoTo ErrHandler
Dim wkSpc As Workspace
Dim db As Database
Dim intCT As Integer
Dim x As Integer
Dim rs As Recordset
Dim fOpenedRecSet As Boolean
Dim fOpenedDB As Boolean
Dim fOpenedWkSpc As Boolean
'-----------------------------------------------------
' Create a 2nd Wkspc to handle the
' other DB object separately.
'-----------------------------------------------------
Set wkSpc = DBEngine.CreateWorkspace("TempWkSpc", "Admin", "")
fOpenedWkSpc = True
Set db = wkSpc.OpenDatabase(Me!txtDBLocation.Value, False)
fOpenedDB = True
intCT = db.QueryDefs.Count
Set rs = CurrentDb.OpenRecordset("tblQueries")
fOpenedRecSet = True
For x = 0 To intCT - 1
rs.AddNew
rs!qryName = db.QueryDefs(x).Name
rs.Update
Next x
CleanUp:
If (fOpenedRecSet) Then
rs.Close
fOpenedRecSet = False
End If
If (fOpenedDB) Then
db.Close
fOpenedDB = False
End If
If (fOpenedWkSpc) Then
wkSpc.Close
fOpenedWkSpc = False
End If
Set rs = Nothing
Set db = Nothing
Set wkSpc = Nothing
Exit Sub
ErrHandler:
MsgBox "Error in populate_qrylist( ) in" & vbCrLf & Me.Name & _
" form." & vbCrLf & vbCrLf & "Error #: " & _
Err.Number & vbCrLf & Err.Description,
vbExclamation + vbOKOnly
Err.Clear
GoTo CleanUp
End Sub
'******* End Code *******
But to be honest, I'm wondering why you went to all this trouble to do this
in VBA code. Why doesn't your application just query the other database's
MSysObjects table for the current list of query names? The list of query
names in your tblQueries table is going to become outdated at some point,
not to mention one of the goals of relational databases is elimination of
redundancy.
HTH.
Gunny
See
http://www.QBuilt.com for all your database needs.
See
http://www.Access.QBuilt.com for Microsoft Access tips.
(Please remove ZERO_SPAM from my reply E-mail address, so that a message
will be forwarded to me.)