Access 2010:链接数据库、参考还是加载项?

Posted

技术标签:

【中文标题】Access 2010:链接数据库、参考还是加载项?【英文标题】:Access 2010: linked database, reference, or add-in? 【发布时间】:2017-09-05 17:51:40 【问题描述】:

环顾四周,找到了各种各样的答案,但最近没有真正比较这些选项的优缺点。所以我想我会要求社区权衡你喜欢哪条路线以及为什么。

背景

这就是我们所拥有的:

许多协议数据库中使用的通用 Access 模块和类集(Access 2010 *.accdb 拆分前端/后端) 前端链接到后端数据库表和代码(链接数据库) 后端包含协议特定的数据和代码 公共模块/类数据库不应由用户直接编辑

已知

插件和数据库参考数据库:

每次更改时都需要重新分发(即使其中没​​有更改任何代码)。 必须在他们的 IDE 与协议数据库的 IDE 中进行编辑(否则您将丢失所做的编辑,因为该 db 不是通用代码)

问题

公共模块/类数据库应该如何连接到协议数据库?

链接数据库就像后端一样 将其作为参考附加到 IDE(工具 > 参考) 创建加载项并将其添加为参考

你会怎么做?为什么?

有什么优点/缺点?

哪个选项可以最大限度地提高性能?

【问题讨论】:

这个问题肯定会引起自以为是的答案,因为没有“黄金标准”,而且很大程度上取决于您在做什么。我自己有一个链接数据库设置,我正在使用自动化将模块推送到前端。如果您想阻止用户编辑您的课程模块,您可以锁定它们以供查看并在完成后使用密码保护它们(注意:不是真正安全的,但也不是链接它并将其添加为参考)。 Erik,感谢您的评论 - 实际上,我很乐意接受固执己见的答案 - 我们都有自己的发展趋势;)您能否放大或添加一个链接来说明您的情况做自动化推送? 这样的问题在 *** 上是题外话。使用的一些代码可以在this answer 中找到(删除代码以创建新文件,以及您不想推送的任何对象的代码)。在我的设置中,我实际上使用了一个表单,该表单列出了文件夹中的所有前端以及所有表、查询、表单、模块等,它允许我选择要推送的内容。如果这个问题明天仍然存在,我可能会分享完整的代码(然后有更多时间)。 谢谢埃里克。查看提到的代码,所引用的“推送”更多地将模块/类放入前端,这并不是我想要的,但我愿意看看你如何使用它。我可能会发现它实际上比我想象的要好 - 我试图解决的根本问题是公共代码的扩散,因此是公共数据库。 没有足够的空间最后注:我不同意这个问题属于“离题”(***.com/help/on-topic)的想法。虽然是主观的,但希望那些具有真实经验的回答足够详细,以使问题具有价值,这里的“良好主观”线程:***.blog/2010/09/29/good-subjective-bad-subjective 实际上,对于许多开发问题有不同的解决方案。在这种情况下,只需尝试确定哪个是最好的给定约束和其他人的经验。我可以做任何一个,但有些会是更好的选择。干杯! 【参考方案1】:

我有以下代码的几种变体,我认为这个最适合您的情况(它从数据库中提取模块和表单,在数据库启动后立即覆盖现有的)。

Public Sub ImportModules()
    Dim ImportDbLocation As String: ImportDbLocation = CurrentProject.path & "\ModuleDb.accdb"
    Dim ObjectsToImport As Recordset
    Set ObjectsToImport = CurrentDb.OpenRecordset("SELECT * FROM Objects IN """ & ImportDbLocation & """")
    Do While Not ObjectsToImport.EOF
        On Error Resume Next
        DoCmd.DeleteObject ObjectsToImport!ObjectType, ObjectsToImport!ObjectName
        On Error GoTo 0
        DoCmd.TransferDatabase acImport, "Microsoft Access", ImportDbLocation, ObjectsToImport!ObjectType, ObjectsToImport!ObjectName, ObjectsToImport!ObjectName
        ObjectsToImport.MoveNext
    Loop
End Sub

此代码由前端数据库中的 AutoExec 宏触发。 称为ImportDbLocation 的数据库是包含我要导入的所有模块和表单的数据库。它包含一个名为Objects 的表。该表有两列,一列名为ObjectName,其中包含应拉取的所有对象的名称,另一列名为ObjectType,这是一个与acObjectType enum 对应的查找字段(删除了一些不相关的对象)。

优点:

您将获得数据库中所有模块的新副本,确保任何覆盖都无关紧要。 您可以在 Objects 表中添加第三列来过滤特定数据库的对象,从而选择性地将一些对象推送到某些前端,而将其他对象推送到其他前端(第四列用于指定对象的名称) ModulesDb 文件,为不同的前端使用相同形式的多个变体)。 您在前端拥有所有代码,因此外部文件和引用没有奇怪之处 您还可以使用此代码提取您想要的任何其他类型的对象(在我的情况下主要是查询和表单)

缺点:

加载时间增加(通常会增加一点点,但取决于导入的对象数量,可能会很长) 模块对最终用户可见和可读(技术上也可修改,但任何更改在数据库加载时都将撤消) 您无法修改以这种方式进行导入的模块 您需要适当的安全设置,否则用户将在每次打开数据库时收到安全弹出消息的垃圾邮件

我还有一个变体,它在打开时将模块从单独的线程异步推送到数据库,我还有另一个实现允许我在进行修改后有选择地将模块移动到前端。

如果需要,我可以共享它们,但尚未在生产环境中实现异步(仍在进行中,它应该可以节省加载时间并且可以推送所有模块)

【讨论】:

另一个缺点是代码未编译。它可能会运行(你会知道;我没有尝试过这种方法),但仍然可以。 @Gustav 你说得对,但我在实际使用中从未遇到过由它引起的错误。但是,您不应该从立即导入的模块中运行函数(在同一个子中),因为 DoCmd.DeleteObject 会以某种方式延迟,将创建模块的副本,然后该模块仍将被删除,但是将存在带有1 附加到其名称的副本,并且在下一次导入时,由于函数/类/子名称不明确,您将有2个模块和编译错误。但由于您是直接从 autoexec 宏调用 sub,这纯粹是假设。 感谢埃里克和古斯塔夫。这是一个有趣的选择。是否在网络上有许多用户的分布式系统中实现(网络上的公共数据库,用户将代码拉到本地存储的数据库)?当网络中断或笔记本电脑(例如)离线时,dbs 会工作吗? @NWdev 我在一个网络中使用它,同时数据库上有大约 5-10 个用户,但网络上有超过一千个用户在做不同的事情(大型公司网络)。但是,链接表将是您的问题,而不是链接代码。启动数据库时会拉取代码,之后将可以脱机使用。链接表不会(并且 WiFi 上的链接表可能会导致错误)。但是,您可以通过相同的方法拉取未链接的表,然后您可以离线使用数据库,但它是单向流,因此您无法对这些表进行更改。 此外,如果源数据库不可用,代码当前会引发运行时错误,但您可以通过在 .OpenRecordset 之前添加 On Error Resume Next 轻松抑制该错误,然后数据库将只使用以前导入的模块离线工作(并在网络连接开始后立即拉入新模块)【参考方案2】:

首先向@Erik 和@Gustav 致以深深的谢意。

解决方案

在我的用例中选择的解决方案是使用包含模块和类的通用参考库数据库。

虽然我考虑了@Erik's 解决方案,但最终将模块和类复制到每个协议数据库中有点像发送它们的副本,然后可以从主模块/类中转移出来。这部分是转向单一参考数据库的一个原因 - 以避免传播到其他数据库,因此它们将有一个单一的代码源。

警告:如果参考库解决方案存在性能问题,则可能必须从公共库数据库中提取类和模块,例如 @Erik's 解决方案。

数据库作为参考库

通用模块和类包含在数据库 (*.accdb) 中。每当需要另一个数据库中的代码时,都会添加一个引用,就像引用任何其他代码库 (VB IDE - Tools > References) 一样。唯一的区别是您 Browse... 到图书馆并确保您在搜索过滤器中选择 Microsoft Access Databases (*.accdb)

如果参考图书馆数据库保存在一个公共位置,那么重新参考应该不会有问题,尽管重新连接参考很容易(与最初的连接相同)。

我还将常见的版本控制和开发模块分离到类似的独立数据库中,这些数据库可以在开发期间根据需要进行引用,并在给定数据库投入生产时取消引用。

开发“陷阱”

实际上,这些是比真正的“陷阱”更多的注意事项/要记住的事情:

- Edit library classes & modules in the library database

如果您从引用库数据库的数据库中编辑类或模块,您将在关闭您正在使用的数据库后立即丢失编辑。

可以尝试从您正在使用的数据库中进行编辑 - 代码运行,但它不会保存

我经常打开 Notepad++ 或 OneNote 以将我正在测试的代码复制并粘贴到库数据库中。这样我就可以继续在其他领域工作,并进行一系列更改以更新图书馆数据库。

- Compile the library database before using its components in the referencing database

这更像是一个工作流程问题 - 确保您在库数据库中保存和编译,然后在完成更改后打开您的引用数据库并首先关闭库数据库。

资源

以下是一些有用的链接:

Using a centralized vba module in multiple access databases Using VBA Code Libraries in Access Database Applications Referencing VBA Projects as Libraries Demonstration Applications & VBA Code Libraries Classes in VBA Using Database Library Files in Your Access Application Object Oriented VBA: Design Patterns: Simple Factory Object Oriented VBA: Static Classes

第 6 篇参考资料(只能通过 Internet 存档获得)在整理如何正确实例化类方面特别有帮助。最后,我选择创建一个具有多个函数(每个类一个 - 例如NewClassABC())的工厂类(静态类),在公共参考库数据库中实例化该类。

到目前为止,一切都很好。

参考库数据库将代码保存在一处,其他协议数据库可以在需要时更新到它。无需处理同一模块或类的多个副本和版本。

希望这有助于其他寻找“通用”库类型解决方案的人。

【讨论】:

以上是关于Access 2010:链接数据库、参考还是加载项?的主要内容,如果未能解决你的问题,请参考以下文章

我可以将 Access 2010 数据库与 SharePoint 2013 一起使用吗

MS Access 2010:是不是可以链接数据表子表单

如何在拆分数据库中将表从前端链接到后端(MS Access 2010)

access 2010,语文

急求助,office 2010 Word,Excel的功能区突然消失了,点击展开功能区无效.在网上搜了很久没有找到解决办法

Access 2010 运行时错误 2185