5.3 DAO数据访问与事件驱动


5.3 DAO 数据访问与事件驱动

本节摘要:DAO 是 Access 自己的原生数据访问对象库,核心三件套是 Database、Recordset、Field。本节讲清对象层级的走位、记录集的打开模式与遍历写回套路,再把代码挂到正确的窗体事件上——BeforeUpdate 与 AfterUpdate 的分工是全节枢纽。

语法学会之后,离"让系统自己干活"还差最后一块拼图:怎么在代码里正式读写表。Access 给出的原厂答案是 DAO(Data Access Objects)——一个专为 Jet 或 ACE 引擎设计的对象家族,也是 Access 内嵌的官方路线。

一、对象层级:一图先记住走位

DAO 的世界像一座档案楼:

  • Database 是整栋楼,代表当前打开的库文件,CurrentDb 一个函数就到手;
  • TableDef 与 QueryDef 是楼层里的房间清单,描述表与查询的定义;
  • Recordset 是从某个房间搬出来的一批档案卡片,你的读写几乎都发生在它身上;
  • Field 是单张卡片上的某栏,取值赋值都在这层完成。

走进去的标准路线代码里长这样:

Dim db As DAO.Database Dim rst As DAO.Recordset Set db = CurrentDb ' Set 关键字给对象变量赋值 独家规矩 Set rst = db.OpenRecordset("货品", dbOpenDynaset) Do While Not rst.EOF If Nz(rst!现有量, 0) < rst!安全库存 Then Debug.Print rst!品名 & " 需要补货" End If rst.MoveNext Loop rst.Close Set rst = Nothing

四个新手必踩点全部埋在这段里了,逐个排雷:其一,对象赋值必须带 Set 前缀,漏写的后果是把对象的默认属性值存进变量,报错还是幸运的;其二,感叹号简写 rst!现有量 等价于字段集合查找,日常首选;其三,Nz 函数把 Null 化为给定的替身(这里是零),Null 传染性极强,凡可能为空的列都该套一层;其四,MoveNext 忘写是 DO 循环死机事故排行榜冠军,Close 与置 Nothing 则是放回档案卡的良好教养。

二、打开模式的取舍

OpenRecordset 第二个参数决定你拿到什么性质的结果集,常用两档差异要分清:

模式 特征 适用
dbOpenTable 直连表最快 可用索引定位 Seek 单表高频读写 大批量
dbOpenDynaset 动态集 支持联接来源 可更新 多表来源或查询结果
dbOpenSnapshot 只读快照 内存友好 报表数据 纯展示

经验法则:写报表就 Snapshot 只求快;做编辑窗体用 Dynaset 保可写;真有上万行的整表搬运再考虑 Table 加索引 Seek 这条高速路。

图题:一次库存联动写入的完整链路

图题:一次库存联动写入的完整链路

三、事件驱动:代码挂在哪儿

窗体上的每个控件自带一串"事件钩子"——点击、双击、获得焦点、数据变化前后。在属性表的"事件"页选定事件,选择"代码生成器",VBE 会自动开出空过程让你填肉。真正需要刻进脑子的是这一对:

BeforeUpdate(更新前):数据即将写盘前的最后关卡。在这里检查业务规则,不合规就把系统的 Cancel 参数设为 True 并滚回焦点——错误数据根本无法落地。它的黄金地位来自时机:此时用户还没离开控件,纠正成本最低。

AfterUpdate(更新后):落库之后触发的联动点。经典的例子是选完客户自动带出其结算方式填到单头;库存扣减这种衍生写入也属此列——彼时原始数据已经板上钉钉,派生动作建立在确凿事实之上。

把这个时序纪律上升成团队规范不过四句话:先校验后落库,前事件守门;先落库后联动,后事件发货;边界之外的丑活交给提交按钮统一编排;任何事件过程开头先 On Error 护网。 违反第四句的下场见下一段真实翻车实录。

四、实战复盘:库存扣减的全部代码

华彩录单台最终版的联动模块长这样,逻辑浓缩但五脏俱全:

Private Sub 表单_明细_AfterUpdate() Dim db As DAO.Database, rst As DAO.Recordset On Error GoTo 兜底 ' 没有护网的联动 等于裸奔开道闸 Set db = CurrentDb ' 参数化条件 双引号包中文 单引号包内层字串 Set rst = db.OpenRecordset( "SELECT 现有量 FROM 货品 WHERE ID = " & Me!货品ID, dbOpenDynaset) If rst.EOF Then MsgBox "货品档案异常 请重新选择" GoTo 收尾 End If If rst!现有量 < Me!数量 Then MsgBox "库存只余 " & rst!现有量 & " 已按最大可用量登记" End If rst.Edit ' 进入编辑态 三步舞第一拍 rst!现有量 = rst!现有量 - Me!数量 ' 第二拍 改值 rst.Update ' 第三拍 提交 Me.Requery ' 屏上数字同步新现实 收尾: rst.Close Set rst = Nothing Exit Sub 兜底: MsgBox "库存更新失败 " & Err.Description & " 请联系管理员 并手工核对库存" End Sub

拆两个精华细节。Edit 三步舞:改 Recordset 字段值必须先进 Edit 态、改完必须 Update,这是 DAO 与普通变量的本质区别,跳拍则改动无声丢失;Me 关键字指代当前窗体自身,Me!货品ID 直接引用屏上控件的现值,代码因此跟着窗体走、拷贝即用。另外注意失败分支的话术设计延续了 4.3 的人话工程——不但报错,还提醒核对库存,因为扣减失败的补偿路径可能已经被执行了一半。

三条新手期最省事的小抄

查找别遍历。 在记录集里定位某条记录,第一反应应该是 FindFirst 加条件,而不是 Do 循环逐行比对——前者引擎代劳,后者费力还慢。"是否找到"的判据是 NoMatch 属性,别忘了先 Recordset 本身要可搜索类型。

多步写入包事务。 一次业务动作要写两张表时,套上 BeginTransCommitTrans,中间任何一步出错走 Rollback——两行护住一致性,成本几乎为零。详细原理第 8 章揭晓,这里先把模板抄走。

Clone 一份做参照。 窗体绑定的记录集移动会连带屏幕翻页;想在不打扰用户的前提下"偷看"数据,用 Me.RecordsetClone,它与屏上记录同源却各行其道,是联动查询的老搭档。

最后的忠告留给实践顺序:先把本节的 Recordset 三步舞写熟,再去碰更炫的对象花园。华彩项目的 DAO 代码两年里最常被复用的恰恰是那些朴素的 OpenRecordset 加 Edit Update 小函数——对象模型的甜头要靠数量堆出来,基础件的可靠性永远是整个自动化层的地基。

本节的压舱石

  • 对象楼梯 Database、Recordset、Field,Walk 路线四雷区:Set 缺失、Null 传染、MoveNext 遗忘、用完不 Close。
  • 打开模式按用途选:编辑 Dynaset、报表 Snapshot、海量搬运 Table。
  • 事件分工铁律:校验挂更新前,联动挂更新后,顺序装反就是数据事故。
  • Edit 与 Update 成对出现,DAO 写操作的基本礼仪。

下一节更进一步:让 VBA 手握 SQL 这个大杀器,处理动态多变的战场。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U