DAO Database Object (1 Viewer)

JDubya

Registered User.
Local time
Today, 20:45
Joined
Oct 16, 2007
Messages
39
Hi Everybody, I've just progressed onto the DAO chapter of my VBA text and am already confused by what is supposed to be one of the simplest aspects of the Database object, that being counting the number of databases open in a workspace.

The text says " Normally, we will have only one database open at a time, so there will be only one Database object in the Databases collection for the current workspace. You can see this for yourself by typing this in Immediate Window and hitting Enter:-

?DBEngine.Workspaces(0).Databases.Count"

And just like the example in the book, when I hit Enter I get a return value of 1. However, I then open an additional 2 different Access databases and then run the ?DBEngine.Workspaces(0).Databases.Count request again in the Immediate window, but it still returns a value of 1.

So, can anyone explain to me why this count is still only 1 and not the 3 that I was expecting? Cheers, John
 

gemma-the-husky

Super Moderator
Staff member
Local time
Today, 20:45
Joined
Sep 12, 2006
Messages
15,738
Not checked, but I assume it's databases open in the current instance of Access, not multiple instances of Access.

You can open another database in code within your active database. That's probably what it's referring to.
 

JDubya

Registered User.
Local time
Today, 20:45
Joined
Oct 16, 2007
Messages
39
Thanks Dave, so from that I'm guessing that all 3 separate databases open on my pc would therefore be in their own workspace, but if I modify the expression to look at Workspace(1) or Workspace(2), I get an error?
 

kevlray

Registered User.
Local time
Today, 12:45
Joined
Apr 5, 2010
Messages
1,046
Just thinking here, no proof. But considering how the Windows work. Unless you open the DB's within the code, each database will be in it's separate 'sandbox' and thus not aware of any other Access databases.
 

JDubya

Registered User.
Local time
Today, 20:45
Joined
Oct 16, 2007
Messages
39
Ok thanks Kevlray & Dave
So, if I'm understanding this right.....if there is an Access Database that is being used by 10 users, then each one of those users will occupy one workspace each, so that if I type ?dbengine.workspaces.count, I should get a return value of 10.

Each user will typically have 1 database open within their workspace unless a particular user initiates a piece of code that opens a different database from within their current database, which results in that user having 2 databases open in their workspace, whilst their colleagues will still only have 1 database open in each of their respective workspaces.

Cool, thanks guys. John
 

MarkK

bit cruncher
Local time
Today, 12:45
Joined
Mar 17, 2004
Messages
8,198
So, if I'm understanding this right.....if there is an Access Database that is being used by 10 users, then each one of those users will occupy one workspace each, so that if I type ?dbengine.workspaces.count, I should get a return value of 10.
No. You will never find one workspace with 10 databases because each of these 10 users will be using a database on their own machine, so each will be running their own DBEngine, and each will have their own workspace.

To open multiple databases in the same workspace you have to work at it. You can do it with code like...
Code:
Private Sub Test012845719578()
    Dim dbs As DAO.Database

    With DBEngine.Workspaces(0)
        Debug.Print .Databases.Count[COLOR="Green"]   'will show 1 database[/COLOR]
        Set dbs = .OpenDatabase("C:\DataBase1.accdb")
        Debug.Print .Databases.Count[COLOR="Green"]   'will show 2 databases[/COLOR]
    End With
End Sub
... but that second database will immediately close when the dbs variable goes out of scope.
 

JDubya

Registered User.
Local time
Today, 20:45
Joined
Oct 16, 2007
Messages
39
Hi Mark, thank you for your example showing how you can have more than 1 database open in a particular workspace. However, I wasn't saying that if 10 users are logged onto a database that will show as 10 databases in 1 workspace.... I was theorising that it would be seen as 10 separate workspaces containing 1 database each. However, you mentioned that each user would be running their own DBEngine, which if that is the case and taking that into account that each workspace equates to "a single session or instance of a user interacting with the database engine", how is it possible for one database engine to have more than 1 workspace?
 
Last edited:

Tieval

Still Clueless
Local time
Today, 20:45
Joined
Jun 26, 2015
Messages
475
But the command is counting databases (1) not Workspaces (10).
 

MarkK

bit cruncher
Local time
Today, 12:45
Joined
Mar 17, 2004
Messages
8,198
how is it possible for one database engine to have more than 1 workspace?
Code:
Private Sub Test192386471293847()
    Dim wrk As DAO.Workspace
    
    With DBEngine
        Debug.Print .Workspaces.Count
        Set wrk = .CreateWorkspace("New Test Workspace", "admin", "")
        .Workspaces.Append wrk
        Debug.Print .Workspaces.Count
    End With
End Sub
Does it answer the questions "How is it possible?" to simply show that it is possible?
 

JDubya

Registered User.
Local time
Today, 20:45
Joined
Oct 16, 2007
Messages
39
But the command is counting databases (1) not Workspaces (10)

Yes, true Tieval, but as is always the case, each answer raises another question. My understanding originally was that the Database engine resides in the MS Access Application itself and so that as a single user, if I had 3 separate databases open on my pc, that would equate to 1 database engine (contained within MS Access), 1 workspace (my session with MS Access) and 3 databases (the 3 .accdb files I had opened at the time. Dave and Kevlray then pointed out that the database count referred to multiple databases opened from with each instance of an .accdb file, which therefore led me to believe that if there were 10 users logged onto a single database that this would equate to 10 different workspaces connected to the DBEngine of that networked database, with each workspace containing a database count of 1. However, then Markk pointed out that each user would have their own database engine which has confused me further, as if each user has their own database engine, and a workspace is each session with that particular dbengine, then how can you have more than one workspace at any one time?
 

JDubya

Registered User.
Local time
Today, 20:45
Joined
Oct 16, 2007
Messages
39
Does it answer the questions "How is it possible?" to simply show that it is possible?

Thanks for the example Markk, yep so when I run the code I now have two workspaces, I just don't understand why it takes action in an object lower in the DAO hierarchy to create an object higher up in the food chain and if this is how to create a new workspace, then for what real world reason ?
 

MarkK

bit cruncher
Local time
Today, 12:45
Joined
Mar 17, 2004
Messages
8,198
I just don't understand why it takes action in an object lower in the DAO hierarchy to create an object higher up in the food chain
Where does this occur? CreateWorkspace is a method of the DBEngine. CreateDatabase is a method of the Workspace.

if this is how to create a new workspace, then for what real world reason ?
To isolate transactions. Check out the BeginTrans, CommitTrans, and Rollback method of the Workspace object. In cases where all updates must succeed or all must fail, like updating a batch of balancing debits and credits in an accounting system, you would begin a transaction in a workspace, execute your update queries, and then commit the transaction. In this way, if you had multiple databases open in that workspace, you could guarantee that separate databases would always remain synchronized, for instance.
 

static

Registered User.
Local time
Today, 20:45
Joined
Nov 2, 2015
Messages
823
"already confused by what is supposed to be one of the simplest aspects of the Database object, that being counting the number of databases open in a workspace."

"The text says " Normally, we will have only one database open at a time"

In most cases in Access you can just use

Code:
set rs = currentdb.openrecordset(sql)

or

Code:
currentdb.execute sql

currentdb is the equivalent of dbengine(0)(0), the default database of the default workspace.


Knowledge is always good, but there are far more useful things for a beginner to learn than this. So, unless you have a specific need to know, I'd say you can safely skip this section and come back later if you want to. ;)
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 14:45
Joined
Feb 28, 2001
Messages
27,440
JDubya, you were confused because you asked the question about Access, but the problem is actually a Windows question.

If you launch 3 applications using a window and a mouse click or any analogous method, each click launches MSACCESSS.EXE, and you can confirm this with Task Manager. Each of these starts a Windows Process which has its own separate resources - including its own allocation of physical memory. Since it is the Access front-end that contains the DBEngine, your 3 processes all have independent workspaces that, due to Windows security, cannot "see" each other. This is because WINDOWS is keeping them from being able to overlap.

Most people don't think about it because they don't that often get involved with Windows Server 2xxx. However, back in the days when Windows 98 and Win2k and WinME were current, Microsoft wanted to sell a LOT of workstations to the U.S. Government. However, there was this thing called the "Orange Book" - part of a series of government standards collectively called the "Rainbow Series" - that described certain properties that were the basis for evaluation of an operating system's readiness for use in government offices. The target standard was something called "C2" and all of the (then) DOS-based PCs would have failed the evaluation. The problem was that even though they ran Windows, underneath they still ran MS-DOS and THAT would have kept them down in the D evaluation levels.

At that time, Microsoft commissioned Dave Cutler et al. to rewrite the Windows Kernel code so that it could at least be C2 compliant, as that was what was needed to be allowed to run "Sensitive but Unclassified" (SBU) software. I was with the U.S. Navy at the time as a contractor and saw all of Microsoft's gyrations from the outside, but I kept up with publications and knew what was happening.

Windows NT came out and it met C2 requirements. Subsequent versions of Windows (technically starting with v4) have a Windows Kernel, not a DOS Kernel, and are able to perform the isolation required to meet that standard. In fact, as time has marched on, Windows has reached the level that allows it to run stuff at Secret level. The "Orange Book" has been replaced, but by that older standard it would mean that Windows is up to at least the B1 level. ("A" level is Top Secret and I have not been on such systems so can't tell you much about that.)

Why is this relevant to your question? The answer is that in the more secure versions of the Windows environment, whether Server or Desktop, processes that run simultaneously by taking chunks from the same pool of physical memory are NOT ALLOWED to see into each other's spaces. Isolation of parallel processes is part of the requirement that Microsoft was addressing when they build Win NT so many years ago. It is how you keep hackers and malware at bay - by using advanced memory management to assure that "the left hand doesn't know what the right hand is doing."

Therefore, when you look at "DBEngine(0).xxx" properties, each separately launched process has only one DBEngine. At least in theory, but I've never seen it done in the real world, it would be POSSIBLE with Windows for a process to launch multiple threads in the same process space and trigger a second copy of the database engine in a separate thread. However, Access wasn't written that way. The reason you are seeing "DBEngine(0)" and not just "DBEngine" is because the Component Object Model is rearing its ugly head. That is just the formal way that COM requires you to access things in its heirarchical series of object pointers.

Now, the theoretical question about DBEngine(0).Workspace(number).Databases(number) - works like it does because you have access to the DBEngine primitives to open workspaces, and you have access to the Workspace primitives to open databases. But you don't have access to the thing that is above DBEngine(), so you have no primitives to say "Add another engine." That would done at the process level and the COM API doesn't take you there.

So this is why you see what you see. Hope it clarifies for you what you see and why you see it that way vs. any other way.
 

JDubya

Registered User.
Local time
Today, 20:45
Joined
Oct 16, 2007
Messages
39
Many thanks for a really informative piece The_Doc_Man - it really helps to get a bit of background to help make sense of the topic. Cheers, John.
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 14:45
Joined
Feb 28, 2001
Messages
27,440
Always glad to help, John.

- Richard
 

Users who are viewing this thread

Top Bottom