据我了解,DAO和ADO对象模型仅具有用于数据访问的对象,例如表和查询,而没有与数据表示有关的对象,例如表单和报表。
与此相符,MS documentation of DAO objects中的一长串对象不包括表格或报告。
另外,MS documentation on the DAO container object表示“下表列出了Microsoft Access数据库引擎定义的每个Container对象的名称”,并且该表列出了三个对象:数据库,表和关系。
但是,当我在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
我得到以下输出:
DataAccessPages
Databases
Forms
Modules
Relationships
Reports
Scripts
SysRel
Tables
此输出有两个问题:
? Forms.Count
= 0,但是? CurrentDb().Containers("Forms").Documents.Count
= 1。因此,这两个都称为“表单”的东西是不同的东西。此容器对象Forms似乎在任何地方都没有记录。它的存在似乎与上面引用的陈述相矛盾,即Access仅定义了三个容器对象。而且,由于它在DAO对象容器中,因此似乎也与DAO不包含表单和报表对象的想法相矛盾。
所以我的问题是,此容器对象表单来自何处?它属于什么对象模型?如果您知道答案,则可以链接到该文档的一些文档。
答案 0 :(得分:1)
如果您真的想掌握Access编程的详细信息,其他答案和联机文档都包含值得理解的有用信息。但是,它们通常排除假定的或遗忘的关键细节。在自己直接回答您的问题之前,请考虑以下几点:
它具有一个名为“ Relationships”而不是“ Relations”的容器对象。这是否表示上面引用的容器对象的文档清单中有错字?
是的,“关系”和“关系”之间的任何差异只是一个错误,可能没有更深的含义。
此容器对象表单来自何处?
这只是猜测,至少是对直接答案的尝试:
提供容器对象作为发现相关对象的向后参考。当MS Access通过DAO创建/加载数据库时,显然会出于自身目的添加其他Container对象。 DAO提供了一个通用的Containers集合,并允许其他对象添加到其中。
尽管DAO的目的只是简单地访问和表示数据本身,但显然MS认为提供一种通过DAO对象模型发布(也称为公开)相关对象的方法很有用。我认为它就像许多对象的Parent
属性一样。没有这样的Parent
属性,通常就没有内置的方法来确定对象与其源的关系。同样,在复杂的应用程序中,如果没有容器集合,可能没有其他方法可以确定数据库的各种详细信息。 Albert D. Kallal已经强调了DAO与Container对象之间不需要任何特殊的连接。也许Container类和对象确实没有任何有意义的关系,但是MS显然出于某种原因决定将其附加到DAO对象模型上,因此我发现缺少Kallal先生的解释。 Access仍然是具有隐藏方法的专有产品,MS不会发布所有API和类的详细信息。老实说,我不相信这是武断的-即使没有共享,MS也有其原因。
它属于什么对象模型?
从文档中描述的内容以及在 VBA对象浏览器中探索细节,并使用诸如TypeName
之类的某些VBA方法,看来Containers
集合和Container
对象确实是DAO对象模型的一部分。但是,容器对象(和相关的文档对象)本身可以引用和/或保存DAO对象模型之外的对象。严格来说,访问表单的概念不在DAO之外。表单的实际类和对象是Access对象模型的一部分。
再进一步一点,各种集合不仅是“开放形式”还是“所有形式”。尽管它们都返回称为“表单”的概念实体,但它们甚至都没有返回相同类型的运行时对象。 CurrentDB.Database.Containers(FormContainerIndex)
集合返回Container
个对象和Document
个对象(其中FormContainerIndex可以等于2,也可以不等于2)。 Application.CurrentProject.AllForms
集合返回AccessObject
的实例。 Application.Forms
集合返回具有特定表单类类型的实际表单对象。
我认为这是一个很好的问题。问题中的文档链接揭示了这种混淆的复杂性,因为在Access上下文中各种概念都融合在一起了。 MS文档的一棵树清楚地表明DAO和ADO是与Access截然不同且分开的,但是另一文档分支将相同的对象放到了相关的数据访问概念列表中。
答案 1 :(得分:0)
它来自:
Microsoft Access
您可以轻松地检查以下内容:
? Forms.Parent.Name
Microsoft Access
这包含所有打开或不打开的表单:
Application.CurrentProject.AllForms
当前数据库引用该容器。这些将返回相同的计数:
? CurrentDb.Containers(acForm).Documents.Count
? Application.CurrentProject.AllForms.Count
在您引用的文档中,CurrentDb (或任何其他 DAO.Database 对象)可能是DAO所在的地方。
答案 2 :(得分:0)
这里没有太多要写的东西。
Access有一些“容器”对象。我们可以在这些容器中存储图片,PDF文档或其他内容。
我们甚至可以将说关系图存储在那些容器中。 (哦,等等–他们做到了!!!)
容器就是这样-Access应用程序中的一些容器。
因此,它们几乎可以是Access应用程序设计人员想要存储在容器中的任何东西。
我的意思是,确实,这与表格没有太大不同。该表可能有发票,或者说有一些客户
然后推断DAO具有“客户”对象或“发票”对象作为DAO对象模型的一部分,在这里毫无意义。
容器“对象”仅是-事物的容器。它们与DAO对象模型无关。
“容器”是Access系统(不是DAO)提供的对象列表。
DAO对象模型没有“容器”方法或“容器”属性。
坦白地说,Access中使用的“本机”数据库引擎是JET(现在称为ACE)。公平地说,由于访问数据库引擎与DAO对象模型非常紧密地联系在一起,因此可以肯定地说,Access(开发人员工具)与DAO紧密联系而与ADO紧密联系。
虽然您最自由地使用DAO或ADO从JET / ACE引擎获取数据,但DAO无疑是这里的首选。
此首选项的“主要原因”是DAO与JET / ACE数据库引擎非常紧密地联系在一起。 Access最初是围绕JET + dao库代码构建的,因此其根源与DAO对象模型更加紧密。
但是,如果要从SQL Server获取数据,那么很长一段时间以来,大多数开发人员都更喜欢ADO对象模型。如果说使用SQL Server或说MySQL或Oracle作为后端数据库(使用MS-access作为前端),则使用ADO有许多优点。
使用ADO的“主要”优势是ADO使用的SQL与“行业”标准使用的SQL语法“更接近”(ansi-92)。因此,如果您使用SQL Server,或者说使用Oracle作为后端,则使用ADO编写的SQL可以正常运行(通常)。 (而且您可能可以在两个数据库之间切换,而不必更改使用的sql语法。)
对于DAO,您正在使用Access(喷射)SQL语法,或者更好的说是JET / ACE语法。当您使用ADO但仍使用JET / ACE引擎时,可以使用sql ansi-92语法。结果是您的sql语法将更加匹配SQL Server上使用的语法,或者说oracle。
对于访问+ JET / ACE应用程序,推荐的标准选择是使用DAO。 (18年前,Microsoft在Access 2000中将“默认”对象模型更改为ADO。开发人员在某种程度上进行了“反叛”,在Access 2003中,他们将DAO作为默认值返回。(您至今,STILL仍可以选择对象模型,或者更糟的是将两者“混合” –不要去那里!!)所以Microsoft并没有强制进行更改,但是“默认”设置是ADO –但是我们总是总是将引用更改回DAO并保留像往常一样编写代码。
因此,多年来,微软一直在推动所有人使用ADO,包括非常流行的MS-access系统。
但是,我们大多数开发人员都忽略了Microsoft的建议,并在构建本机访问应用程序时继续使用DAO。如前所述,在相当长的一段时间内,DAO是默认的对象模型。由于DAO被“弃用”,因此Access团队采用了DAO对象和代码库,现在他们拥有了该库。 (之前,它只是所有开发人员都可以使用的标准Microsoft库)。因此对于V6,vb.net等,他们倾向于使用ADO。
因此,您现在可以“读取”已弃用DAO,但是Access使用的是ACE数据库引擎附带的更新和较新版本。 (因此,当DAO作为独立的对象库被淘汰时,DAO代码将更新,并且新功能将在Access中继续作为ACE数据引擎对象。
当您设置对ACE数据引擎的引用时,所有DAO代码都应该可以正常工作。 这意味着什么(自2007年访问以来),您无需为DAO对象模型设置外部引用-它现在是JET / ACE数据库引擎的一部分。 (在访问2007之前,您必须设置对DAO的引用。如果要使用ADO,则始终必须设置该引用,直到今天仍然如此)。
之所以做出此更改,是因为实际上只有Access社区和开发人员都在使用DAO –其他大多数平台都在使用ADO(出于许多原因,但是一个重要原因是ADO不受限制,也不在MS-中具有起源)像DAO一样访问数据库引擎,直到今天仍然如此。
请记住,大约5到10年间,Microsoft没有SQL Server,因此Access + DAO是他们的“大事”。当他们最终开始销售SQL Server时,关于Microsoft推销DAO的事情当然发生了变化。 DAO是MS-access数据引擎技术的“主要”。
如果将来您将数据从Access移到sql服务器,并继续使用MS-access作为GUI前端,则访问社区STILL建议您坚持使用用于开发应用程序的任何对象模型。因此,访问使用DAO开发但使用sql server作为后端数据库的应用程序就可以了,并且应该保持这种状态。
如果您使用ADO开发,那么如果您开始将SQL Server与Access一起使用,则希望继续。请注意,我所说的是您编写的VBA代码-特定的ADO记录集。
您仍然始终使用Access中存在的“相同”内部容器-如果在编写代码以修改Access客户端中的数据时使用ADO或DAO,则这些容器不会更改。
如果您要从“第一天”开始使用SQL Server作为后端,而Access作为前端,ADO肯定会具有一些优势,但是即使在那些情况下,如果您的访问应用程序是使用DAO编写的,那么我将继续甚至在SQL Server上也可以使用DAO。
但是,对于.net开发人员,Visual Basic开发人员而言,他们很可能使用ADO对象模型来提高他们的技能,并且当他们使用MS-access作为开发工具时,他们可以继续使用熟悉的“长时间”在MS-access中编写代码时使用ADO数据对象模型。
如前所述,我不建议在给定的单个应用程序中混合使用两个对象模型,因为这会造成混淆。
编辑:
每个数据库对象都有一个由内置Container对象组成的Containers集合。应用程序可以定义自己的文档类型和相应的容器(仅Microsoft Access数据库引擎数据库);但是,并非总是可以通过DAO支持这些对象。
这些容器对象中的某些是由Microsoft Access数据库引擎定义的,而其他则可能是由其他应用程序定义的。下表列出了Microsoft Access数据库引擎定义的每个Container对象的名称及其包含的信息类型。 。
答案 3 :(得分:0)
不确定这是多么不合时宜,但我碰到了它,没有读完整个内容,所以我希望上面还没有回答。但是,从粗略的阅读看来,似乎有人错过了某处的东西。
以下是我用来尝试了解VBA怪癖及其结果的一些代码。结果首先,代码之后。
致电DumpDBContainers()
当前数据库包含9个容器
容器DataAccessPages包含0个文档
容器数据库包含3个文档
容器表单包含14个文档
容器模块包含20个文档
容器关系包含4个文档
容器报告包含0个文档
容器脚本包含22个文档
SysRel容器包含1个文档
容器表包含151个文档
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