2

感谢对上一个问题的出色回答感谢 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 个客户端。当我打开表单时,它显示了两个客户的数据(好)。当我选择一个客户端时,它成功过滤了数据(也很好)。当我选择第二个客户时,它什么也没做(不太好)

为什么这个过滤器只能工作一次?它不会抛出任何错误。屏幕只是刷新,仅此而已。

4

1 回答 1

1

我最好的猜测是,当您尝试修改或删除非空.Filter属性时,Access 会尝试从数据提供者重新加载表单的记录集。由于断开连接的记录集没有提供程序,因此该尝试失败。在我的测试中,我实际上触发了错误 #31,“无法初始化数据提供者”。

在您的第一次尝试(成功)中,该.Filter属性事先是空的。我看到了相同的行为,我猜 Access 可以将 a.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()

因此,如果您的组合框和断开连接的记录集都在同一个表单上,则组合的更新后过程可能是......

Private Sub Combo_PickClient_AfterUpdate()
    Set Me.Recordset = GetRecordset("Client='" & _
        Me.Combo_PickClient & "'")
End Sub

就我而言,断开连接的记录集显示在子窗体中,组合框位于其父窗体上。所以我在子表单代码模块中创建了一个包装过程,并从组合的更新后调用它:

Call Me.SubFormControlName.Form.ChangeRecordset("Client='" & _
    Me.Combo_PickClient & "'")

包装程序非常简单,但我发现它很方便......

Public Sub ChangeRecordset(Optional ByVal pFilter As String)
    Set Me.Recordset = GetRecordset(pFilter)
End Sub
于 2013-01-26T16:22:21.223 回答