Karen Schaefer
asked on
Display combo value base on selection of another combo
What do I need to change to have combo 2 display the actual value based on selection of combo 1.
Rowsource of combo1 (cboState)
Also, I need to do a record count on the results of the combo and if the count = 1 then display the actual value, if >1 then combo.dropdown becomes the option.
K
Rowsource of combo1 (cboState)
strSQL = "SELECT tblCity.StateRecID, tblState.StateCode, tblState.StateName, tblcity.CountryRecID" & _
" FROM tblState RIGHT JOIN tblCity ON tblState.StateRecID = tblCity.StateRecID" & _
" WHERE (((tblCity.CityName) Like [Forms]![frmHomePage]![cboCity] & '*'))" & _
" GROUP BY tblCity.StateRecID, tblState.StateCode, tblState.StateName, tblCity.CityName, tblcity.CountryRecID"
Forms!frmHomePage!cboState.RowSource = strSQL
Private Sub cboState_AfterUpdate()
On Error GoTo cboState_AfterUpdate_Error
gStateID = Me.cboState.Column(0)
If IsNullOrBlank(Me.cboCity) = False _
Or IsNullOrBlank(Me.cboCountry) = False Then
Forms!frmHomePage!cboCity.RowSource = "SELECT tblCity.CityName" & _
" FROM tblCountry RIGHT JOIN (tblState RIGHT JOIN tblCity ON tblState.StateRecID = tblCity.StateRecID) ON" & _
" tblCountry.CountryRecID = tblCity.CountryRecID" & _
" WHERE (tblCity.StateRecid)= " & gStateID & " " & _
" ORDER BY CityName asc"
Forms!frmHomePage!cboCountry.RowSource = "SELECT tblCountry.CountryRecID, tblCountry.CountryCode, tblCountry.CountryName" & _
" FROM tblCountry RIGHT JOIN tblCity ON tblCountry.CountryRecID = tblCity.CountryRecID" & _
" WHERE (tblCity.StateRecid)= " & gStateID & " " & _
" GROUP BY tblCountry.CountryRecID, tblCountry.CountryCode, tblCountry.CountryName, tblCity.StateRecID" & _
" ORDER BY tblCountry.CountryCode asc"
Forms!frmHomePage!cboCountry.value = Forms!frmHomePage!cboState.Column(1)
End If
On Error GoTo 0
Exit Sub
cboState_AfterUpdate_Error:
MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure cboState_AfterUpdate of VBA Document Form_frmHomePage"
End Sub
Also, I need to do a record count on the results of the combo and if the count = 1 then display the actual value, if >1 then combo.dropdown becomes the option.
K
ASKER
Thanks for the input, however, I need to have the sql at runtime due to the variable changes of each of the combos depending on which is selected. If the user select RESET then the rowsource reverts back the to basic query for each combo. If the user Selects or inputs the City, the state and/or the country combo will be based on the City selection (Which may be a Wildcard search), if the user Selects City, then Country( the country may have more than one option). Example
City - Paris
My current list of country indicates there are 2 Paris, 1 in Canada and 1 in France.
Hence the Country should display Canada & France.
The user will have the option to further narrow the search criteria.
But the code behind the Country can effect the State and City list. So how do I handle if the City has data and the user selects Country = CANADA, that it will not refresh the City list, allowing them to complete the search criteria. to update the listbox filter.rowsource?
K
City - Paris
My current list of country indicates there are 2 Paris, 1 in Canada and 1 in France.
Hence the Country should display Canada & France.
The user will have the option to further narrow the search criteria.
But the code behind the Country can effect the State and City list. So how do I handle if the City has data and the user selects Country = CANADA, that it will not refresh the City list, allowing them to complete the search criteria. to update the listbox filter.rowsource?
K
What do I need to change to have combo 2 display the actual value based on selection of combo 1.
This isn't your first rodeo, so I assume that you know how to make combos cascade.
You make the WHERE clause of the second combo depend upon the selected value of the first, and you issue a requery in the AfterUpdate event of the first one.
I'm not seeing that .Requery statement, though
combo 2 display the actual value based on selection of combo 1.
There's, and rightfully so, no combo1 and 2 in the code.
In fact, there's three combos in there.
1.
Me.cboCity.Requery
Me.cboCountry.Requery
Are going to be required.
2.
Also, I need to do a record count on the results of the combo and if the count = 1 then display the actual value, if >1 then combo.dropdown becomes the option.
Then you'll need recordset code, and I am not seeing any of that here.
3.
If IsNullOrBlank(Me.cboCity) = False _
Or IsNullOrBlank(Me.cboCountr y) = False Then
There's lots of possibilities there.
I don't see an ELSE clause!
***K
Your post came in while I was composing this***
This isn't your first rodeo, so I assume that you know how to make combos cascade.
You make the WHERE clause of the second combo depend upon the selected value of the first, and you issue a requery in the AfterUpdate event of the first one.
I'm not seeing that .Requery statement, though
combo 2 display the actual value based on selection of combo 1.
There's, and rightfully so, no combo1 and 2 in the code.
In fact, there's three combos in there.
1.
Me.cboCity.Requery
Me.cboCountry.Requery
Are going to be required.
2.
Also, I need to do a record count on the results of the combo and if the count = 1 then display the actual value, if >1 then combo.dropdown becomes the option.
Then you'll need recordset code, and I am not seeing any of that here.
Dim SQL as string
Dim rs as recordset
'ampersands are hell enough
'do yourself a favor and skip _
SQL = "SELECT tblCity.CityName"
SQL = SQL & " FROM tblCountry RIGHT JOIN (tblState RIGHT JOIN tblCity ON tblState.StateRecID = tblCity.StateRecID) ON" SQL = SQL & " tblCountry.CountryRecID = tblCity.CountryRecID"
SQL = SQL & " WHERE (tblCity.StateRecid)= " & gStateID
SQL = SQL & " ORDER BY CityName asc"
Set rs = CurrentDb.OpenRecordset(SQL, dbOpenDynaset,dbSeeChanges)
Case rs.RecordCount
Case 0
msgbox "Oops, no good value found!"
Case 1
me.cboCity.RowSource = SQL
me.cboCity.Requery
me.cboCity.Value = rs![tblCity.CityName]
Case Else
me.cboCity.RowSource = SQL
me.cboCity.Requery
me.cboCity.dropdown
End Select
'and now the other one
3.
If IsNullOrBlank(Me.cboCity) = False _
Or IsNullOrBlank(Me.cboCountr
There's lots of possibilities there.
I don't see an ELSE clause!
***K
Your post came in while I was composing this***
ASKER
I need to be able to handle all variances in the selection processes.
1. User can select either City or State or Country.
2. If user enters a wildcard type of search w/* to the right of data for city name, then return all applicable Country names to use as Country.rowsource.
3. If user Selects Country First, then requery City, except when City already contains data.
4. if Country has applicable states, then update State, except when State already contains data.
5. Also if the returning value of Country or State record count equals 1 then update the combo to display actual values. if Record >1 then have the Country DropDown displayed.
6. Update Listbox with results on click of Search button.
Also the return values for the listbox must be sorted ascending by Country, State, then City.
I am preparing a sample of my database that might help.
also see previous posting on ee. https://www.experts-exchange.com/questions/28678542/List-box-does-not-like-rowsource.html?anchorAnswerId=40796785#a40796785
Partial success, however, unable to update the search when City has been entered and then I need to select the country after the list box has been updated. I get no records.
Sample.zip
1. User can select either City or State or Country.
2. If user enters a wildcard type of search w/* to the right of data for city name, then return all applicable Country names to use as Country.rowsource.
3. If user Selects Country First, then requery City, except when City already contains data.
4. if Country has applicable states, then update State, except when State already contains data.
5. Also if the returning value of Country or State record count equals 1 then update the combo to display actual values. if Record >1 then have the Country DropDown displayed.
6. Update Listbox with results on click of Search button.
Also the return values for the listbox must be sorted ascending by Country, State, then City.
I am preparing a sample of my database that might help.
also see previous posting on ee. https://www.experts-exchange.com/questions/28678542/List-box-does-not-like-rowsource.html?anchorAnswerId=40796785#a40796785
Partial success, however, unable to update the search when City has been entered and then I need to select the country after the list box has been updated. I get no records.
Sample.zip
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I found in my search for an answer to prevent numerous case statements, however, I am having an issue with the cbocity..
It is coming across as id and note wildcard search so I am getting type mismatch issue.
Private Sub cmdSearch_Click()
Dim strRS As String
If Me.cboCountry.ListIndex >= 0 Then strRS = strRS & " AND CountryRecID = " & gCountryID
If Me.cboState.ListIndex >= 0 Then strRS = strRS & " AND stateRecID = " & gStateID
If Me.cboCity.ListIndex >= 0 Then strRS = strRS & " AND InStr(Me.cboCity.Value," * ") > 0"
'IF FILTER FOUND ADD 'WHERE' AND REMOVE LEADING 'AND' (IF NOT FOUND IT WILL REMAIN A NULL STRING)
If strRS <> "" Then strRS = " WHERE " & Mid(strRS, 6)
'ADD FILTER TO QUERY
strRS = "SELECT CityRecID, CityName, StateCode as State, CountryCode As Country" & _
" FROM qryFilterListData " & strRS & ""
'ADD ORDER BY CLAUSE
strRS = strRS & " GROUP BY CityRecID, CityName, StateCode as State, CountryCode as Country"
strRS = strRS & " ORDER BY CountryCode, StateCode, CityName"
Forms![frmHomePage]![lstCityFilter].RowSource = strRS
It is coming across as id and note wildcard search so I am getting type mismatch issue.
prevent numerous case statements
No argument there. That's the elegance of Select Case TRUE
You can have a single case statement.
You order the various CASEs from most specific to least, because the first CASE that is true gets executed, and then the structure exits.
This is far easier to write, debug, test and maintain than nested IF THENs with a whack of Boolean operators thrown in.
You can throw in breakpoints and watch as each CASE gets evaluated, and see if you got it right.
If Me.cboCity.ListIndex >= 0 Then strRS = strRS & " AND InStr(Me.cboCity.Value," * ") > 0"
I like this construction InStr(Me.cboCity.Value," * ") > 0 very much better as a Boolean test to
me.CboCity.Value Like SomeStringValue with or without some wildcards -- but what are you using it for here?
InStr(Me.cboCity.Value," * ") This is searching Me.cboCity.Value for " * " and will return an integer if it finds it, zero if it does not find it.
InStr(Me.cboCity.Value," * ") > 0 This is a Boolean, either true or false
So this
If Me.cboCity.ListIndex >= 0 Then strRS = strRS & " AND InStr(Me.cboCity.Value," * ") > 0"
will either be whatever strRS is with "AND TRUE" or "AND FALSE" tacked on the end.
Does that make sense in context?
No argument there. That's the elegance of Select Case TRUE
You can have a single case statement.
You order the various CASEs from most specific to least, because the first CASE that is true gets executed, and then the structure exits.
This is far easier to write, debug, test and maintain than nested IF THENs with a whack of Boolean operators thrown in.
You can throw in breakpoints and watch as each CASE gets evaluated, and see if you got it right.
If Me.cboCity.ListIndex >= 0 Then strRS = strRS & " AND InStr(Me.cboCity.Value," * ") > 0"
I like this construction InStr(Me.cboCity.Value," * ") > 0 very much better as a Boolean test to
me.CboCity.Value Like SomeStringValue with or without some wildcards -- but what are you using it for here?
InStr(Me.cboCity.Value," * ") This is searching Me.cboCity.Value for " * " and will return an integer if it finds it, zero if it does not find it.
InStr(Me.cboCity.Value," * ") > 0 This is a Boolean, either true or false
So this
If Me.cboCity.ListIndex >= 0 Then strRS = strRS & " AND InStr(Me.cboCity.Value," * ") > 0"
will either be whatever strRS is with "AND TRUE" or "AND FALSE" tacked on the end.
Does that make sense in context?
ASKER
Yes, however I want to return the wildcard like state results. ie. Paris*.
How do I modify the
So that it will be included in the where statement as a wilcard search?
K
How do I modify the
If Me.cboCity.ListIndex >= 0 Then strRS = strRS & " AND InStr(Me.cboCity.Value," * ") > 0"
So that it will be included in the where statement as a wilcard search?
K
ASKER
Sorry to be so wishy washy, I am just look for the simpliest way to get these combos working - did you get a chance to look as my sample db?
K
K
did you get a chance to look as my sample db?
It was an accdb, and I cannot deal with those. Sorry.
Being the dev, I run Access 2003, so that everything uplevel functions nicely.
Besides, for what I do A2003 is a far superior platform.
We run Access 2003, 2010 and 2013 concurrently, but my machine is A2003.
Hence, no accdb.
So what is in strRS that appending AND TRUE or AND FALSE to it would make sense!?!
And note " AND InStr(Me.cboCity.Value," * ") > 0"
That is looking for [space][asterisk][space] in the Me.cboCity.Value
Will you really have a space before and after the asterisk?
It was an accdb, and I cannot deal with those. Sorry.
Being the dev, I run Access 2003, so that everything uplevel functions nicely.
Besides, for what I do A2003 is a far superior platform.
We run Access 2003, 2010 and 2013 concurrently, but my machine is A2003.
Hence, no accdb.
So what is in strRS that appending AND TRUE or AND FALSE to it would make sense!?!
And note " AND InStr(Me.cboCity.Value," * ") > 0"
That is looking for [space][asterisk][space] in the Me.cboCity.Value
Will you really have a space before and after the asterisk?
ASKER
This is what I have got working so far, thanks to you - you help make the light bulb go off. THANKS SO MUCH.
Private Sub cmdSearch_Click()
Dim nName As String
Dim gStateID As Integer
Dim gCountryID As Integer
Dim strRS As String
nName = Nz([Forms]![frmHomePage]!cboCity.value & "*")
gStateID = Nz([Forms]![frmHomePage]!cboState.Column(0))
gCountryID = Nz([Forms]![frmHomePage]!cboCountry.Column(0))
'Debug.Print nName, gStateID, gCountryID
' Filter the list box appropriately based on the combo box selection(s)
On Error GoTo filterList_Error
strSQL = "SELECT tblCity.CityRecID, tblCity.CityName, tblState.StateCode as State, tblCountry.CountryCode as Country, tblCity.StateRecID, tblCity.CountryRecID" & _
" FROM tblState RIGHT JOIN (tblCountry RIGHT JOIN tblCity ON" & _
" tblCountry.CountryRecID = tblCity.CountryRecID) ON tblState.StateRecID = tblCity.StateRecID" '& _
Select Case True
Case Nz(Me.cboCity.value, "") = "" And Nz(Me.cboState.value, "") = "" And Nz(Me.cboCountry.value, "") = ""
strSQL = "SELECT tblCity.CityRecID, tblCity.CityName, tblState.StateCode as State, tblCountry.CountryCode as Country, tblCity.StateRecID, tblCity.CountryRecID" & _
" FROM tblState RIGHT JOIN (tblCountry RIGHT JOIN tblCity ON" & _
" tblCountry.CountryRecID = tblCity.CountryRecID) ON tblState.StateRecID = tblCity.StateRecID" '& _
Case Nz(Me.cboCity.value, "") <> "" And Nz(Me.cboState.value, "") = "" And Nz(Me.cboCountry.value, "") = ""
strWHERE = " WHERE ((tblCity.CityName) Like " & Chr(39) & nName & Chr(39) & ")"
strSQL = strSQL & strWHERE
Case Nz(Me.cboCity.value, "") <> "" And Nz(Me.cboState.value, "") = "" And Nz(Me.cboCountry.value, "") <> ""
strWHERE = " WHERE ((tblCity.CityName) Like " & Chr(39) & nName & Chr(39) & ")"
strWHERE = strWHERE & " AND ((tblCountry.CountryRecID) =" & gCountryID & ")"
strSQL = strSQL & strWHERE
Case Nz(Me.cboCity.value, "") <> "" And Nz(Me.cboState.value, "") <> "" And Nz(Me.cboCountry.value, "") <> ""
strWHERE = " WHERE ((tblCity.CityName) Like " & Chr(39) & nName & Chr(39) & ")"
strWHERE = strWHERE & " AND ((tblState.StateRecID) =" & gStateID & ")"
strWHERE = strWHERE & " AND ((tblCountry.CountryRecID) =" & gCountryID & ")"
strSQL = strSQL & strWHERE
Case Nz(Me.cboCity.value, "") = "" And Nz(Me.cboState.value, "") = "" And Nz(Me.cboCountry.value, "") <> ""
strWHERE = " WHERE ((tblCountry.CountryRecID) =" & gCountryID & ")"
strSQL = strSQL & strWHERE
Case Nz(Me.cboCity.value, "") = "" And Nz(Me.cboState.value, "") <> "" And Nz(Me.cboCountry.value, "") = ""
strWHERE = " WHERE ((tblState.StateRecID) =" & gStateID & ")"
strSQL = strSQL & strWHERE
End Select
strOrderBy = " ORDER BY CountryCode, StateCode, CityName asc"
strSQL = strSQL & strOrderBy
Debug.Print strSQL
Forms![frmHomePage]![lstCityFilter].RowSource = strSQL
' Forms![frmHomePage]![lstCityFilter].Requery
On Error GoTo 0
Exit Sub
filterList_Error:
MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure filterList of VBA Document Form_frmHomePage"
End Sub
No problem.
Sometimes you need another set of eyes.
We've strayed from the original cascading combos, though, to the using of the values of those in creating a ListBox rowsource.
Your Select Case True is beginning to look good.
You have 3 combos, with 2 conditions (null or has a value)
2^3 = 8
So there should be 8 Cases
I see only 6
1.All Null
2. City not null, 2 null
3. city & country not null, state null
4. All values
5. Country not null, other null
6. State not null, others null
You are missing
7. City & state not null, country null
8. State and country not null, city null
Even if you have 100% of the probabilities, have a CASE ELSE block
in code maintenance, it signals what you intend in the worse-case scenario and can really help you or your successor understand what is important about the form.
Select case true beats the hell out of trying to use if then and AND OR to try to cover 8 possibilities for readability, doesn't it!
I see you have the requery commented out. You will likely need it.
Generally, to go along with that you need code to de-select any choices that were made previously.
They either stay selected in a new context (bad) or are outside the number of new choices (BANG!)
Is this a single select or multi-select listbox?
Sometimes you need another set of eyes.
We've strayed from the original cascading combos, though, to the using of the values of those in creating a ListBox rowsource.
Your Select Case True is beginning to look good.
You have 3 combos, with 2 conditions (null or has a value)
2^3 = 8
So there should be 8 Cases
I see only 6
1.All Null
2. City not null, 2 null
3. city & country not null, state null
4. All values
5. Country not null, other null
6. State not null, others null
You are missing
7. City & state not null, country null
8. State and country not null, city null
Even if you have 100% of the probabilities, have a CASE ELSE block
in code maintenance, it signals what you intend in the worse-case scenario and can really help you or your successor understand what is important about the form.
Select case true beats the hell out of trying to use if then and AND OR to try to cover 8 possibilities for readability, doesn't it!
I see you have the requery commented out. You will likely need it.
Generally, to go along with that you need code to de-select any choices that were made previously.
They either stay selected in a new context (bad) or are outside the number of new choices (BANG!)
Is this a single select or multi-select listbox?
ASKER
Multi Selection and I will remove all commented out temporary code. Didn't want to remove until I am sure we are on the right path.,
also any Ideas on how do I get the actual value displayed in combos if the recordcount =1 and/or display the drop down recordcount > 1
Thanks for the follow thru.
1.All Null - Not need handled on load and on the reset button
2. City not null, 2 null
3. city & country not null, state null
4. All values
5. Country not null, other null
6. State not null, others null
You are missing
7. City & state not null, country null
8. State and country not null, city null
also any Ideas on how do I get the actual value displayed in combos if the recordcount =1 and/or display the drop down recordcount > 1
Thanks for the follow thru.
ASKER
Forms!frmHomePage!cboState .RowSource = strSQL
Set rs = curDB.OpenRecordset(strSQL )
If rs.RecordCount = 1 Then
Me.cboState.value = Me.cboState.value
Else
Me.cboState.Dropdown
End If
rs.Close
Set rs = Nothing
Still not displaying the actual value in combo.
Set rs = curDB.OpenRecordset(strSQL
If rs.RecordCount = 1 Then
Me.cboState.value = Me.cboState.value
Else
Me.cboState.Dropdown
End If
rs.Close
Set rs = Nothing
Still not displaying the actual value in combo.
Me.cboState.value = Me.cboState.value
By itself, does that look like it makes sense :)
Me.cboState.value = rs!SomeFieldThatIsTheCombo BoxesIndex Field
Much better!
Note that Access will only permit one concurrent dropdown, and you may need to SetFocus the control first!
By itself, does that look like it makes sense :)
Me.cboState.value = rs!SomeFieldThatIsTheCombo
Much better!
Note that Access will only permit one concurrent dropdown, and you may need to SetFocus the control first!
ASKER
Thanks so much you really helped. Thanks for all the time you put into this.
K
K
No Problem
Glad to have helped you over the years.
Nick67
Glad to have helped you over the years.
Nick67
For cboCity:
SELECT tblCity.CityName FROM tblCountry
RIGHT JOIN (tblState
RIGHT JOIN tblCity ON tblState.StateRecID = tblCity.StateRecID)
ON tblCountry.CountryRecID = tblCity.CountryRecID
WHERE tblCity.StateRecid = Forms!frmHomePage.cboState
ORDER BY CityName asc
For Country:
SELECT Country.CountryRecID, Country.CountryCode, Country.CountryName
FROM tblCountry as Country
RIGHT JOIN tblCity ON Country.CountryRecID = tblCity.CountryRecID
WHERE tblCity.StateRecid = Forms!frmHomePage.cboState
GROUP BY Country.CountryRecID, Country.CountryCode, Country.CountryName, tblCity.StateRecID
ORDER BY Country.CountryCode asc
Then, in your AfterUpdate event, I would use:
Private Sub cboState_AfterUpdate
me.cboCity.Requery
me.cboCity = NULL
me.cboCountry.Requery
me.cboCountry.Null
End Sub