Ms access 如何根据Access中的组合框显示记录?

Ms access 如何根据Access中的组合框显示记录?,ms-access,forms,Ms Access,Forms,在MS Access中,我有一个简单的数据输入表单。在屏幕底部,您可以单步浏览记录,每次单击都会更新表单: (来源:) 如何从表单上的组合框中执行此操作?也就是说,我希望能够从列表中快速选择一个项目,并让表单显示该项目。您可以使用该组合框中的条件作为表单行源的基础,即 SELECT * FROM tblFoo WHERE bar=forms!frmMyForm!cboBar 然后在更新事件后的组合框上放置这行代码 Me.Requery 这应该可以做到,但自从我使用绑定表单以来已经有一段时间

在MS Access中,我有一个简单的数据输入表单。在屏幕底部,您可以单步浏览记录,每次单击都会更新表单:


(来源:)


如何从表单上的组合框中执行此操作?也就是说,我希望能够从列表中快速选择一个项目,并让表单显示该项目。

您可以使用该组合框中的条件作为表单行源的基础,即

SELECT * FROM tblFoo WHERE bar=forms!frmMyForm!cboBar
然后在更新事件后的组合框上放置这行代码

Me.Requery

这应该可以做到,但自从我使用绑定表单以来已经有一段时间了

您可以使用向导向绑定表单添加组合框。向导提供的选项之一是“根据我在组合框中选择的值在我的窗体上查找记录”。如果您的表单很复杂,您可能看不到此选项,在这种情况下,请创建一个简单的表单以查看向导并生成示例代码—虽然不是最好的代码,但肯定非常有用


有一些小问题可能会困扰您,也可能不会困扰您,例如,如果用户在不使用组合键的情况下移动到某个记录,组合键不会更改以显示新记录,但在表单的当前事件中使用一点代码很容易解决这一问题

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

它的一个错误是,您无法在现有控件上运行它,因此最终会出现一个随机命名的组合框,当您更改组合框的名称时,您必须将其重新应用于事件,并对其进行编辑以反映名称的更改。但与向导代码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
首先,绝对没有理由定义任何类型的记录集变量,因为您可以轻松地直接对适当的记录集进行操作

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

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

第三,如果确实为变量分配了一个记录集,则需要在完成后进行清理,并在子文件末尾将变量设置为Nothing,然后关闭创建的表单记录集的克隆

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

第五,在组合框中处理空值是疯狂的——即使你找不到任何东西,也继续克隆recordsource对我来说毫无意义。如果为空,只需退出子文件(或者为退出点创建一个标签并跳转到该文件),而不必经历克隆记录集和执行FindFirst操作的麻烦,这些操作可能是徒劳的

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

第七,如果组合框为Null,则使用Nz()返回0,如果0实际上是所搜索字段的有效值,则会产生错误的结果

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

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

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

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

我还需要多说吗

为什么是这样?我的第一个猜测是,向导会生成相同的c
  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