感谢对前一个question(感谢Hansup和Remou)的一个很好的答案,我已经基于运行时提取的ADODB记录集创建了一个Access表单。这使它具有仅在内存中的复选框。复选框很好。
我现在被要求通过“客户端”向表单添加一个下拉过滤器。很容易。我创建了下拉框,对控件源进行了一些查询,并在After_Update事件中添加了以下代码:
Private Sub Combo_PickClient_AfterUpdate()
Me.Filter = "Client='" & Combo_PickClient.Value & "'"
Me.FilterOn = True
Me.Refresh
End Sub
出于测试目的,我选择了2个客户端。当我打开表单时,它会显示客户端的数据(好)。当我选择一个客户端时,它成功过滤了数据(也很好)。当我选择第二个客户端时,它什么都不做(不太好)
为什么这个过滤器只能工作一次?它不会抛出任何错误。屏幕只是刷新,就是这样。
答案 0 :(得分:1)
我最好的猜测是,当您尝试修改或删除非空.Filter
属性时,Access会尝试从数据提供程序重新加载表单的记录集。由于断开连接的记录集没有提供程序,因此该尝试失败。在我的测试中,我实际上在某一时刻触发了错误#31,“数据提供程序无法初始化”。
在您第一次尝试(成功)时,.Filter
属性事先是空的。我看到了相同的行为,我猜测Access可以将.Filter
应用于未经过滤的记录集,而无需重新访问数据提供者。
抱歉猜测。不幸的是,这是我能提供的最好的解释。
无论如何,我放弃了尝试使用表单的.Filter
属性来完成我认为你想要的东西。我发现根据查询在其.Filter
子句中包含WHERE
字符串,只需重新加载断开连接的记录集就更容易了。代码更改很小,运行时性能成本可以忽略不计......更改组合框选择后,重新加载的记录集会立即显示。
首先,我将构建断开连接的记录集的代码从Form_Open
移动到一个单独的函数,其签名是......
Private Function GetRecordset(Optional ByVal pFilter As String) _
As ADODB.Recordset
该函数将非空pFilter
参数合并到WHERE
查询的SELECT
子句中,该子句为断开连接的记录集提供信息。
然后我将Form_Open
更改为一个声明......
Set Me.Recordset = GetRecordset()
因此,如果您的组合框和断开连接的记录集都在同一个表单上,那么组合的After Update过程可能是......
Private Sub Combo_PickClient_AfterUpdate()
Set Me.Recordset = GetRecordset("Client='" & _
Me.Combo_PickClient & "'")
End Sub
在我的情况下,断开连接的记录集显示在子窗体中,组合框位于其父窗体上。所以我在子窗体代码模块中创建了一个包装程序,并从组合的After Update:
中调用它Call Me.SubFormControlName.Form.ChangeRecordset("Client='" & _
Me.Combo_PickClient & "'")
包装程序非常简单,但我觉得很方便......
Public Sub ChangeRecordset(Optional ByVal pFilter As String)
Set Me.Recordset = GetRecordset(pFilter)
End Sub