重新绑定访问组合框
我有一个可通过组合框搜索的Access 2007表单。添加新记录时,需要更新组合框以包括新添加的项目。
我认为需要在窗体的AfterInsert事件中做一些事情,但我不知道要做什么。
插入后如何重新绑定组合框,以便新项目出现在列表中?
解决方案
回答
我假设组合框是窗体上的控件,而不是commandBar中的组合框控件。该组合框具有一个名为rowsource的属性,该属性可以是值列表(丈夫;妻子;儿子;女孩),也可以是SQL SELECT指令(SELECT Table_relationType中的SELECT RelationshipDescription)。
我还假定窗体记录集与组合框记录集有关。我们需要做的是,一旦正确更新了表单记录集(我认为是afterUpdate事件),就重新初始化组合框控件的rowsource属性。
如果recordsource是SQL指令:
myComboBoxControl.recordsource = _ "SELECT relationDescription FROM Table_relationType"
或者如果它是一个值列表
myComboBoxControl.recordsource = myComboBoxControl.recordsource & ";nephew"
但总的来说,我发现要求很奇怪。桌上是否有自反(父母-子女)关系?
回答
最简单的方法是确保组合框始终是最新的,一旦组合框获得焦点,便只需重新查询即可。即使记录集随后在其他地方更新,组合框也始终是最新的。在OnFocus事件中只需要一个简单的TheCombobox.Requery就足够了。
回答
我通常会使用NotInList事件将数据添加到带有
Response = acDataErrAdded
更新组合。
Access 2007开发人员参考包含所有详细信息,包括示例代码:
http://msdn.microsoft.com/en-us/library/bb214329.aspx
回答
在窗体的更新后事件和删除事件中重新查询组合框。每当用户对记录集进行更改(无论是新记录,更改还是删除)时,组合框都是最新的。
除非用户必须立即进行其他所有人的更改,否则不要在每次获得焦点时都重新查询组合框,因为不仅用户必须等待(在大型记录集中很明显),而且如果记录集未更改。但是,在这种情况下,只要其他人进行了更改,不仅是组合框,还需要重新查询整个表单。这将是非常不寻常的情况。
更新后:
Private Sub Form_AfterUpdate() On Error GoTo Proc_Err Me.cboSearch.Requery Exit Sub Proc_Err: MsgBox Err.Number & vbCrLf & vbCrLf & Err.Description Err.Clear End Sub
删除后:
Private Sub Form_Delete(Cancel As Integer) On Error GoTo Proc_Err Me.cboSearch.Requery Exit Sub Proc_Err: MsgBox Err.Number & vbCrLf & vbCrLf & Err.Description Err.Clear End Sub
回答
这里有两个有效的可能答案:
- 使用窗体的AfterInsert事件重新查询组合框(以及OnDeleteConfirm事件)。如果组合框不显示用户可以更新的数据,并且在基础记录已更新的情况下需要更新的数据,这将足够。
- 如果需要在组合框中反映对数据的更新,则有必要在用于编辑组合框中显示的数据的控件的AfterUpdate事件中添加重新查询。
例如,如果组合框列出了表中的人员名称,则需要使用方法2,然后在Me!txtFirstName和Me!txtLastName的AfterUpdate事件中,重新查询组合框。由于我们要在四个地方执行相同的操作,因此我们需要编写一个子例程来进行重新查询。因此,sub看起来像这样:
Private Sub RequerySearchCombo() If Me.Dirty Then Me.Dirty = False Me!MyCombo.Requery End Sub
确保仅在组合框中显示的数据实际上有更新时才重新查询的原因是,如果用整个表的列表填充组合框,则重新查询会花费很长时间。有1000条记录中的10条。
保存所有查询的另一种方法是为组合框添加一个空白行源,并仅在键入1个或者2个字符后填充该行,然后根据键入的字符过滤组合显示的结果。为此,我们将使用组合框的OnChange事件:
Private Sub MyCombo_Change() Dim strSQL As String If Len(Me!MyCombo.Text) = 2 Then strSQL = "SELECT MyID, LastName & ', ' & FirstName FROM MyTable " strSQL = strSQL & "WHERE LastName LIKE " & Chr(34) & Me!MyCombo.Text & Chr(34) & "*" Me!MyCombo.Rowsource = strSQL End If End Sub
上面的代码假定我们要在显示" LastName,FirstName"的组合框中搜索一个人的名字。
还有一个重要的警告:如果要搜索绑定到完整表的表单(或者返回表中所有记录的SQL语句)并使用"书签导航"来定位记录,此方法将无法很好地扩展,因为它需要拉动整个搜索字段的整个索引。在上面的虚构组合框中,我们将使用FindFirst导航到具有相应MyID值的记录,因此必须提取MyID的索引(尽管只有足够多的索引页才能满足搜索实际上会被拉出)。对于具有几千条记录的表来说,这不是问题,但是超过15-20K时,它可能是网络瓶颈。
在这种情况下,我们可以使用组合框将结果集过滤为单个记录,而不是通过书签进行导航。当然,无论我们使用的是Jet后端还是服务器后端,这都非常高效。迫切需要尽快将这类效率纳入应用程序中。如果这样做,则可以更轻松地将其升级到服务器后端,或者如果我们应该使用大量新数据来达到临界点,则这将非常轻松,这会使旧方法的效率低下,以至于用户不友好。