Microsoft Access 应用程序开发指南






4.40/5 (5投票s)
一些用于开发更好的 MS Access 解决方案的指南。
动机
本文档为创建 MS Access 解决方案的开发人员定义了一套指南。由于 MS Access 旨在供 IT 专业人员和非专业最终用户同样使用,它包含了针对这两类受众的功能,这些功能不应混淆。
从专业的角度来看,当打算开发一个专业、可扩展且可靠的 MS Access 解决方案时,并非 MS Access 提供的每一个便利功能都应该使用。遵循本文档中的指南可以防止开发人员从一开始就使用那些便利功能,因为他们稍后才会意识到,这种便利会逐渐搞乱一个清晰的软件架构和数据库设计。
然而,不假思索地遵循这些规则并不会自动带来清晰可靠的软件。每条指南都可能被违反,无论是在个别情况下还是在整个项目中。以适当的方式记录这些违规行为是有意义的。
以下规则仅涵盖特定于 MS Access 的指南。它们不涵盖任何通用的数据库设计规则,如规范化、事务、ID 生成等。这些指南也不涵盖通用的编程指南主题,如命名约定、代码缩进等。所有这些规则已在许多其他在线文章中讨论过(例如,请参考 [1])。
规则
1. 工具配置规则
规则 1.1:使用目标 MS Office 版本进行开发
解释
尽管在类似目标的环境中进行测试似乎足以保证 MS Access 解决方案在客户系统上正常工作,但应考虑到,在开发阶段发现(甚至避免)问题比在测试阶段才发现要便宜得多。
因此,请在从未安装过较新版本的系统上,使用目标版本的 MS Windows、MS Access 和 MS Office(如果需要)进行开发。
风险
尽管新版本的 MS Access 可能会增加开发时的便利性,但开发人员最好还是回到客户解决方案所针对的 MS Access 版本。新的 MS Access 版本会引入新的特性和功能,开发人员可能会在不知不觉中使用它们。即使是较新版本的 MS Office 与较旧的 MS Access 结合使用(如 MS Office 2010 与 MS Access 2007),也可能产生困难,因为 MS Access 项目可能会引用新 MS Office 引入的较新的 DLL。另请注意,卸载 MS Office 可能不会像它应该做的那样从系统中删除每一个新的 DLL。
规则 1.2: 谨慎使用“名称自动更正”功能
解释
在 MS Access 中开发时使用“名称自动更正”功能确实可以帮助开发人员防止错误,并了解所有对象(表、查询、窗体和报表)之间的关系。
但对开发人员来说,了解“名称自动更正”功能在后台如何工作非常重要,因为它有时可能表现得与预期不同(另见 [2])。了解背景后,开发人员只需遵循以下简单规则,即可从此功能中获得预期的结果。
了解“名称自动更正”功能的限制。
请注意,“名称自动更正”功能对宏、数据访问页、VBA 代码、联合查询、传递查询和数据定义查询不起作用。它也不会将连接的后端文件中的表的更改传播到前端文件。
激活“名称自动更正”后,打开每个 MS Access 对象。
当为一个以前禁用“名称自动更正”的数据库启用该功能后,开发人员应逐个打开并关闭每个表、查询、窗体和报表,以便“名称自动更正”功能可以正常工作。“名称自动更正”仅在打开 MS Access 对象时才进行其内部关系结构的重新计算。
更改后打开每个 MS Access 对象,以开始将更改传递给依赖对象。
在重命名某些内容后,逐个打开并关闭每个表、查询、窗体和报表,以允许“名称自动更正”功能正确检测损坏的引用。
在一个对象的名称更改后,在更改已传播到每个依赖对象之前,不要创建同名的新对象。
在以下情况下,它无法检测到损坏的依赖关系:
tabel1
被form1
引用table1
重命名为table2
- 在
form1
打开之前创建了新的table1
结果:下次打开 form1
时,“名称自动更正”功能无法检测到对 table1
的依赖关系已损坏,因此不会将其更正为 table2
。
解决方案是,在将名称从 table1
更改为 table2
后,打开 form1
,以便“名称自动更正”可以更正损坏的依赖关系。之后,可以毫无顾虑地创建新的 table1
。
风险
不详细了解“名称自动更正”功能的工作原理并且不遵守上述规则的风险是(在“名称自动更正”仍开启的情况下),该功能会导致意外行为,更新或更改某些内容可能会破坏关系,而本应期望自动修复。
但是,完全禁用此功能也不是一个合适的解决方案,因为它可以支持开发过程,防止引入新的错误,并积极支持保持对整体关系结构的概览。
2. 架构规则
规则 2.1: 将应用程序分为三层:数据、模型和视图
解释
即使将窗体直接连接到表很方便,也强烈建议不要这样做。每个报表和每个窗体都应使用查询层来连接数据。甚至 VBA 代码通常也不应直接操作表,而应操作查询来检索或操作数据。
此外,查询应作为存储在表中的数据与该数据的视图之间的抽象层。对同一表的不同查询实现了对相同数据的不同视图,例如,来自不同的视角、不同的用户角色、不同的访问或安全级别。
在使用查询的这种方式下,表设计的更改(例如,为了性能改进)可能只会导致查询更新,而根本不需要触及报表和窗体。
另请参考规则 6.1。
风险
从应用程序内部的不同层访问相同的数据,将导致比必要的更复杂的复杂性和对开发人员的困惑。应用程序将更难测试,无论是自动测试还是手动测试。让新开发人员熟悉项目,或者甚至是同一位开发人员在长时间后由于增强功能而重新接触,都会变得更加复杂和耗时。
异常
然而,在极少数情况下,可能需要 VBA 代码直接操作表。例如,在后端更新的情况下,(前端的)VBA 代码可能会直接更改表及其关系。
规则 2.2: 分为前端和后端文件
解释
即使它只是一个小的 MS Access 应用程序,仅在文件级别上,无需引用任何数据库服务器,MS Access 应用程序也应被拆分为两个(或更多)不同的文件。包含后端的文件或文件应仅包含保存数据的表。包含前端的文件或文件应包含任何存储的 SQL 语句以及 GUI 元素,如窗体和报表。
风险
将包含后端和前端的 MS Access 文件作为一个整体部署,在以下方面可能存在风险或不利之处:
- 当多个用户同时使用时(文件存储在某个网络位置),单文件解决方案将变得缓慢且使用效率低下。相反,应部署双文件解决方案,其中唯一的后端文件存储在某个网络位置,而前端文件存储在每个用户的计算机上。
- 在解决方案已经投入生产使用后更新 GUI,存储在表中的数据将会丢失,或者迁移将变得复杂且昂贵。在拆分解决方案中,更新 GUI 就像将前端部署到用户的计算机一样简单,同时仍然连接到“旧的”后端。更新后端可以通过从新的前端更改表结构来实现,而不会破坏生产数据。
3. 表设计规则
规则 3.1: 不在表中配置查阅字段
解释
不要在表本身中使用查阅字段作为外键。应使用常规的整型 ID 来引用其他表中的主键。
在设计窗体或报表时,当然应该利用记录源或行来源,向用户呈现为外键字段准备好的便利数据。
风险
在许多情况下,当开发人员只能看到“查阅”的数据而不是外键字段中实际的“底层值”时,开发过程中的问题解决需要更多的时间。
在“查阅”的外键字段数据比实际数据更有帮助的情况下,应改用 SQL 查询。
规则 3.2: 防止表设计影响 GUI 实现
解释
不幸的是,表设计级别上的一些属性稍后会影响窗体或报表上的属性。特别是,这是指
- 表字段的说明,稍后将被复制到代表该字段的每个控件的状态栏文本中,
- 表字段的标题,稍后将被复制到与代表该字段的控件相关联的标签中,
- 表字段的验证文本和输入掩码,稍后将被复制到代表该字段的控件的相同属性中。
风险
尽管这看起来像是一种为每个字段自动设置正确标题和状态栏文本的舒适方式,但在几次重命名后,这会导致过多的混淆。此外,在 MS Access 应用程序拆分为前端和后端文件的情况下(另见规则 4),它将无法工作。
要描述表及其字段,应改用表属性中的说明字段。
规则 3.3: 不要将自动编号用作有意义的数据
解释
除了生成一个单独的、仅在应用程序内部使用的值外,不要将自动编号值用于任何有意义的目的(例如递增的数字或表中的行数)。
MS Access 中的自动编号值仅用于自动生成独特的数字。这个数字不会每次添加新记录时都加 1。此外,在压缩数据库和其他 MS Access 内部清理例程中,这个数字可能会被重新组织或更改。所以人们只能依赖该数字的唯一性——仅此而已。
人们甚至不能限制该数字的格式,例如生成一个精确的 6 位凭证号或类似的东西。
也没有任何必要将自动编号值重置为从零开始或任何没有间隙的连续顺序。如果表中仅有的三条记录的自动编号值为 0、1、2 或 25、1034 和 567,这对任何用户或开发人员来说都不应该有任何关系。
风险
因此,将这个数字用于除唯一性之外的任何附加含义都可能是非常危险和不可控的。
规则 3.4: 在有用的地方强制引用完整性
解释
单个记录之间的依赖关系必须符合表设计的预期关系。因此,这就是为什么必须为字段之间需要依赖关系的每个地方启用引用完整性。
风险
通过激活引用完整性,MS Access 确保不会存在没有主记录的从属记录,即它们所依赖的主记录已被删除。开发人员甚至可以选择强制执行此完整性的策略:要么拒绝删除主记录,要么在主记录被删除时也删除所有从属记录。
在表设计级别强制执行此规则将有助于开发人员在 GUI 或查询设计期间不会忽视这些规则。
规则 3.5: 在表设计级别实现完整性规则
解释
所有允许或不允许字段包含无数据、NULL 数据或零长度字符串的规则,都可以归纳为完整性规则。此外,还有关于表间字段关系完整性的规则(强制引用完整性、级联删除或更新)。
在每个字段上利用所有这些规则,在表级别配置一个整体的完整性系统。不要为了在窗体级别实现完整性系统而将这些规则设置得过于宽松。
风险
在窗体级别,开发人员很有可能忘记在每个窗体和控件上强制执行或检查某一条规则。这样,表迟早会被填充包含异常值或其他窗体或报表未预期的关系的数据,风险太高。
尽管表设计及其完整性系统也可能以有缺陷的状态部署,但由于用户界面错误而导致数据结构混乱的风险要高得多。特别是因为用户界面级别上的一条规则可能涉及许多窗体和控件,需要在 VBA 中妥善处理,而在表级别,每条规则仅在表设计期间的一个单点进行配置。
此外,在数据可以由其他系统提供(如从 Excel、其他数据库等导入)的接口上,如果完整性规则仅在用户界面级别实现,则不会被检查。因此,如果 MS Access 的数据库后端系统可以自行强制执行这些规则,它会降低从任何渠道输入非结构化数据的风险。
规则 3.6: 文本字段不应允许零长度字符串
解释
字段可以配置为接受包含 NULL 数据。NULL 数据是(不仅是)MS Access 的一个重要特性,它不强制用户在每个字段中都输入数据。除了 NULL 数据,字符串字段还可以配置为接受“零长度字符串”。此功能应被禁用。仅使用 NULL 数据来允许用户不在字段中输入任何数据。
风险
NULL 数据和“零长度字符串”是不同的内容。通过 VBA 代码处理它们需要使用不同的例程来检查或写入这些值。因此,当通过 VBA 访问表的字符串字段时,存在开发人员可能忘记处理所有这些异常值的风险。
异常
NULL 数据和“零长度字符串”值不仅是不同的值,而且各有其非常独特的含义。NULL 数据意味着“未知”。这就是为什么一个尚未被赋予内容(或在新记录上)的字段包含 NULL 值,因为到目前为止数据库对其内容一无所知。相比之下,“零长度字符串”意味着“已知为空”。在这种情况下,数据库明确知道该字段是空的(例如,因为它是以某种方式明确输入或由用户选择的)。
“学术学位”可以作为这里的绝佳例子。当它在新记录上或尚未输入时为 NULL(因此数据库对当前记录的学术学位一无所知),它稍后可能会被设置为零长度字符串(因此数据库现在知道它应该是空的)。
如果确实有必要对一个字段使用这两种不同的内容类型,开发人员可能需要考虑明确地使用它们。在这种情况下,在为该(些)字段进行 VBA 编码时应特别小心。在窗体和报表上,这两种不同的值也应以某种方式明确地显示给用户,并且用户应有能力将字段明确地设置为这些值中的每一个。
规则 3.7: 在表设计级别实现验证规则
解释
验证规则也是一种完整性规则,因为它强制执行有关同一记录不同字段的规则。因此,这就是为什么验证规则也需要在表级别实现,就像其他完整性规则一样。
风险
在用户界面级别而不是表设计级别实现验证规则的风险与不在表级别实现完整性规则的风险相同(请参考规则 3.5)。
规则 3.8: 不要在表级别设计中实现输入掩码
解释
与验证规则或完整性规则相反,输入掩码是另一回事。它们仅在用户界面级别限制输入,即使它们是在表设计级别配置的。因此,不要在这里使用这种约束。而是在设计窗体时使用它。
更重要的是,与其使用输入掩码来约束表本身接受的值,不如利用完整性规则、验证规则以及允许或不允许空字段、NULL 值和零长度字符串。
风险
在表设计级别使用此功能将影响稍后的窗体设计过程。开发人员不应在这里使用它,而应注意每个窗体上每个控件的配置。当稍后在表级别更改输入掩码时,更改可能不会传播到每个窗体。更糟糕的是,如果它仍然可能被传播,它可能会覆盖窗体设计上已经更改的输入掩码。
在表设计上使用输入掩码也阻止了开发人员在表级别输入意外数据以正确测试窗体和报表。
对于来自其他接口(例如从 Excel、文本文件或其他数据库导入)的数据,输入掩码也不会被考虑。因此,意外的数据可能会被导入数据库,并且必须由可能未经测试以正确处理这些数据的窗体和报表来处理。
规则 3.9: 表应配置为没有子数据表
解释
将每个表的“子数据表名称”属性设置为“[无]”。此功能默认设置为“[自动]”。它主要用于向用户显示一对多关系。
风险
如果保持此属性激活,可能会显著降低性能并增加数据库的大小。因此,如果不使用此功能,应禁用它。
此外,这里只能显示主表与其子表之间的一个(可能是多个)关系。
开发人员应考虑创建窗体-子窗体(或报表-子报表)来向用户显示此类关系,而不是使用 MS Access 的这个自动功能。
4. 查询和 SQL 设计规则
规则 4.1: 无表通用的 SQL 语句
解释
不要实现将作用于不同表(例如借助参数)的 SQL 语句。使用参数传递数据是可以的。但至少为每个表创建单独的 SQL 语句。
风险
当 SQL 语句过于通用时,在表的更改或错误修复时维护它们将变得困难。更新通用的 SQL 语句很容易被忽视。相反,当使用带有硬编码表引用的 SQL 语句时,MS Access 可以帮助识别所有需要在表更改时检查的 SQL 查询。
规则 4.2: 无复合 SQL 语句
解释
避免以一次性解决多个任务的方式实现 SQL 语句(例如,使用多个参数)。
反面例子:克隆一条记录并同时更改克隆记录上的 field2(通过参数 parForField2)
INSERT into tab(field1, field2, field3)
SELECT tab.field1, parForField2, tab.field3 FROM tab
WHERE tab.ID = parForId;
如果原子性和数据一致性是这里的关注点,请使用事务而不是复合 SQL 语句。
风险
一旦项目复杂度增加,或者客户需求需要实现越来越多的更改,最终将需要复合语句中的每个单独功能独立存在。
对于上面的例子,将克隆和更新这两个不同的任务分成两个不同的语句。
克隆…
INSERT INTO tab(field1, field2, field3)
SELECT tab.field1, tab.field2, tab.field3 FROM tab
WHERE tab.ID = parForId;
…和更新
UPDATE tab
SET tab.field2 = parForField2
WHERE tab.ID = parForId;
5. 窗体和报表设计规则
规则 5.1: 无隐藏查询
解释
不要使用直接在窗体和报表的数据源属性中组装查询语句的可能性。也应尽可能避免在 VBA 代码中这样做。如果需要,请使用参数化查询。
MS Access 在一个面板中清晰地列出了所有存储的查询。通过这个功能,开发人员可以方便地跟踪所有需要的查询、它们的含义以及它们对数据的视图。在更改表的设计时,这是一个基本功能。
风险
在更改表设计时,开发人员可能会忽略某个隐藏的查询,从而有忘记更新它们的风险。此外,当查询被隐藏时,在更改表设计时可能会忘记或忽略对数据模型的特殊要求。
规则 5.2: 优先使用功能区按钮而非窗体上的按钮(Access 2007 或更高版本)
解释
窗体上的按钮甚至在调用按钮事件的 VBA 代码之前就可能改变网格视图中的选择。这是因为焦点会从网格视图转移到被点击的按钮上。特别是当点击主窗体上的按钮时,子窗体上的多记录选择会被取消。
如果操作是在功能区而不是在按钮上执行,这种情况不会发生。
风险
然而,为了通过使用按钮来避免这种行为,必须在窗体处于前台时循环地实现检查和记忆选择。这是有风险的,因为必须停止对最后选择的循环更新才能正确访问此信息(例如通过某种信号量)。
此外,实现和激活窗体的循环计时器例程,会干扰在该窗体在 GUI 上打开时对该窗体 VBA 模块的开发。
规则 5.3: 为添加新记录设计不同的窗体
解释
当使用数据表或网格视图来操作记录时,为添加新记录和操作现有记录使用不同的窗体。
风险
尤其是在对一行或多行选择进行操作时,开发人员需要注意“新记录”行的选择。
规则 5.4: VBA 代码中不应包含用户界面字符串
解释
在设计窗体或报表时,开发人员可能希望向用户显示消息,例如“记录已成功保存”、“操作已中止”或“草稿打印”。不要通过使用一个通用的消息标签,然后由 VBA 代码填充来设计用户界面上的消息。相反,为每个消息在窗体或报表上放置一个不同的标签(例如,彼此堆叠),并通过 VBA 启用或禁用它们的可见性属性。这样,GUI 设计和内容就与业务逻辑分离了。
风险
将用户界面设计与实现分开通常是有益的。重新设计或翻译影响代码更改的窗体或报表,有引入新错误的风险。此外,在设计阶段直接将所有消息放在 GUI 上,可以立即向开发人员显示结果。如果放置一个空标签供 VBA 稍后填充,可能会在开发阶段后期才显示出位置不当或字符串过宽或过短的问题。
6. VBA 编程规则
规则 6.1: SQL 优先于 VBA
解释
在业务逻辑层,尽可能多地用 SQL 而不是 VBA 来实现。例如,删除、更新或插入记录或更改表应实现为 SQL DML 查询,而不是在 VBA 中。然后可以通过 VBA 执行它。
另请参考规则 2.1。
风险
查询的任务是访问数据层并将其连接到视图层。当数据层被更改时(例如,通过向应用程序添加新功能),开发人员倾向于首先检查查询层以了解该更改的影响。依赖于特定表设计的 VBA 代码的更改更难实现,开发人员可能会忘记更新很少使用的 VBA 例程。
异常
然而,在极少数情况下,可能需要 VBA 代码直接操作表。例如,在后端更新的情况下,(前端的)VBA 代码可能会直接更改表及其关系。
规则 6.2: 与 GUI 无关的 VBA 代码
解释
窗体和报表及其 VBA 代码很难进行自动化的单元测试。此外,已经有框架可以对单个 VBA 例程进行回归测试。因此,作为可测试性开发的最佳实践,是将尽可能多的功能从窗体或报表 VBA 代码模块中提取到单独的模块或类中。这样,大部分编写的代码都可以更容易地进行单元测试。
风险
实现的功能可能会引入在通过 GUI 难以重现的情况下未被发现的错误。增强功能也可能会破坏已经正常工作的功能,如果开发人员不至少时不时地重新检查旧的东西。因此,开发一个没有或单元回归测试太少的 MS Access 解决方案不是一个好选择。
规则 6.3: 强制显式变量声明
解释
要强制开发人员显式声明在 VBA 代码中使用的任何变量,请使用
Option Explicit
可以通过在 VBA 编辑器的选项对话框中设置“要求变量声明”,来配置 VBA 编辑器自动将这行代码添加到任何新创建的模块的顶部。但请记住,此设置仅影响新创建的模块。已经存在的模块保持不变,必须在之后手动更改。
风险
不使用此选项,VBA 开发人员无需在使用变量之前声明它们。这起初看起来更方便。但这会阻止编译器自动发现拼写错误的变量,这可能导致非常难以找到的错误。
首先声明一个变量也定义了它的数据类型,并同时将该变量的使用限制在该数据类型上。因此,编译器也能够发现不打算用于该变量的用法。例如,将一个姓氏放入一个长整型变量中,而该变量本意是用来存储年龄的,当稍后检查该变量是否大于 21 时,肯定会产生问题。
规则 6.4: 明确声明对象为 DAO 或 ADO 类
解释
在使用 DAO 或 ADO 对象和方法时,许多对象和方法的名称是相同的。为保证无歧义,通过明确引用 DAO 或 ADO 库来定义 DAO 或 ADO 对象是至关重要的。
Dim rstAdo as ADODB.Recordset
Dim rstDao as DAO.Recordset
风险
Dim rst as Recordset
当定义一个 Recordset 对象而没有引用其库时,如上面的变量所示,不清楚这里将使用两个库中的哪一个。这取决于项目引用中 DAO 和 ADO 库的配置顺序。如果两个库都被引用,则将使用首先引用的那个库。现在,如果开发人员使用 rst 的属性和方法,而这些属性和方法是另一个库所独有的,那么它将产生一个可能难以理解的编译器警告。更糟糕的是,两个库中都存在(按名称)的属性和方法,其行为可能不同,或者返回不同的值或数据类型,这可能引起更难找到和修复的运行时错误。
规则 6.5: 避免使用对象的默认属性
解释
由 Microsoft 预定义的对象带有一个预先配置的“默认属性”。这是一个特定的属性,当在期望访问该对象属性的地方访问该对象时,会返回该属性的值。
不要使用访问该默认属性的方式。相反,要明确地访问每个属性。
风险
ComboBox 对象的示例
If Me!cmbClerks = vbNullString Then …
在这个例子中,VBA 编译器会自动识别出 Me!cmbClerks(对象类型)与 vbNullString(字符串类型)不兼容。这就是为什么这个条件应该编译失败。但编译器没有抛出编译失败,而是检查“默认属性”,这是一个返回字符串的属性值。在这种情况下,由于值可以与 vbNullString 进行检查,因此可以正确评估该条件,但可能不是开发人员的意图。
对于上面的例子,应改为执行以下操作
If Me!cmbClerks.value = vbNullString Then …
或
If Me!cmbClerks Is Nothing Then …
按照开发人员的意图。
在这里,第一个解决方案检查 Me!cmbClerks.value 是否包含任何值(用户已选择或输入一个值),而第二个解决方案检查 Me!cmbClerks 是否仍未初始化。两者有非常不同的含义。更糟糕的是,并非每个对象类型都可能将 value 属性定义为其默认属性。不同的对象类型可能有非常不同的已定义默认属性。
所以,为了保证无歧义,不要相信默认属性。
规则 6.6: 不要向 MS Access 宏返回值
解释
尽管 MS Access 宏只能调用 VBA 函数,而不能调用 VBA 子过程,但 VBA 函数返回的值将被忽略。
因此,如果一个带有返回值的函数需要由宏调用,应将该函数调用封装在另一个 VBA 函数中,然后由宏调用该函数。这个 VBA 函数(尽管定义了返回值数据类型)根本不需要调用 return 语句。这个函数应该对其封装的函数调用的返回值做出适当的反应,例如向用户报告错误、停止操作、关闭数据库等。
风险
通常,返回值包含有意义的信息。忽略它们可能导致意外的行为,尽管可能只在极少数情况下发生。但多次使用一个软件程序,可以相信每个“罕见情况”迟早都会发生一次。这就是为什么对一个有意义的返回值做出适当的反应是必不可少的。
参考
[1] RVBA 编码约定:http://www.xoc.net/standards/rvbacc.asp
[2] Microsoft Access 中名称自动更正的工作原理:http://msdn.microsoft.com/en-us/library/aa139941(v=office.10).aspx
更新历史
- 2012年5月10日 - 初始版本。版本 1.0.
关于作者
简而言之:我是一名 C 语言嵌入式解决方案的软件开发人员。
那么这与 MS Access 和 VBA 编程有什么关系呢?首先,虽然我主要进行 C 语言编程,但我们在工作中使用了许多 MS Office 自动化工具来完成许多不同的任务:C 代码生成、软件参数处理、单位转换、控制器和公式建模、成本估算、文本处理和美化以及许多其他流程管理工具。所有这些工具都是我们自己开发的,主要是在 MS Excel 和 MS Word 中。这就是为什么,在多年来定期使用 VBA 之后,我现在对 VBA 编程语言和整个 MS Office 自动化系统有了透彻的理解。
此外,由于我已经对 VBA 编程有深入的了解,我从事一些 MS Office 编程的自由职业工作——主要是 MS Excel 优化和 MS Access 编程,至今已有好几年了。特别是当 MS Access 解决方案可能从一个简单的“快速而粗糙”的工具成长为一个成熟的数据库解决方案,需要数周或数月的工作时,从一开始就保持代码、数据库和用户界面的设计和架构清晰且经过深思熟虑就非常重要。然而,关于良好的数据库设计和 GUI 设计,互联网上有很多文章,也有书籍可供参考,开发人员在开始大型项目之前绝对应该阅读。但 MS Access 仍然有一些特殊性,需要额外考虑,以建立一个良好且可靠的解决方案。
这就是为什么我根据我迄今为止在 MS Access 开发中所获得的经验写了这篇文章。