Author Topic: MultiSelect ListBox woes...  (Read 4623 times)

0 Members and 1 Guest are viewing this topic.

Columbia

  • Guest
MultiSelect ListBox woes...
« on: June 24, 2004, 02:39:13 PM »
All right guys, here's one that might be real easy, and then again it might not...  But first let me preface this with the fact that I'm a noob at VBA but an old hand at VLisp & DCL, with lots of experience doing neat stuff with the latter two.  Okay with that said here's my question...

I've got a ListBox with the MultiSelect Property set to 2.  How can I tell when the user has selected anything.  To expound just a little, if the MultiSelect property was set to 0, I could use the Click() event to tell when a user has picked something.  But what's the equivalent event for a ListBox with MultiSelect=2?

Thanks for any and all help you can give this wanderer of the great wide VBA...

MP

  • Seagull
  • Posts: 17653
  • Have thousands of dwgs to process? Contact me.
MultiSelect ListBox woes...
« Reply #1 on: June 24, 2004, 03:15:22 PM »
Just a quick though off the top of me nuggin', but did you try trapping any of the other events like mouseup / keyup and then subsequently determine if any items are selected?
Engineering Technologist • Programmer Analyst • CAD Specialist
Multi-Discipline • Design • Drafting • Document Control • Automation.
cadanalyst@gmail.comwww.linkedin.com/in/cadanalyst

Columbia

  • Guest
MultiSelect ListBox woes...
« Reply #2 on: June 24, 2004, 03:45:44 PM »
Umm... No I haven't tried that.  But I will.  Can you think of anything else, in the mean time?

Jeff_M

  • King Gator
  • Posts: 3975
  • C3D user & customizer
MultiSelect ListBox woes...
« Reply #3 on: June 24, 2004, 04:21:19 PM »
I think it would depend on what you want to do. If you are allowing multiple selections why do you need to see when anything is selected?

If you want to verify that there is, in fact, something selected prior to doing something else, check the selected property of each item in the listbox......

HTH
Jeff

SMadsen

  • Guest
MultiSelect ListBox woes...
« Reply #4 on: June 24, 2004, 05:54:31 PM »
The help files has a small example of single to multiple selections:

Quote
To use this example, copy this sample code to the Declarations portion of a form. Make sure that the form contains:

- Two ListBox controls named ListBox1 and ListBox2.

- A CommandButton named CommandButton1.

- Three OptionButton controls named OptionButton1 through OptionButton3.


Dim i As Integer

Private Sub CommandButton1_Click()
    ListBox2.Clear
   
    For i = 0 To 9
        If ListBox1.Selected(i) = True Then
            ListBox2.AddItem ListBox1.List(i)
        End If
    Next i
End Sub

Private Sub OptionButton1_Click()
    ListBox1.MultiSelect = fmMultiSelectSingle
End Sub

Private Sub OptionButton2_Click()
    ListBox1.MultiSelect = fmMultiSelectMulti
End Sub

Private Sub OptionButton3_Click()
    ListBox1.MultiSelect = fmMultiSelectExtended
End Sub

Private Sub UserForm_Initialize()
    For i = 0 To 9
        ListBox1.AddItem "Choice " & (ListBox1.ListCount + 1)
    Next i
   
    OptionButton1.Caption = "Single Selection"
    ListBox1.MultiSelect = fmMultiSelectSingle
    OptionButton1.Value = True
   
    OptionButton2.Caption = "Multiple Selection"
    OptionButton3.Caption = "Extended Selection"
   
    CommandButton1.Caption = "Show selections"
    CommandButton1.AutoSize = True
End Sub

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16779
  • Superior Stupidity at its best
MultiSelect ListBox woes...
« Reply #5 on: June 24, 2004, 07:33:14 PM »
Well, it looks like the work here is done ... see what happens when the internet connection goes wacko ...

I typically use the focus event for multi-select list boxes (i.e. EXIT), this way when they lose the focus, you can step through each of the listbox elements and determine if it is selected.

For example:
Code: [Select]

Private Sub ListBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
 On Error Resume Next
 For X = 0 To ListBox1.ListCount - 1
  If ListBox1.Selected(X) = True Then
  MsgBox ListBox1.List(X)
  End If
 Next X
End Sub
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Columbia

  • Guest
MultiSelect ListBox woes...
« Reply #6 on: June 25, 2004, 10:42:09 AM »
Keith,

I like your idea.  I will probably try that next.  But let me explain a little better.

I'm trying to duplicate a the functionality of a DCL list box with multiple_select=true;.  When anything is done in that list box (selecting one, or more, as they are being selected) the index stirng is immediately returned to the action_tile expression even if the user hasn't clicked on another feature of the box.  Do you follow me?

Because what I want to do is: as the user is selecting in the listbox I want the program to be processing the selected items on the fly.  does that make any more sense?

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16779
  • Superior Stupidity at its best
MultiSelect ListBox woes...
« Reply #7 on: June 25, 2004, 08:30:48 PM »
Ok, then try this one ... it is a little tricky because you are not validating the selection of the item. This can present a problem in multiple selection listboxes because the previous or next item may have been select and programmatically the only way to find out if it was selected is to check the entire list and compare it against a previous list.

Anyway, In my programming I have found that the number that most closely represents the number in Y coordinates in a list box is 9.75 per item.
So, to check which was selected you would do this:

Code: [Select]

Private Sub ListBox1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)

 Dim SelectedItem As Long
 
 SelectedItem = Fix(Y / 9.75) + ListBox1.TopIndex
 If (Button = 1) And (SelectedItem < ListBox1.ListCount) Then
  'do your initialization here
 End If
End Sub


Essentially we are grabbing the Y coordinate and dividing it by 9.75, that will give us a number that is close to the index count. We will then "fix" that number and then find that item in the list.

There may be a more elegant way of determining the index to select, by using rounding, but this works for me 99.9% of the time.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

SMadsen

  • Guest
MultiSelect ListBox woes...
« Reply #8 on: June 26, 2004, 07:29:37 AM »
Couldn't you just use the Change event in case user makes selection via mouse AND keyboard?

For example:

Code: [Select]
Private Sub ListBox1_Change()
Dim i As Integer
Dim myItems() As String

  ReDim myItems(ListBox1.ListCount)
  For i = ListBox1.TopIndex To ListBox1.ListCount - 1
    If ListBox1.selected(i) = True Then
      'sweep up selected in an array to process
      myItems(i) = ListBox1.List(i)
    End If
  Next i

  'do some processing of selected items
  processSelected myItems()
End Sub

'Assuming the form has two listboxes, this could be some processing sub:

Private Sub processSelected(selected() As String)
  ListBox2.Clear
  For i = LBound(selected) To UBound(selected)
    If selected(i) <> "" Then ListBox2.AddItem selected(i)
  Next i

End Sub


I have no idea how to only sweep up the actually selected items (without blanks in the array) but then, I don't really know VBA.

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16779
  • Superior Stupidity at its best
MultiSelect ListBox woes...
« Reply #9 on: June 27, 2004, 03:17:24 PM »
Dangit ... my solution was on the other server ... BEFORE we were notified that it would not be making it's way back here.....

Oh well... a twist on Stig's to make sure you only have the correct number if items selected in your array AND to select all items in the list to correctly get everything ......

So here goes again ...

Code: [Select]

'code to call the function to grab selected items
Private Sub ListBox1_Change()
 Dim RVal As Variant
  RVal = PutSelectedInArray(UserForm1.ListBox1)
  processSelected RVal
End Sub

'code to populate a second listbox to see that it works
Private Sub processSelected(ByVal IsSelected As Variant)
  ListBox2.Clear
  For i = LBound(IsSelected) To UBound(IsSelected)
    ListBox2.AddItem IsSelected(i)
  Next i
End Sub

'code to populate listbox1 with 25 items
Private Sub UserForm_Activate()
 For X = 1 To 25
  ListBox1.AddItem "ListItem" & X
 Next X
End Sub

'function to get entire selected list in listbox control passed to function
Private Function PutSelectedInArray(ByRef WhichListBox As ListBox) As Variant
  Dim ListItems() As Variant
  Dim Index As Integer
  Index = 0
  For X = 0 To WhichListBox.ListCount - 1
   If WhichListBox.selected(X) = True Then
    ReDim Preserve ListItems(Index) As Variant
    ListItems(Index) = WhichListBox.List(X)
    Index = Index + 1
   End If
  Next X
  PutSelectedInArray = ListItems
End Function


If you have any problems let us know ...
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Columbia

  • Guest
MultiSelect ListBox woes...
« Reply #10 on: June 28, 2004, 04:10:36 PM »
Thanks Keith, Thanks Stig.  I think this is going to do it.  I've tried it out and so far so good!

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16779
  • Superior Stupidity at its best
MultiSelect ListBox woes...
« Reply #11 on: June 28, 2004, 04:21:18 PM »
No problem .. I live to code ...
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal