我在MS Access 2003数据库中有一组ComboBox,它们都绑定到单个表中的字段。但是,它们允许您选择的数据不是来自该表,而是来自其他各种表。这适用于记录创建故事,但现在我希望能够追溯编辑记录。问题是我无法弄清楚如何在不编写一堆自定义代码的情况下重新填充表单元素。
我最初的倾向是提供一个组合框,限制您选择记录ID,然后执行自定义查询并使用它来设置所有不同表单元素中的选定值。但是,我觉得我应该能够做一些像DoCmd.GoToRecord , , , ID
那样简单的事情,并且表格应该重新填充。我并不反对做繁忙的工作,但我确信我只是因为对VBA和Access的相对微不足道的知识而遗漏了一些东西。
答案 0 :(得分:1)
只是添加到混合中,我会提供两种方法,一种推荐,另一种不推荐。
方法1:如果您已将表单绑定到整个数据表(这是非推荐的方法),您可以使用组合框向导导航到请求的记录,但我不建议在最新版本的Access:
一个。它不允许您在创建代码之前正确命名组合框。
湾代码只是错误。
这是我刚在测试数据库中生成的代码:
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
这在许多方面都是错误的,这是非常了不起的。这就是代码应该是:
With Me.RecordsetClone
.FindFirst "[ID]=" & Me!cmbMyComboBox
If Not .NoMatch Then
If Me.Dirty Then Me.Dirty = False
Me.Bookmark = .Bookmark
Else
MsgBox "Not Found!"
End If
End With
当RecordsetClone已经存在时,无需克隆表单的记录集。
当您可以直接使用预先存在的对象时,没有理由使用对象变量。
在离开记录之前需要检查脏记录,因为如果不强制保存,保存过程中的错误可能会导致数据丢失。
但更好的方法是:
方法2:使用组合框更改表单的基础记录源。
组合框的AfterUpdate事件如下所示:
If Not IsNull(Me!cmbMyComboBox) Then
Me.Recordsource = Me.Recordsource & " WHERE [ID]=" & Me!cmbMyComboBox
End If
现在,这只是第一次工作,就像第二次重置Recordsource一样,你最终得到两个WHERE子句,这是不好的。有两种方法:
一个。假设表单打开时没有WHERE子句,将开始记录源值存储在表单的OnLoad事件中的模块级变量中:
Private Sub Form_Load()
strRecordsource = Left(Me.Recordsource,Len(Me.Recordsource)-1)
End Sub
在模块级别,相应地定义strRecordsource:
Dim strRecordsource As String
然后在组合框的AfterUpdate事件中,你改为:
Me.Recordsource = strRecordsource & " WHERE [ID]=" & Me!cmbMyComboBox
现在,如果您的表单打开并且已经定义了WHERE子句,那么它会变得更复杂,但我不会进入并将其作为练习向读者留下最佳方法。
答案 1 :(得分:0)
我认为您已经为每个组合框设置了行源。只要你没有将组合框限制在该列表中;它应该显示您在该列中存储的内容。
但是,如果您的组合框更改了每行的列表,您可以在记录的OnCurrent事件或字段的GotFocus事件中执行类似的操作:
Me.combo_box_name.Requery
答案 2 :(得分:0)
重新阅读你的问题之后,我想我会看到你想要实现的目标。虽然在这种情况下我可能会使用GotoRecord
,但是你可能会使用OpenForm
,因为它有一个WhereCondition
属性,允许您使用SQL来准确指定要记录的内容打开。听起来您希望在表单中实现“跳转到记录”类型功能,用户从列表中选择记录ID,表单将更改以显示所选记录。
一种可能性是每次用户选择ComboBox中的项目时切换到新记录。您可以在ComboBox的Click
事件中处理此问题。
我将使用一个简单的示例:假设您有一个Students
表,并且StudentForm
用于查看/编辑Students
表中的记录。 StudentForm
有一个ComboBox cboStudentID
,它通过Students.ID
属性绑定到RowSource
列。当您在ComboBox中选择学生ID时,StudentsForm
将切换为显示相应的学生记录。
在ComboBox的Click
事件处理程序中,您可以使用以下内容对此“跳转到记录”功能进行编码:
Private Sub cboStudentID_Click()
Dim recordID As Long
'The ItemData property will return the value of the bound'
'column at the specified index.'
recordID = cboStudentID.ItemData(cboStudentID.ListIndex)
'Jump to the record. This assumes we want to use the same form.'
'You can change the form name if you want to open a different form when'
'the user selects an ID from the ComboBox.'
DoCmd.OpenForm "StudentForm", WhereCondition:="Student.ID=" & recordID
End Sub
正如David W. Fenton在评论中指出的那样,你可以缩短以下几行:
recordID = cboStudentID.ItemData(cboStudentID.ListIndex)
到此:
recordID = Me!cboStudentID
或只是:
recordID = cboStudentID
因为在这种情况下ComboBox的默认值将是当前ListIndex
处的绑定列的值。在这种情况下,您可以完全删除recordID
并对Click
事件进行编码,如下所示:
Private Sub cboStudentID_Click()
DoCmd.OpenForm "StudentForm", WhereCondition:="Student.ID=" & cboStudentID
End Sub