Sometimes in a form-based parameter query it would be nice to limit the values in one combo box based on the value selected in another combo box. For example, if a form has two combo boxes, one for the type of music and the other for artists, when you select the type of music in the first combo box, you'd like the list of artists in the second combo box to be limited to artists of the selected music type. But no matter which type of music you select, you always see all the
When you place two combo boxes on a form, Access by default doesn't link them together. But you can link them by basing the second combo box on a parameter query whose criteria point to the value of the first combo box. This solution
Follow these steps to create linked combo boxes:
Create a form bound to a table or query. Make it a continuous form by setting the DefaultView property of the form to Continuous Forms. This will be used as a subform, like fsubAlbumBrowse in the frmAlbumBrowse example.
Create a second form with two
Set the LinkChildFields and LinkMasterFields properties of the subform control to keep the subform in sync with the main form. We entered ArtistID as the LinkChildFields and cboArtistID as the LinkMasterFields.
Create the query that will supply rows for the first combo box. The query that's the source of rows for cboMusicType is a simple one-column query based on tblMusicType and sorted
Create the query that will supply rows to the second combo box. The query that provides rows for the cboArtistID combo box, qryFilteredArtists, contains three
Create the parameter that links this query to the first combo box. For qryFilteredArtists, enter the following in the MusicType field:
Forms![frmAlbumBrowse]![cboMusicType]
Select Query
Parameters to declare the data type of the parameter. Use the exact same parameter
Adjust the properties of the two combo box controls so they now obtain their rows from the queries created in Steps 3 through 6. In the frmAlbumBrowse example, set the properties of the combo boxes as shown in Table 1-2.
|
Name |
RowSourceType |
RowSource |
ColumnCount |
ColumnWidth |
BoundColumn |
|---|---|---|---|---|---|
|
cboMusicType |
Table/Query |
qryMusicType |
1 |
<blank> |
1 |
|
cboArtistID |
Table/Query |
qryFilteredArtists |
2 |
0 in; 2 in |
1 |
When the value selected for the first combo box changes, you need two things to happen:
Blank out any value in the second combo box to avoid a mismatch.
Requery the second combo box so that only matching values will show. In the example, we want to see artists of only the selected music type.
You could use a macro to accomplish this, but adding a VBA procedure is just as easy. To make your code run automatically when the value in the first combo box, cboMusicType, changes, use that combo box's AfterUpdate property. Select [Event Procedure] on the properties sheet, and click the "..." button that appears to the right of the property. This
Private Sub cboMusicType_AfterUpdate( )
cboArtistID = Null
cboArtistID.Requery
End Sub
To see a form-based query in which one drop-down combo box depends on the value selected in another,
The parameter query (in this example, qryFilteredArtists) causes the second combo box's values to be dependent on the choice made in the first combo box. This works because the criteria for the MusicType field in qryFilteredArtists point directly to the value of the first combo box.
This works without any macro or VBA code until you change the value in the first combo box. To keep the two combo boxes synchronized, however, you must create an event procedure to force a requery of the second combo box's row source whenever the first combo box's value changes. Any value in the second combo box (cboArtistID) will probably become invalid if the first combo box (cboMusicType) changes, so it is also a good idea to blank out the second combo box when that happens. This is accomplished in the frmAlbumBrowse example by using two simple lines of VBA code placed in the AfterUpdate event procedure of the first combo box.
The subform in this example automatically updates when an artist is selected, because cboArtistID was entered as the LinkMasterFields (the property name is plural because you may need to use more than one field). The LinkMasterFields property can contain the names of one or more controls on the main form or fields in the record source of the main form. If you use more than one field, separate them with semicolons. The LinkChildFields property must contain only field names (not control
The example shown here uses two unbound combo boxes and a subform. Your use of this technique for relating combo boxes, however, needn't depend on this specific style of form. You can also use this technique with bound combo boxes located in the detail section of a form. For example, you might use the frmSurvey form (also found in the 01-02.MDB database) to record critiques of albums. It contains two linked combo boxes in the detail section: cboArtistID and cboAlbumID. When you select an artist using the first combo box, the second combo box is filtered to display only albums for that artist.
To create a form similar to frmSurvey, follow the steps described in this solution, placing the combo boxes in the detail section of the form instead of the header. Create an event procedure in the AfterUpdate event of the first combo box, cboArtistID, to blank out and requery the second combo box, cboAlbumID. Because the artist may be different on different records in the form, cboAlbumID also needs to be requeried as you navigate from record to record. You can accomplish this by requerying cboAlbumID in the Current event of the form:
Private Sub Form_Current( )
cboAlbumID.Requery
End Sub
{% if main.adsdop %}{% include 'adsenceinline.tpl' %}{% endif %}
|