Reputation: 1739
It is my understanding that the DAO and ADO object models only have objects for data access, such as tables and queries, and do not have objects that relate to the presentation of data, such as forms and reports.
In agreement with that, the long list of objects in the MS documentation of DAO objects does not include forms or reports.
Also in agreement, the MS documentation on the DAO container object says "The following table lists the name of each Container object defined by the Microsoft Access database engine" and the said table lists three objects: Databases, Tables, and Relations.
However, when I run the following routine in Access 2007 VBA:
Sub ListDocuments()
Dim oDB As DAO.Database: Set oDB = CurrentDb()
Dim oContainer As DAO.Container
For Each oContainer In oDB.Containers
Debug.Print oContainer.Name
Next oContainer
End Sub
I get the following output:
DataAccessPages
Databases
Forms
Modules
Relationships
Reports
Scripts
SysRel
Tables
There are two problem with this output:
? Forms.Count
= 0, but ? CurrentDb().Containers("Forms").Documents.Count
= 1 . So these two things, both called "Forms", are different things.This container object Forms does not seem to be documented anywhere. And its existence seems to contradict the statement quoted above that Access only defines three container objects. And further, since it is in the DAO object Containers, it seems to also contradict the idea that DAO does not include objects for forms and reports.
So my question is, where does this container object Forms come from? What object model does it belong to? If you know the answer, it would be helpful if you could link to some documentation for it.
Upvotes: 1
Views: 1761
Reputation: 1
on a new database you get fewer containers: Current database contains 3 containers
Container Databases contains 1 documents
MSysDb
Container Relationships contains 0 documents
Container Tables contains 5 documents
MSysACEs
MSysComplexColumns
MSysObjects
MSysQueries
MSysRelationships
Upvotes: 0
Reputation: 1
No sure how untimely this is, but I came across it, didn't read the whole thing, so i hope this wasn't already answered above. From a cursory read, though, it seems someone missed something somewhere.
Here is a little code I'm using to try to understand the quirks of VBA, along with its results. Results first, code after.
Call DumpDBContainers()
Current database contains 9 containers
Container DataAccessPages contains 0 documents
Container Databases contains 3 documents
Container Forms contains 14 documents
Container Modules contains 20 documents
Container Relationships contains 4 documents
Container Reports contains 0 documents
Container Scripts contains 22 documents
Container SysRel contains 1 documents
Container Tables contains 151 documents
Public Sub DumpDBContainers()
Dim dbs As Database, Cntr As Container
Dim bNmeOnly As Boolean
Set dbs = CurrentDb()
Debug.Print " "
Debug.Print "Current database contains " & dbs.Containers.count & " containers"
Debug.Print " "
For Each Cntr In dbs.Containers
Debug.Print "Container " & Cntr.Name & Space(30 - Len(Cntr.Name)) & "contains " & Cntr.Documents.count & " documents"
Next Cntr
End Sub
Upvotes: 0
Reputation: 3883
Other answers and online documentation all contain good information worth understanding if you really want to grasp the details for programming Access. However, they often exclude critical details that are either assumed or forgotten. Before directly answering your questions myself, consider these points:
It has a container object called "Relationships" and not "Relations". Does this indicate a typo in the documented list of container objects quoted above?
Yes, any discrepancy between "Relationships" and "Relations" is just a mistake and likely has no deeper meaning.
Where does this container object Forms come from?
This is only a guess, but at least an attempt at a direct answer:
The container object is provided as a backward reference for discovery of related objects. When MS Access creates/loads the database via DAO, it apparently adds additional Container objects for its own purposes. DAO provides a generic Containers collection and allows other objects to add to it.
Even though DAO's purpose is to simply access and represent to the data itself, apparently MS determined it was useful to provide a way to publish (a.k.a. expose) related objects via the DAO object model. I would consider it like the Parent
property of many objects. Without such a Parent
property, there is often no built-in way to determine the relationship of an object to its source. Likewise, in a complex application, there may have been no other way to determine various details of the database without the containers collection. Albert D. Kallal already emphasized there need not be any particular connection between DAO and the Container objects. Perhaps it is true that the Container classes and objects really have no meaningful relationship, but MS obviously decided for some reason to tack that onto the DAO object model, so I find Mr. Kallal's explanation lacking. Access is still a proprietary product with hidden methods and MS does not publish all API's and class details. I honestly don't believe it was that arbitrary--MS had their reasons even if they don't share it.
What object model does it belong to?
From what is described in documentation AND from exploring details in the VBA Object Browser and using some VBA methods like TypeName
, etc., it appears that the Containers
collection and Container
objects are indeed part of the DAO object model. However, the Container objects (and related Document objects) themselves can refer to and/or hold objects outside of the DAO object model. Strictly speaking, the concept of an Access Form is outside of DAO. The actual classes and object for Forms are part of the Access object model.
To go a little further, the various collections are not just simply "open forms" vs. "all forms". Although they all return conceptual entities called "forms", they do not even return the same type of run-time objects. The CurrentDB.Database.Containers(FormContainerIndex)
collection returns Container
objects with Document
objects (where FormContainerIndex may or may not equal 2). The Application.CurrentProject.AllForms
collection returns instances of AccessObject
. The Application.Forms
collection returns actual form objects that are of specific form-class types.
I think this is a great question. The documentation links in the question reveal how confusing this can get, since various concepts are all blended together in context of Access. One tree of the MS documentation makes clear that DAO and ADO are distinct and separate from Access, but then another documentation branch puts the same objects together in a list of related data-access concepts.
Upvotes: 1
Reputation: 49204
Not really much of anything to write about here.
Access has some “container” objects. We could store pictures, PDF documents, or whatever in those containers.
And we could even store say the Relationship diagram in those containers. (Oh, wait – they did that!!!).
The containers are just that – some containers in the Access application.
As such, they can quite much arbitrarily be anything the desires of the Access application designers wanted to store in the containers.
I mean, really, this is not much different then a table. That table might have invoices, or say have some customers
To THEN infer that DAO has a “customers” object or an “invoice” object as part of the DAO object model would make little sense here.
The containers “objects” are just that – a container of things. They have little relevance to the DAO object model.
The “containers” is a list of objects provided by the Access system, not DAO.
There is no “containers” method or “containers” property of the DAO object model.
Now to be fair, the “native” database engine used in Access is JET (now called ACE). And to be fair, since the access database engine is tied VERY close to the DAO object model, then it is most certainly fair to state that Access (the developer tool) is tied far closer to DAO then it is to ADO.
While you are most free to use DAO or ADO for grabbing data from the JET/ACE engine, DAO is certainly the preferred choice here.
The “main” reason for this preference, is that DAO is VERY tight tied to the JET/ACE database engine. Access originally was built around the JET + dao library code, so its roots are tighter with the DAO object model.
However, if you going to grab data from SQL server, then for a long time, most developers preferred the ADO object model. There are several advantages to using ADO when say using SQL server, or say MySQL, or Oracle as the back end database with MS-access as the front end.
The “major” advantage of using ADO, is the SQL used for ADO is “closer” to the SQL syntax that the “industry” standard uses (ansi-92). As a result, your SQL you write with ADO will work (in general) without changes if you use SQL server, or say Oracle as the back end. (And you can likely switch between the two databases without having to change the sql syntax you use).
With DAO, you are using Access (jet) SQL syntax, or better said, JET/ACE syntax. When you using ADO, but STILL use the JET/ACE engine, you get to use the sql ansi-92 syntax. The result is your syntax for the sql will MUCH more match the syntax used on SQL server, or say oracle.
For an access + JET/ACE application, the recommended standard choice is to use DAO. (18 years ago, Microsoft changed the “default” object model to ADO in Access 2000. Developers staged somewhat of a “revolt”, and in Access 2003, they returned DAO as the default. (You can to this day, STILL choose either object model, or worse “intermix” the two – don’t go there!!!). So Microsoft did not force a change, but the “default” setting was ADO – but we just always changed the reference back to DAO and kept on writing code as we always did.
So for a good number of years, Microsoft was pushing everyone to use ADO – including the very popular MS-access system.
However, most of us developers ignored this advice from Microsoft, and continue to use DAO when building native access applications. And as noted, for a rather long time now, DAO is the default object model. Because DAO been somewhat “deprecated”, the Access team took the DAO object and code library and they now own this library. (Before it was simply a standard Microsoft library that all developers could use). So for V6, vb.net etc., they tended to use ADO.
So you can now “read” that DAO is deprecated, but Access uses an updated and newer version that is included with the ACE database engine. (So while DAO as a standalone object library is depreciated, the DAO code updates, and new features continue in Access as the ACE data engine object.
When you set a reference to the ACE data engine then all of your DAO code should work just fine. What this means (since access 2007), you do NOT need to set an external reference to the DAO object model – it is now part of the JET/ACE database engine. (Prior to access 2007, you had to set a reference to DAO. And if you were going to use ADO, you ALWAYS had to set that reference, and you still do to this day)
This change was made since really only the Access community and developers were using DAO – most other platforms were using ADO (for many reasons, but one big reason was ADO was NOT tied nor did it have roots of origin in the MS-access database engine like DAO does, and still does to this day.
Remember, for about 5-10 years, Microsoft did not have SQL server, so Access + DAO was their “big deal”. When they finally started selling SQL server, then of course things changed in regards to Microsoft pushing DAO. DAO was “primary” a MS-access data engine technology.
If you do in the future move the data from Access to say sql server, and continue to use MS-access as the GUI front end, the access community STILL suggests you stick with whatever object model you used to develop your application with. So access applications developed with DAO, but using sql server as the back end database work just fine, and should remain as such.
And if you developed with ADO, then you want to continue if you start using SQL server with Access. Note that I am talking about VBA code you write – specific ADO recordsets.
You still always use the “same” internal containers that exist in Access – these containers do NOT change if you use ADO or DAO when writing code to modify data in the access client.
ADO certainly has some advantages if you going to use say SQL server as the back end from “day 1” with Access as front end, but even in those cases, if your access application was written using DAO, then I would continue to use DAO – even with SQL server.
However, for .net developers, Visual Basic developers, they likely honed their skills using the ADO object model, and when they use MS-access as the development tool, then they can continue to use their “long time” familiar with the ADO data object model when writing code in MS-access.
As noted, I don’t recommend mixing the two object models in a given single application, as that just gets confusing.
edit:
To quote from this link: https://learn.microsoft.com/en-us/office/client-developer/access/desktop-database-reference/container-object-dao
Each Database object has a Containers collection consisting of built-in Container objects. Applications can define their own document types and corresponding containers (Microsoft Access database engine databases only); however, these objects may not always be supported through DAO.
Some of these Container objects are defined by the Microsoft Access database engine while others may be defined by other applications. The following table lists the name of each Container object defined by the Microsoft Access database engine and what type of information it contains.
Upvotes: 0
Reputation: 55961
It comes from:
Microsoft Access
You can easily check this:
? Forms.Parent.Name
Microsoft Access
This contains all forms, open or not:
Application.CurrentProject.AllForms
The current database refers to that container. These will return the same count:
? CurrentDb.Containers(acForm).Documents.Count
? Application.CurrentProject.AllForms.Count
CurrentDb (or any other DAO.Database object) is probably where DAO comes in - in the documentation you refer to.
Upvotes: 0