gpt4 book ai didi

ms-access - 如何根据 Access 中的组合框调出记录?

转载 作者:行者123 更新时间:2023-12-04 09:56:28 25 4
gpt4 key购买 nike

在 MS Access 中,我有一个简单的数据输入表单。在屏幕底部,您可以逐步浏览记录,并在每次单击时更新表单:
access previous next bar
(来源:yfrog.com)
如何从表单上的组合框执行此操作?也就是说,我希望能够从列表中快速选择一个项目并让表单显示该项目。

最佳答案

在评论@Remou 完全有效且有用的答案时,我提到了这样一个事实,即查找组合框向导会创建非常糟糕的代码。这是当您为绑定(bind)列选择自动编号 PK 时向导创建的代码(如果您搜索的是文本字段而不是数字字段,向导创建的代码会略有不同,但这还不够):

  Private Sub Combo2_AfterUpdate()
' Find the record that matches the control.
Dim rs As Object

Set rs = Me.Recordset.Clone
rs.FindFirst "[InventoryID] = " & Str(Nz(Me![Combo2], 0))
If Not rs.EOF Then Me.Bookmark = rs.Bookmark
End Sub

它的一个问题是你不能在现有控件上运行它,所以你最终会得到一个随机命名的组合框,当你改变组合框的名称时,你必须将它重新应用到事件中,然后编辑它反射(reflect)了名称的变化。但与向导代码 itelf 中的其他问题相比,这相对较小,每创建一行代码的错误率至少为 2.5 个问题。

这是我的替代代码:
  Private Sub cmbFind_AfterUpdate()
If IsNull(Me!cmbFind) Then Exit Sub

With Me.RecordsetClone
.FindFirst "[InventoryID] = " & Me!cmbFind
If Not .NoMatch Then
If Me.Dirty Then Me.Dirty = False
Me.Bookmark = .Bookmark
Else
' put your not found code here, but you really shouldn't need it
End If
End With
End Sub

首先,绝对没有理由定义任何类型的记录集变量,因为您可以轻松地直接对适当的记录集进行操作。

其次,如果您确实声明了它,那么将其声明为 Object 变量实际上是一种防御性编程。鉴于 .FindFirst 仅适用于 DAO 记录集,它始终是一个 DAO 记录集,它是其余代码可以处理的唯一记录集类型(无论表单的 Recordset 对象是否始终是 DAO 记录集——我甚至不确定这是真的)。因此,只有在应用程序中没有 DAO 引用的情况下才需要使用 Object 类型变量。

这似乎过于谨慎,但我的主要观点是首先没有理由声明变量。

第三,如果确实为变量分配了记录集,则需要自己清理并将变量设置为子文件末尾的 Nothing,并关闭您创建的表单记录集的克隆。

第四,没有理由使用表单记录集的克隆,因为 RecordsetClone 已经存在,它存在的全部原因正是为了这种用法。

第五,在组合框中处理 Null 值是疯狂的——即使在你不会找到任何东西的情况下继续克隆记录源对我来说也是没有意义的。如果它是 Null,只需退出 sub(或为退出点创建一个标签并跳转到该点),而不是经历克隆记录集并执行可以知道是徒劳的 FindFirst 操作的麻烦。

第六,FindFirst 效率不高——它通过字段的索引进行顺序扫描,如果没有索引,则通过表本身进行顺序扫描——因此,如果您一开始就不需要,则要避免启动一个。

第七,如果组合框为 Null,则使用 Nz() 返回 0 将产生不正确的结果,如果 0 实际上是正在搜索的字段的有效值。

第八,即使您从查找组合框中删除了值,执行 FindFirst 也会将当前记录移回第一个记录,而逻辑行为是在删除值之前将当前记录保留在任何位置从查找组合框中。也就是说,如果您不搜索,就不要找到任何东西!

第九,使用 EOF 作为测试假设 FindFirst 执行表扫描而不是索引扫描(我不知道它是否这样做),并且 FindFirst 移动克隆记录集中的指针,即使有没有结果(与没有结果相反)。

第十,当每个记录集都有一个 NoMatch 属性正是为此目的而没有其他目的时,为什么要使用 EOF?在 FindFirst 命令之后进行测试时,它的含义没有歧义,与 EOF 不同,EOF 报告记录指针是否已到达表的末尾。一个属性 NoMatch 具有狭义的含义,不能表示任何其他含义,并且恰好存在于 FindFirst 操作之后使用,而 EOF 具有更广泛的含义,在这里用作其他事物的代理。

第十一,也是最严重的缺陷是,如果在设置书签之前记录是脏的,向导代码不会明确强制执行 SAVE。这是一个严重的错误,因为这是 Access 多年来一直不可靠的一个领域——由于通过设置书签而离开初始记录而启动的隐式保存所发生的错误可能会丢失并导致数据丢失。从理论上讲,这是一个很久以前修复的错误,但在导航到另一个记录之前显式强制保存是最佳实践,因为您允许保存操作中的任何错误与导航操作无关。

需要我多说?

为什么会这样?我的第一个猜测是该向导在 MDB/ACCDB 和 ADP 中生成相同的代码,但 ADP 表单无法返回 DAO 记录集,因此您将无法使用 FindFirst。也许在 ADP 中它使用 Find 而不是 FindFirst。这将解释为什么使用 EOF 而不是 NoMatch,因为 ADO 记录集缺少 NoMatch。

但是为什么我的 MDB/ACCDB 会被 ADP 的要求削弱,而这与它们无关?如果我是正确的,有条件代码用于确定是使用 Find 还是 FindFirst,那么为什么不全力以赴并在运行向导的上下文中使用最合适的方法呢?

这是一段糟糕的代码,每次调用向导时都需要重写。它本来可以是更好的代码,但出于某种未知的原因,MS 选择生成拙劣的代码。这与我曾经使用过的所有其他 Access 向导生成的代码形成鲜明对比——我可能会发现它们在某些情况下有点过于冗长,但在可扩展性方面有充分的理由。我简直无法理解为什么这个特定的向导会产生如此糟糕的代码。

关于ms-access - 如何根据 Access 中的组合框调出记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3401645/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com