在MS Access中,我有一个简单的数据输入表单.在屏幕的底部,您可以单步执行记录,并在每次单击时更新表单:
访问上一个下一个栏http://a.yfrog.com/img62/2654/5ge.png
我怎么能从表格上的组合框中做到这一点?也就是说,我希望能够从列表中快速选择一个项目并让表单显示该项目.
Dav*_*ton 15
在评论@ Remou完全有效且有用的答案时,我提到了这样一个事实,即find组合框向导会创建非常糟糕的代码.以下是为绑定列选择Autonumber 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
Run Code Online (Sandbox Code Playgroud)
有一点是错误的,你不能在现有的控件上运行它,所以你最终得到一个随机命名的组合框,当你更改组合框的名称时,你必须重新应用它到事件,并编辑它反映了名称的变化.但是,与向导代码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
Run Code Online (Sandbox Code Playgroud)
首先,完全没有理由定义任何类型的记录集变量,因为您可以直接在相应的记录集上轻松操作.
其次,如果你确实声明它,那么将它声明为Object变量实际上是相当防御性的编程.鉴于.FindFirst仅适用于DAO记录集,它始终是DAO记录集,这是其余代码可以处理的唯一记录集类型(无论表单的Recordset对象是否始终是DAO记录集 - 我我甚至不确定这是真的.因此,只有在应用程序中没有DAO引用的情况下运行时,才需要使用Object类型变量.
这似乎过于谨慎,但我的主要观点是,没有理由首先声明一个变量.
第三,如果你做一个记录赋给变量,你需要照顾好自己清理,并设置变量设置为Nothing在子结束,并关闭您创建的窗体的记录的克隆.
第四,没有理由使用表单记录集的克隆,因为RecordsetClone已经存在,并且其存在的全部原因正是这种用法.
第五,在组合框中处理Null值是疯狂的 - 即使你不想找到任何对我来说没有意义的事情,也要克隆记录源.如果它是Null,只需退出sub(或为退出点创建一个标签并跳转到那个),而不是经历克隆记录集和执行可以被证明无效的FindFirst操作的麻烦.
第六,FindFirst效率不高 - 它会对字段的索引进行顺序扫描,或者如果没有索引则通过表本身进行顺序扫描 - 因此如果您不需要首先启动,则需要避免启动.
第七,如果组合框为空,则使用Nz()返回0,如果0实际上是被搜索字段的有效值,则会产生不正确的结果.
第八,甚至做的FindFirst,当你删除了查找组合框中的值将当前记录回到第一位的,逻辑的行为反而会是离开当前记录无论是摆在首位你删除前值从查找组合框.也就是说,如果你没有搜索,就找不到东西!
第九,使用EOF作为测试假设FindFirst执行表扫描而不是索引扫描(我不知道它是否执行),并且FindFirst将指针移动到克隆的记录集中,即使存在没有结果(相反没有结果).
第十,为什么当每个记录集都有一个NoMatch属性正是为了这个目的而没有其他的时候使用EOF?在FindFirst命令之后进行测试时,它没有含糊之处,与EOF不同,后者报告记录指针是否已到达表的末尾.一个属性NoMatch具有狭义的含义,并不能代表任何其他东西,并且精确地存在于FindFirst操作之后,而EOF具有更广泛的含义,在此处用作其他东西的代理.
第十一,也是最严重的缺陷,如果在设置书签之前记录是脏的,则向导代码不会明确强制SAVE.这是一个关键的错误,因为这是在访问已经靠不住多年来的地区 - 的错误,从隐含发生保存由设置书签和精神的初始记录开始可能会丢失,从而导致数据丢失.从理论上讲,这是很久以前被修正了一个错误,但是,明确强制导航到另一个记录之前保存是最好的做法,因为你允许在保存操作的任何错误的导航操作indendently发生.
需要我多说?
为什么会这样?我的第一个猜测是该向导在MDB/ACCDB和ADP中生成相同的代码,但ADP表单无法返回DAO记录集,因此您不会使用FindFirst.也许在ADP中它使用Find而不是FindFirst.这可以解释为什么使用EOF而不是NoMatch,因为ADO记录集缺少NoMatch.
但是为什么我的MDB/ACCDB会因ADP的要求而瘫痪,这与它们无关?如果我是正确的,有确定是否使用Find或FindFirst的条件代码,那么为什么不进行整体操作并在运行向导的上下文中使用最合适的方法?
这是一个糟糕的代码,需要在调用向导时重写.它可能是更好的代码,但由于某些未知的原因,MS选择生成拙劣的代码.这与我用过的所有其他Access向导生成的代码形成鲜明对比 - 在某些情况下我可能会发现它们有点过于冗长,但在可扩展性方面有很好的理由.我根本无法理解为什么这个特殊的向导产生如此糟糕的代码.
您可以使用向导将组合框添加到绑定表单中。该向导提供的选项之一是“根据我在组合框中选择的值在我的表单上查找记录”。如果您的表单很复杂,您可能看不到此选项,在这种情况下,创建一个简单的表单来查看向导并生成示例代码 - 并不总是最好的代码,但肯定非常有用。
有一些小事情可能会或可能不会困扰您,例如,如果用户在不使用组合的情况下移动到记录,则组合不会更改以显示新记录,但这很容易通过一点点修复表单当前事件中的代码。
| 归档时间: |
|
| 查看次数: |
40912 次 |
| 最近记录: |