G
Guest
I have an interesting problem. I will start with the simple part, and save
the scary part for later. First, I am looking for critiques on my
methodology.
Problem:
The use must be able to select "All" or one or more vaules from 5 list boxes
to filter data for some reports. The reports are to include only rows where
all the values match.
My Solution:
The List Boxes are set to Extended MultiSelect.
The List Box Row Sources are SQL that return unique values and "(All") using
a union select.
The queries for the report use the function below to determine whether a
value should be included. They pass the field value and the name of the List
Box control to the function. The function determines whether the value
passed is in the ItemsSelected collection. If it is, it passes the value
back to the query, if it is not, it passes back Null.
This is the best approach I could come up with. If there is a better way or
my method needs some tweaking, please let me know.
Now the Scary part (I knew you were waiting for it). As I previously
stated, there are 5 list boxes. Populating them on the first round is no
problem. The problem is that the data has some interdependancies. For
example:
All rows have a Master Activity Number.
All rows have an Activity Number.
Master Activity to Activity is One to Many.
The other 3 fields have no relationships, but each row may have a value in 0
to 3 of the fields.
If a user selects a Master Activity, then selects an Activity that is not
related to that Master Activity, no rows will be returned. So far, not a
problem. When a Master Activity is chosen, I change the row source of the
Activity list box so that only Activityies related to the Master are included
and requery.
Now the hard part. To avoid allowing the user to select mulually exclusive
values, I want to requery after each selection so that only valid values are
presented for selection. For example. If a user first selects a Bill
Network, then selects a Master Activity, then decides to select a home room.
I am getting lost in which lists to requery, because each requery looses the
previous selections.
Public Function IsInList(varValue As Variant, strControl As String) As Variant
'D Hargis 11/05
'Used by frmBPO to determine if a value is selected in a list box
'for BPO Reports
'VarValue - The field value to evaluate
'strControl - The name of the list box to search
Dim varItm As Variant 'Index to selected items
Dim ctl As Control 'List Box control object reference
Set ctl = Forms!frmbpo.Controls(strControl)
For Each varItm In ctl.ItemsSelected
If ctl.ItemData(varItm) = "(All)" Then
IsInList = varValue
Set ctl = Nothing
Exit Function
End If
If ctl.ItemData(varItm) = varValue Then
IsInList = varValue
Set ctl = Nothing
Exit Function
End If
Next varItm
Set ctl = Nothing
IsInList = ""
End Function
HAVING (((tblMasterActivity.MActivity)=IsInList([Mactivity],"lstMActivity"))
AND ((tblBudgetVSActualLbrPO.activity)=IsInList([Activity],"lstActivity"))
AND
((tblActivity.actvContractActivity)=IsInList([actvContractActivity],"lstBillNetwork"))
AND ((tblBudgetVSActualLbrPO.acctgunit)=IsInList([acctgunit],"lstHomeRoom"))
the scary part for later. First, I am looking for critiques on my
methodology.
Problem:
The use must be able to select "All" or one or more vaules from 5 list boxes
to filter data for some reports. The reports are to include only rows where
all the values match.
My Solution:
The List Boxes are set to Extended MultiSelect.
The List Box Row Sources are SQL that return unique values and "(All") using
a union select.
The queries for the report use the function below to determine whether a
value should be included. They pass the field value and the name of the List
Box control to the function. The function determines whether the value
passed is in the ItemsSelected collection. If it is, it passes the value
back to the query, if it is not, it passes back Null.
This is the best approach I could come up with. If there is a better way or
my method needs some tweaking, please let me know.
Now the Scary part (I knew you were waiting for it). As I previously
stated, there are 5 list boxes. Populating them on the first round is no
problem. The problem is that the data has some interdependancies. For
example:
All rows have a Master Activity Number.
All rows have an Activity Number.
Master Activity to Activity is One to Many.
The other 3 fields have no relationships, but each row may have a value in 0
to 3 of the fields.
If a user selects a Master Activity, then selects an Activity that is not
related to that Master Activity, no rows will be returned. So far, not a
problem. When a Master Activity is chosen, I change the row source of the
Activity list box so that only Activityies related to the Master are included
and requery.
Now the hard part. To avoid allowing the user to select mulually exclusive
values, I want to requery after each selection so that only valid values are
presented for selection. For example. If a user first selects a Bill
Network, then selects a Master Activity, then decides to select a home room.
I am getting lost in which lists to requery, because each requery looses the
previous selections.
Public Function IsInList(varValue As Variant, strControl As String) As Variant
'D Hargis 11/05
'Used by frmBPO to determine if a value is selected in a list box
'for BPO Reports
'VarValue - The field value to evaluate
'strControl - The name of the list box to search
Dim varItm As Variant 'Index to selected items
Dim ctl As Control 'List Box control object reference
Set ctl = Forms!frmbpo.Controls(strControl)
For Each varItm In ctl.ItemsSelected
If ctl.ItemData(varItm) = "(All)" Then
IsInList = varValue
Set ctl = Nothing
Exit Function
End If
If ctl.ItemData(varItm) = varValue Then
IsInList = varValue
Set ctl = Nothing
Exit Function
End If
Next varItm
Set ctl = Nothing
IsInList = ""
End Function
HAVING (((tblMasterActivity.MActivity)=IsInList([Mactivity],"lstMActivity"))
AND ((tblBudgetVSActualLbrPO.activity)=IsInList([Activity],"lstActivity"))
AND
((tblActivity.actvContractActivity)=IsInList([actvContractActivity],"lstBillNetwork"))
AND ((tblBudgetVSActualLbrPO.acctgunit)=IsInList([acctgunit],"lstHomeRoom"))