问题
Thanks to a great answer to a previous question (thanks Hansup and Remou), I've made an Access form based on a ADODB recordset that pulls at runtime. This enables it to have a checkbox that is only in memory. The checkbox is fine.
I've now been asked to add a drop-down filter by "Client" to the form. Easy enough. I made the drop-down box, made a little query for the control source, and in the After_Update event, added this code:
Private Sub Combo_PickClient_AfterUpdate()
Me.Filter = "Client='" & Combo_PickClient.Value & "'"
Me.FilterOn = True
Me.Refresh
End Sub
For testing purposes, I chose 2 clients. When I open the form, it shows both client's data (good). When I pick one client, it successfully filters the data (also good). When I pick the second client, it does nothing (not so good)
Why does this filter only work one time? It doesn't throw any error. The screen simply refreshes and that's it.
回答1:
My best guess is that Access tries to reload the form's recordset from the data provider when you attempt to modify or remove a non-empty .Filter
property. Since the disconnected recordset doesn't have a provider, that attempt fails. In my testing, I actually triggered error #31, "Data provider could not be initialized" at one point.
In your first attempt (which succeeded), the .Filter
property was empty beforehand. I saw the same behavior and I'm guessing Access can apply a .Filter
to an unfiltered recordset without revisiting the data provider.
Sorry about the guesswork. Unfortunately, that's the best I can offer for an explanation.
Anyway, I gave up trying to use the form's .Filter
property to accomplish what I think you want. I found it easier to simply reload the disconnected recordset based on a query which includes your .Filter
string in its WHERE
clause. The code changes were minor, and the run time performance cost is neglible ... the reloaded recordset is displayed instantaneously after changing the combo box selection.
First I moved the code which builds the disconnected recordset from Form_Open
to a separate function whose signature is ...
Private Function GetRecordset(Optional ByVal pFilter As String) _
As ADODB.Recordset
The function incorporates a non-empty pFilter
argument into the WHERE
clause of the SELECT
query which feeds the disconnected recordset.
Then I changed Form_Open
to one statement ...
Set Me.Recordset = GetRecordset()
So, if your combo box and disconnected recordset are both on the same form, the combo's After Update procedure could be ...
Private Sub Combo_PickClient_AfterUpdate()
Set Me.Recordset = GetRecordset("Client='" & _
Me.Combo_PickClient & "'")
End Sub
In my case, the disconnected recordset is displayed in a subform and the combo box is on its parent form. So I created a wrapper procedure in the subform code module and call that from the combo's After Update:
Call Me.SubFormControlName.Form.ChangeRecordset("Client='" & _
Me.Combo_PickClient & "'")
The wrapper procedure is very simple, but I found it convenient ...
Public Sub ChangeRecordset(Optional ByVal pFilter As String)
Set Me.Recordset = GetRecordset(pFilter)
End Sub
来源:https://stackoverflow.com/questions/14531218/in-access-form-with-disconnected-ado-recordset-filter-only-works-one-time