Search code examples
objectms-accessdao

MS Access: What object model does the container object Forms belong to?


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:

  • Minor problem: It has a container object called "Relationships" and not "Relations". Does this indicate a typo in the documented list of container objects quoted above?
  • Worse problem. The list of DAO container objects includes one called "Forms". Note that this is NOT the same as the object of the same name in the Access object model. The MS documentation on the Access object Forms says that it includes only open forms. That page says that the Access object that includes closed forms is AllForms. In an Access file with one form which is currently closed, in the Immediate Window, ? 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.


Solution

  • 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:

    • Technically, an "object" model is a bad choice of words since the more proper term is a class model. Generally, an object is an in-memory instance of class. During run time, there is indeed a hierarchy of actual objects, but sometimes it useful to refer not to a particular instance (i.e. object), but rather the overall class. I usually try to be very careful about the terminology, but especially in reference to some of these older models, the names and terms used in documentation are (frankly) sloppy. This is a disclaimer for all of the failed terminology. I'll do my best to clarify where a distinction is critical to understanding.
    • There is redundancy in the various object models related to Access. There may be good reasons for some of this redundancy, but at least some of the redundancy may have no good reason (at least none that are published). Rather some parts of the various components are a result of a mature product that has evolved over time. Different information needs to be exposed at different levels, but rather than just making the entire model open and accessible and consistent, it was designed with an "as needed" paradigm.
      • The redundancy exists both
        • in name: Different classes with the same or similar names are not identical, but may provide a different set of methods and properties for manipulating the same underlying entity. This is likewise true for names of collections and enumerations. Sometimes they don't even manipulate the same underlying entity, although they may provide similar functionality (like ADO.Recordset and DAO.Recordset)
        • in availability: Some identical objects are exposed via different collections and properties of different parent/container objects.

    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.