Problem with Combo Box

  • Thread starter Thread starter FireGeek822
  • Start date Start date
F

FireGeek822

I have a combo box on a form that is creating problems. When I type a
letter to select an item from the list, it immediately produces the
item, however when I tab off the combo box to another control on the
form, the item in the box switches to the first item in the list.

If I highlight the text in the combo box and try again, it moves to the
second item in the list.

I do have Limit To List set to yes in the properties of the combo box.

HELP!!!

Tammy
 
FireGeek822 said:
I have a combo box on a form that is creating problems. When I type a
letter to select an item from the list, it immediately produces the
item, however when I tab off the combo box to another control on the
form, the item in the box switches to the first item in the list.

If I highlight the text in the combo box and try again, it moves to
the second item in the list.

I do have Limit To List set to yes in the properties of the combo box.

Is the combo box bound or unbound? If bound, is it bound to an
updatable field? Is there any code in any of the combo's events, or in
any of the form's events, that manipulates the combo box in any way?
 
Here is the code in the Selection form. There is no code associated
with the combo box (cboDivisions), although it is bound. In the
properties of cboDivisions is the following:

RowSourceType: Table/Query
RowSource: SELECT [cboDivisions].[Division] FROM [cboDivisions] ORDER
BY [Division];


There is a command button on the Selection form. The idea is that the
user selects the item desired in the combo box and hits the [Continue]
button which opens the frmIssues form and shows only the issues for the
selected divisions.

Private Sub cmdContinue_Click()
On Error GoTo ErrorHandler

Me.cboDivisions.SetFocus
IssueDiv = Me.cboDivisions.Text
x = Me.cboDivisions.ListIndex

If IssueDiv = "" Then
MsgBox "Please select a Division" & vbCrLf & "from the drop
down box.", vbOKOnly, "Type Selection Error"
Form_frmIssuesDivisionSelection.cboDivisions.SetFocus
Exit Sub
Else
Set db = CurrentDb()
sql = "SELECT Division FROM tblIssues WHERE Division = " & "'"
& IssueDiv & "'" & ""
Set rs = db.OpenRecordset(sql)

rs.MoveFirst
rs.MoveLast

If rs.RecordCount = 0 Then
MsgBox "Your selection produced zero records.",
vbOKOnly
With Form_frmIssuesDivisionSelection
.SetFocus
.cboDivisions.SetFocus
.cboDivisions.Text = vbNullString
End With
Exit Sub
Else
stDocName = "frmIssues"
stLinkCriteria = "tblIssues![Division]=" & "'" &
IssueDiv & "'"
DoCmd.OpenForm stDocName, , , stLinkCriteria
End If
End If

ExitHere:
rs.Close
db.Close
sql = Null
Set db = Nothing
Set rs = Nothing

Form_frmIssuesDivisionSelection.SetFocus
DoCmd.Close

Exit Sub

ErrorHandler:
'Error handling code is here

end sub


THANKS FOR YOUR HELP!!!

T-
 
FireGeek822 said:
Here is the code in the Selection form. There is no code associated
with the combo box (cboDivisions), although it is bound. In the
properties of cboDivisions is the following:

RowSourceType: Table/Query
RowSource: SELECT [cboDivisions].[Division] FROM [cboDivisions] ORDER
BY [Division];


There is a command button on the Selection form. The idea is that the
user selects the item desired in the combo box and hits the [Continue]
button which opens the frmIssues form and shows only the issues for
the selected divisions.

Private Sub cmdContinue_Click()
On Error GoTo ErrorHandler

Me.cboDivisions.SetFocus
IssueDiv = Me.cboDivisions.Text
x = Me.cboDivisions.ListIndex

If IssueDiv = "" Then
MsgBox "Please select a Division" & vbCrLf & "from the drop
down box.", vbOKOnly, "Type Selection Error"
Form_frmIssuesDivisionSelection.cboDivisions.SetFocus
Exit Sub
Else
Set db = CurrentDb()
sql = "SELECT Division FROM tblIssues WHERE Division = " & "'"
& IssueDiv & "'" & ""
Set rs = db.OpenRecordset(sql)

rs.MoveFirst
rs.MoveLast

If rs.RecordCount = 0 Then
MsgBox "Your selection produced zero records.",
vbOKOnly
With Form_frmIssuesDivisionSelection
.SetFocus
.cboDivisions.SetFocus
.cboDivisions.Text = vbNullString
End With
Exit Sub
Else
stDocName = "frmIssues"
stLinkCriteria = "tblIssues![Division]=" & "'" &
IssueDiv & "'"
DoCmd.OpenForm stDocName, , , stLinkCriteria
End If
End If

ExitHere:
rs.Close
db.Close
sql = Null
Set db = Nothing
Set rs = Nothing

Form_frmIssuesDivisionSelection.SetFocus
DoCmd.Close

Exit Sub

ErrorHandler:
'Error handling code is here

end sub

You're doing an awful lot in that code that you don't need to do, and a
few things that you shouldn't do, but I don't *think* any of that is the
cause of your immediate problem. So I'll skip those for now and
concentrate on this specific problem. We can come back to those issue
later, if you like.

You say the combo box is bound. That implies that the Selection form
containing it -- "frmIssuesDivisionSelection"? -- is bound. What are
the combo box and form bound to? If the form is not updatable, either
because its recordsource is not updatable or because the form doesn't
allow edits, you won't actually be able to update the combo box.

Since you're using the combo box for record selection, I question
whether the combo box should be bound at all. Normally, a combo box
used for record selection is unbound; otherwise, making a selection to
choose a record also changes the value of bound field in the form's
current record. That's not usually what one wants to do.

If your form, "frmIssuesDivisionSelection", is just a selection form,
should it be bound? If you're not using it to display records, but only
to select records for display on another form, then I'd expect it to be
unbound.
 
Dirk,

Thanks for the information - this certainly makes sense and helps. I
will try to make the necessary adjustments. If you have other
suggestions for the other code, I am more than open to your
recommendations so I can improve.

THANKS AGAIN!

T-
 
Dirk,

Thanks for the information - this certainly makes sense and helps. I
will try to make the necessary adjustments. If you have other
suggestions for the other code, I am more than open to your
recommendations so I can improve.

THANKS AGAIN!

T-
 
FireGeek822 said:
Dirk,

Thanks for the information - this certainly makes sense and helps. I
will try to make the necessary adjustments. If you have other
suggestions for the other code, I am more than open to your
recommendations so I can improve.

Since you ask ...

Here's your original code, with comments interspersed:
Private Sub cmdContinue_Click()
On Error GoTo ErrorHandler

Me.cboDivisions.SetFocus
IssueDiv = Me.cboDivisions.Text

There's no need to set the focus to the combo box, to read its value.
Reading the Text property *does* require that, but for most purposes
what you want is the Value property, which is available at all times,
whether the control has the focus or not. It's also the default
property of all data-bound controls, so you don't have to explicitly
refer to the .Value property, though you can if you want.
x = Me.cboDivisions.ListIndex

I dont know why you're making the above assignment. I don't see where
you use "x" anywhere else, nor why you need the ListIndex for anything.

Also, I don't see a Dim statement for "x", which makes me wonder whether
you don't have Option Explicit specified for your module(s). I strongly
recommend that you specify Option Explicit for all modules -- you can
set this up by setting the "Require variable declaration" option in the
VB Editor's Tools->Options... dialog. (Modules you've already created
will have to have the Option Explicit line added by hand. If you don't
use this option, you'll continually run into errors where your
inadvertent misspelling of a variable name causes Access to think it's a
new variable. This sort of bug is hard to track down.
If IssueDiv = "" Then
MsgBox "Please select a Division" & vbCrLf & "from the drop
down box.", vbOKOnly, "Type Selection Error"
Form_frmIssuesDivisionSelection.cboDivisions.SetFocus

Don't use this form of class module reference; that is, the
"Form_<module name>" form. It works, but (a) in this case a simple ...

Me.cboDivisions.SetFocus

.... would be more efficient; (b) in other cases, if the form you
reference isn't open at the moment, that form of reference will open it
in a hidden window, which isn't usually what you would want; and (c) if
at some point you are using multiple non-default instances of a form, a
reference in that form won't reliably give you the instance you want.
Exit Sub
Else
Set db = CurrentDb()
sql = "SELECT Division FROM tblIssues WHERE Division = " & "'"
& IssueDiv & "'" & ""
Set rs = db.OpenRecordset(sql)


I see no declaration for "db", "rs", or "sql".
rs.MoveFirst
rs.MoveLast

There's no reason to do the above moves. Since you just opened the
recordset, you know that it will be at the first record if there is one,
or at both BOF and EOF if there is none. Further, if the recordset is
empty, issuing .MoveLast or .MoveFirst will raise an error. And
finally, you don't actually want to know, in this case, how many records
there are -- you just want to know if there are any. You can find that
out with a SELECT COUNT(*) query or a SELECT TOP 1 query.
If rs.RecordCount = 0 Then
MsgBox "Your selection produced zero records.",
vbOKOnly
With Form_frmIssuesDivisionSelection

Again, don't use the above form of reference.
.SetFocus

No need to set the focus to the form; it's still there.
.cboDivisions.SetFocus
.cboDivisions.Text = vbNullString

Don't set the .Text property; set the combo's Value to Null:

Me.cboDivisions = Null
End With
Exit Sub
Else
stDocName = "frmIssues"
stLinkCriteria = "tblIssues![Division]=" & "'" &
IssueDiv & "'"
DoCmd.OpenForm stDocName, , , stLinkCriteria
End If
End If

ExitHere:
rs.Close
db.Close

Don't close a database object you got from CurrentDb(). That's the
current database, and it does you no harm to call its Close method, but
Access won't do it. In general, you should only close what you opened.
sql = Null

There's no need to clear this variable, as far as I can see.
Set db = Nothing
Set rs = Nothing

Form_frmIssuesDivisionSelection.SetFocus
DoCmd.Close

If you really want to close the current form, there's no need to
SetFocus to it. Just specify its name:

DoCmd.Close acForm, Me.Name, acSaveNo

However, It would make more sense to do this only in the "Else" block
where you've opened the next form.
Exit Sub

ErrorHandler:
'Error handling code is here

end sub

I'd rewrite the original sub more like this:

'------ start of revised code ------
Private Sub cmdContinue_Click()

On Error GoTo ErrorHandler

Dim strIssueDiv As String
Dim strSQL As String
Dim rs As DAO.Recordset

If IsNull(Me.cboDivisions) Then
MsgBox _
"Please select a Division" & vbCrLf & _
"from the drop down box.", _
vbOKOnly, _
"Type Selection Error"
Else

strIssueDiv = Me.cboDivisions

strSQL = _
"SELECT TOP 1 Division FROM tblIssues " & _
"WHERE Division = '" & strIssueDiv & "'"

Set rs = CurrentDb.OpenRecordset(strSQL)

With rs

If .EOF Then

MsgBox _
"Your selection produced zero records.", _
vbOKOnly, _
"No Records Found"

Me.cboDivisions = Null

Else

DoCmd.OpenForm "frmIssues", _
WhereCondition:="[Division]='" & strIssueDiv &
"'"

DoCmd.Close acForm, Me.Name, acSaveNo

End If

.Close ' close recordset

End With

End If

ExitHere:
Set rs = Nothing
Exit Sub

ErrorHandler:
'Error handling code, usually ending up with ...
Resume ExitHere

End Sub
'------ end of revised code ------
 
Hi Dirk,

Lots of great suggestions. Thank you for all the time you spent on
this. I should have evalutated the code better before posting.

First, I have Option Explicit turned on. I do have the variables
declared - they are in a separate Module. I have found putting them
all in a separate module allows me to be able to use them throughout my
project vs re-declaring them over and over.

x = Me.cboDivisions.ListIndex - This was left in there by mistake. I
was looking at it while stepping through the code. Probably should
have checked it in the immediate window instead.
With Form_frmIssuesDivisionSelection
.SetFocus

This was an oops!

I never used the SELECT TOP 1 before. Great idea - will have to start
using it.

Thanks again for all your time/effort in this. Your suggestions won't
go unnoticed. I will incorporate them and definately use the SELECT
TOP 1 in the future.

Tammy
 
FireGeek822 said:
Hi Dirk,

Lots of great suggestions. Thank you for all the time you spent on
this. I should have evalutated the code better before posting.

First, I have Option Explicit turned on. I do have the variables
declared - they are in a separate Module. I have found putting them
all in a separate module allows me to be able to use them throughout
my project vs re-declaring them over and over.

Forgive me for saying so, but this is not a good policy. Variables for
local use should be declared locally. Global variables have their uses,
but using them just to avoid declaring local variables is not a good
one. The whole idea of variable scoping is to prevent the kind of
errors that can occur when different procedures use the same variables;
to insulate one procedure from the operations of another.

Furthermore, if you use global object variables, you had better make
double sure that you set all those variables to Nothing before exiting
the application. Otherwise, you may find that Access remains running in
the background, even though you may not see its window on your desktop
any more.
Thanks again for all your time/effort in this. Your suggestions won't
go unnoticed. I will incorporate them and definately use the SELECT
TOP 1 in the future.

You're welcome. Pardon the lecture.
 
Dirk -

I don't consider it a lecture, rather a bit of instruction. Looks like
a colleague's recommendations really aren't good recommendations
(that's where I got the idea of declaring all variables in one module).

Again, thank you. Looks like I have a lot of code clean-up to do.

Tammy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top