1
votes

I have a continuous form in access with 3 combo boxes in the header to filter the data. Currently I have a fairly lengthy nested IF to to check how many combo boxes are being used and cover all 8 permeatations. With 3 boxes it's not too bad but I may add a 4th or even 5th in which case it is going to get ridiculous.

Is there an easier way to set up combo box filters for continuous forms?

Current Code

Private Sub filters()
    Dim fstr As String, rgS As String, piS As String, hcS As String
    rgS = "research_group_id = " & Me.fRG
    piS = "pi_id = " & Me.fPI
    hcS = "healthcat_id = " & Me.fHC
    If IsNull(Me.fRG) Then
        If IsNull(Me.fPI) Then
            If IsNull(Me.fHC) Then
                ' Do Nothing
            Else
                fstr = hcS
                Call filton(Me.Name, fstr)
            End If
        Else
            If IsNull(Me.fHC) Then
                fstr = piS
                Call filton(Me.Name, fstr)
            Else
                fstr = piS & " AND " & hcS
                Call filton(Me.Name, fstr)
            End If
        End If
    Else
        If IsNull(Me.fPI) Then
            If IsNull(Me.fHC) Then
                fstr = rgS
                Call filton(Me.Name, fstr)
            Else
                fstr = rgS & " AND " & hcS
                Call filton(Me.Name, fstr)
            End If
        Else
            If IsNull(Me.fHC) Then
                fstr = rgS & " AND " & piS
                Call filton(Me.Name, fstr)
            Else
                fstr = rgS & " AND " & piS & " AND " & hcS
                Call filton(Me.Name, fstr)
            End If
        End If
    End If
End Sub

The above code is fired after update of each combo box.

Public Function filton(frmname As String, fstr As String)
        With Forms(frmname)
            .FilterOn = False
            .Filter = fstr
            .FilterOn = True
        End With
End Function
2

2 Answers

1
votes

Add each criterion, with " AND ", to your filter string. Afterward, discard the leading " AND " from that string. This approach should easily accommodate any number of criteria.

Not sure if I matched everything up properly in the code below, but hopefully the pattern is clear.

If Not IsNull(Me.fRG) Then
    fstr = fstr & " AND " & rgS
End If
If Not IsNull(Me.fPI) Then
    fstr = fstr & " AND " & piS
End If
If Not IsNull(Me.fHC) Then
    fstr = fstr & " AND " & hcS
End If
If Len(fstr) > 0 Then
    ' discard leading " AND "
    fstr = Mid(fstr, 6)
End If
1
votes

You can create an After Update event on your combo boxes. Here is an example of a 3-tier heirarchy where Parent and Child combo boxes are disabled on load

Private Sub Grandfather_Combo_AfterUpdate()

    Parent_Combo.RowSource="SELECT ...."
    Parent_Combo.Enabled=True
    Child_Combo.Enabled=False     ' the child is invalid until the parent is defined

End Sub

Private Sub Parent_Combo_AfterUpdate()

    Child_Combo.RowSource="SELECT ...."
    Child_Combo.Enabled=True

End Sub

This is for a single-record form, but should get you started, if it's the combo boxes you want to change.

If it's the record filter you want to change, you use the same event, but instead you change a filter variable for the field concerned and then call a common subroutine to recreate the form filter from the combination of all the filter variables.