Reputation: 1714
While working on an application I had trouble getting a selected item in my listbox to actually output the correct row value. I was using the .Selected
method to choose which row needed to be selected in order to proceed to the next step, which would pull the bound column's value from the listbox for further processing, without the need of the user to interact with the listbox.
It turns out that .Selected
doesn't work the same way as clicking on a listbox row, as its output value remains the last "manually" selected row's bound column value.
I realized I had to follow up the .Selected
method with a .ItemData
method to actually have the listbox output value to equal the row that I selected in the .Selected
method.
Here is the code I used to copy selections on a Vendor PN Lookup Form to a Main Part Search Form:
Private Sub cmdAddTofrmPartSearch_Click()
Dim i as Integer
... [truncated]
Forms("frmPartSearch").lstSearchResults.Selected(i - 1) = True
... [truncated]
Forms("frmPartSearch").txtHiddenPN.Value
= Forms("frmPartSearch").lstSearchResults.ItemData(i - 1)
...[truncated]
End Sub
As above, why do I need to use:
Forms("frmPartSearch").lstSearchResults.Selected(i - 1) = True
AND
Forms("frmPartSearch").txtHiddenPN.Value
= Forms("frmPartSearch").lstSearchResults.ItemData(i - 1)
To get txtHiddenPN
to receive the correct row value instead of simply setting txtHiddenPN
's control source to =[lstSearchResults]
and have it update to the row value after .Selected
?
What use is .Selected
if it doesn't change the output value of the listbox (other than handily, but futilely highlighting a row)? And similarly, why doesn't .ItemData
also highlight the row whose bound value is being outputted? Is this bad design, or is there another method that achieves both results simultaneously? Is it best practice to automatically include both methods sequentially? Are there situations where only one method needs to be called?
I'm new to VBA and coding in general, so maybe this is a common occurrence in the field, but it just seems obtuse.
Upvotes: 1
Views: 6302
Reputation: 29421
"Selected" ListBox property doesn't affect "Value" one
it doesn't even trigger events
"Selected" property is mainly used to check which listbox elements is selected
you may want to check this
so you wouldn't need Forms("frmPartSearch").lstSearchResults.Selected(i - 1) = True
codeline since it has no effect to your code
to have a more thorough knowledge of listbox functioning you may also want to play with it as follows
add this code in a module of your Project
Option Explicit
Sub PlayWithListBox()
With UserForm4
With .ListBox1
.AddItem "a1"
.AddItem "a2"
.AddItem "a3"
.AddItem "a4"
End With
.Show
MsgBox "going to use Select property"
With .ListBox1
.Selected(2) = True
Call ShowValueAndListIndex(.value, .List(.ListIndex))
End With
End With
Unload UserForm4
End Sub
Sub ShowValueAndListIndex(valueStrng As String, listIndexStr As String)
MsgBox "Value: " & valueStrng
MsgBox "listIndex: " & listIndexStr
End Sub
then add to your Project
and finally add the following code in "UserForm4" code module
Private Sub ListBox1_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
MsgBox "BeforeUpdate"
With Me.ListBox1
If .ListIndex >= 0 Then Call ShowValueAndListIndex(.value, .List(.ListIndex))
End With
End Sub
Private Sub ListBox1_Change()
MsgBox "Change"
With Me.ListBox1
If .ListIndex >= 0 Then Call ShowValueAndListIndex(.value, .List(.ListIndex))
End With
End Sub
Private Sub ListBox1_Click()
MsgBox "Click"
With Me.ListBox1
If .ListIndex >= 0 Then Call ShowValueAndListIndex(.value, .List(.ListIndex))
End With
End Sub
Private Sub ListBox1_Enter()
MsgBox "Enter"
With Me.ListBox1
If .ListIndex >= 0 Then Call ShowValueAndListIndex(.value, .List(.ListIndex))
End With
End Sub
Private Sub ListBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
MsgBox "KeyDown"
With Me.ListBox1
If .ListIndex >= 0 Then Call ShowValueAndListIndex(.value, .List(.ListIndex))
End With
End Sub
Private Sub ListBox1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
MsgBox "MouseDown"
With Me.ListBox1
If .ListIndex >= 0 Then Call ShowValueAndListIndex(.value, .List(.ListIndex))
End With
End Sub
Upvotes: 1