+ Reply to Thread
Results 1 to 20 of 20

Add Select All item to UserForm ListBox (created by Leth Ross)

Hybrid View

  1. #1
    Forum Contributor
    Join Date
    05-24-2006
    Location
    Los Angeles
    MS-Off Ver
    2019
    Posts
    328

    Add Select All item to UserForm ListBox (created by Leth Ross)

    Hi,

    I got this code from Leith that uses a UserForm ListBox to filter items and it VBA Userform ListBox load selected.xls works brilliantly. Does anyone know how I could add a "Select All" option as the first ListBox item when there are 2 or more items? Then the user can select/deselect all the items.

    Thanks,

    Lawrence

  2. #2
    Forum Guru
    Join Date
    07-25-2011
    Location
    Florida
    MS-Off Ver
    Excel 2003
    Posts
    9,651

    Re: Add Select All item to UserForm ListBox (created by Leth Ross)

    This will select\deselect all using a checkbox control on the UserForm

    Private Sub CheckBox1_Click()
        'Select\Deselect All all items in ListBox1
        Dim i As Long
        With ListBox1
            For i = 0 To .ListCount - 1
                .Selected(i) = CheckBox1.Value
            Next i
        End With
    End Sub
    Last edited by AlphaFrog; 06-12-2012 at 01:18 PM.

  3. #3
    Forum Contributor
    Join Date
    05-24-2006
    Location
    Los Angeles
    MS-Off Ver
    2019
    Posts
    328

    Re: Add Select All item to UserForm ListBox (created by Leth Ross)

    Very cool, AlphaFrog!

    Just one bug... It seems the Scripting Dictionary does not retain the Checked All setting. If you have say 1 item checked, hit the SelectAll, close the UserForm and reopen it, the original 1 item checked is again the only item checked. It should be every item checked since you closed the USerForm when that was selected.

    Is the solution to run the Scripting Dictionary on UserForm close??? Is there such a method?

    Thanks for your help!

    Lawrence

  4. #4
    Forum Guru
    Join Date
    07-25-2011
    Location
    Florida
    MS-Off Ver
    Excel 2003
    Posts
    9,651

    Re: Add Select All item to UserForm ListBox (created by Leth Ross)

    Private Sub CheckBox1_Click()
        'Select\Deselect All all items in ListBox1
        Dim i As Long
        If Not CheckBox1 Is ActiveControl Then Exit Sub
        With ListBox1
            For i = 0 To .ListCount - 1
                .Selected(i) = CheckBox1.Value
            Next i
            
            Sheet1.Range("TheListSelected").ClearContents
            If CheckBox1.Value Then Sheet1.Range("TheListSelected").Resize(.ListCount).Value = .List
            
        End With
        
    End Sub
    
    Private Sub ListBox1_Change()
    
        Dim i As Integer
        Dim r As Integer
        Dim counter As Long
        
        If Not ListBox1 Is ActiveControl Then Exit Sub
        
        r = 0
        Sheet1.Cells(5, 3).Resize(65531, 1).ClearContents
        
        
        With ListBox1
                
            For i = 0 To .ListCount - 1
                If .Selected(i) Then
                    r = r + 1
                    Sheet1.Cells(r + 4, 3).Value = .Column(0, i)
                    counter = counter + 1
    '   To place selected items on sheet next to their respective list item (also done by CommandButton below)
    '                Sheet1.Cells(r + 4, 3).Value = .Column(0, i)
    
    '   Use if have multi column ListBox
    '                Sheet1.Cells(i, 2).Value = .Column(1, i)
    '                Sheet1.Cells(i, 3).Value = .Column(2, i)
    '                Sheet1.Cells(i, 4).Value = .Column(3, i)
                End If
            Next i
            
            CheckBox1.Value = counter = .ListCount
            
        End With
        
    End Sub
    
    
    Private Sub UserForm_Initialize()
    
      Dim DSO As Object
      Dim i As Long
      Dim counter As Long
      
        With ThisWorkbook.Sheets(1)
    '   ListBox1.List expects an array > 1 cell; if only 1 cell use AddItem
            If .Evaluate("TheListCount") = 1 Then
                ListBox1.AddItem (Range("TheList"))
            End If
            
            If .Evaluate("TheListCount") > 1 Then
                 ListBox1.List = Range("TheList").Value
            End If
                    
            If .Evaluate("TheListCount") = 0 Then
                Sheet1.Cells(5, 3).Resize(65531, 1).ClearContents
            End If
            
        End With
        
    '   Pre loads selected items (no duplicates...however a pivot table can eliminate duplicates)
        Set DSO = CreateObject("Scripting.Dictionary")
        DSO.CompareMode = vbTextCompare
    
           For i = 0 To ListBox1.ListCount - 1
             DSO.Add ListBox1.List(i), i
           Next i
           
           ListBox1.ListIndex = -1
    
           For Each cell In Sheet1.Range("TheListSelected")
             If DSO.Exists(cell.Text) Then
                ListBox1.Selected(DSO(cell.Text)) = True
                counter = counter + 1
            End If
           Next cell
    
        CheckBox1.Value = counter = DSO.Count
        
        Set DSO = Nothing
    
    End Sub
    
    
    Private Sub CommandButton1_Click()
    
    '   Place selected items on sheet next to their respective list item
    
        Dim i As Integer
        Dim r As Integer
        r = 0
        Sheet1.Cells(5, 3).Resize(65531, 1).ClearContents
        With ListBox1
            For i = 0 To .ListCount - 1
                If .Selected(i) Then
                    r = r + 1
                    Sheet1.Cells(i + 5, 3).Value = .Column(0, i)
    
    '   Use if have multi column ListBox
    '                Sheet1.Cells(i, 2).Value = .Column(1, i)
    '                Sheet1.Cells(i, 3).Value = .Column(2, i)
    '                Sheet1.Cells(i, 4).Value = .Column(3, i)
                End If
            Next i
        End With
    End Sub

  5. #5
    Forum Contributor
    Join Date
    05-24-2006
    Location
    Los Angeles
    MS-Off Ver
    2019
    Posts
    328

    Re: Add Select All item to UserForm ListBox (created by Leth Ross)

    AlphaFrog rocks!

    Works perfectly. Thank you.

    Curious...since this code relies in the Scripting Dictionary to store the selected items and there is only one Scripting Dictionary, it would not be possible to have more than one of these kind of ListBoxes on the same UserForm, would it? Say you wanted to select European countries in one ListBox and Asian countries in a second ListBox, this code prevents them from being on the same form, no?

    Lawrence
    Last edited by skysurfer; 06-12-2012 at 05:47 PM.

  6. #6
    Forum Guru
    Join Date
    07-25-2011
    Location
    Florida
    MS-Off Ver
    Excel 2003
    Posts
    9,651

    Re: Add Select All item to UserForm ListBox (created by Leth Ross)

    The Scripting Dictionary is not really used to store your selected items. In this case, the Scripting Dictionary is only used to avoid an error when selecting ListBox items when you Activate the UserForm. Once the listbox is populated and all the proper items are selected, the Scripting Dictionary is not used any more. You could clear it and use it again to populate a different ListBox. Or you could create a second new Scripting Dictionary if you want.

    The selected ListBox values are stored in Sheet1.Range("TheListSelected"). Each time the selected items in the ListBox is changed, those changes are updated on the worksheet. If your selected items list Sheet1.Range("TheListSelected") will never have typed in values that are not included in the original ListBox list Range("TheList"), then you really don't need to use a scripting dictionary.

    So the answer to your question is yes you can have more than one of these types listboxes on the userform. The code doesn't rely on the Scripting Dictionary to store the selected items and you could have more than one Scripting Dictionary if you want.

  7. #7
    Forum Contributor
    Join Date
    05-24-2006
    Location
    Los Angeles
    MS-Off Ver
    2019
    Posts
    328

    Re: Add Select All item to UserForm ListBox (created by Leth Ross)

    Okay, if the "TheListSelected" range is never manually typed into by the user, then there is no need to use the scripting dictionary and I can simply load the ListBox (or ListBoxes) with the range "TheListsSelected".

    How do I do that? Ive tried several times after deleting the Scripting Dictionary lines but I think I deleted too much or your counter code is throwing me.

    Thanks again!

    Lawrence
    Last edited by skysurfer; 06-12-2012 at 06:47 PM.

  8. #8
    Forum Guru
    Join Date
    07-25-2011
    Location
    Florida
    MS-Off Ver
    Excel 2003
    Posts
    9,651

    Re: Add Select All item to UserForm ListBox (created by Leth Ross)

    Do you really want the Align Selections with Source button. The code could automatically align the selection when the user makes the selections in the lisbox.

  9. #9
    Forum Contributor
    Join Date
    05-24-2006
    Location
    Los Angeles
    MS-Off Ver
    2019
    Posts
    328

    Re: Add Select All item to UserForm ListBox (created by Leth Ross)

    No. That was something Leith added and I keep it in my bag of tricks...in this test file.

    Are you you teacher? That explanation of the Scripting Dictionary really hit it out of the park. I totally get it now.

    Anyway, thanks again for all your help. Hoping to see what I goofed up when I look at your solution on opening the the UserForm with selections already marked as true.

    Lawrence

  10. #10
    Forum Guru
    Join Date
    07-25-2011
    Location
    Florida
    MS-Off Ver
    Excel 2003
    Posts
    9,651

    Re: Add Select All item to UserForm ListBox (created by Leth Ross)

    Private Sub CheckBox1_Click()
    
        'Select\Deselect All all items in ListBox1
        Dim i As Long
        
        If Not CheckBox1 Is ActiveControl Then Exit Sub
        
        With ListBox1
        
            'Selecet or Deselect each item in the Listbox
            For i = 0 To .ListCount - 1
                .Selected(i) = CheckBox1.Value
            Next i
            
            If CheckBox1.Value Then
                ' If Select All is checked, write all items to the Selected List
                Range("TheList").Offset(, 2).Value = .List
            Else
                ' Clear the selected list
                Range("TheList").Offset(, 2).ClearContents
            End If
        
        End With
        
    End Sub
    
    Private Sub ListBox1_Change()
    
        Dim i As Long
        
        If Not ListBox1 Is ActiveControl Then Exit Sub
        
        CheckBox1.Value = True  'Default setting
        
        'Write selected items to list
        With ListBox1
            
            For i = 1 To .ListCount             ' Loop through each item in the ListBox
                If .Selected(i - 1) Then
                    'Add selected items to the Selected List
                    Range("TheList")(i).Offset(, 2).Value = Range("TheList")(i)
                Else
                    ' Remove unselected items from the Selected List
                    Range("TheList")(i).Offset(, 2).ClearContents
                    CheckBox1.Value = False
                End If
            Next i
            
        End With
        
    End Sub
    
    
    Private Sub UserForm_Initialize()
    
      Dim cell As Range
      
        'Define the list as a named range
        With Sheets("HappySheet")
            Application.Names.Add "TheList", .Range("A5", .Range("A" & Rows.Count).End(xlUp))
        End With
      
        CheckBox1.Value = True  'Default setting
      
        With ListBox1
        
           For Each cell In Range("TheList")                 ' Loop through each cell in the list
                .AddItem cell.Value                          ' Add items to the ListBox
                If cell.Offset(, 2).Value = cell.Value Then  ' test if the item is in the Selected List
                    .Selected(.ListCount - 1) = True         ' Select the item in the Listbox
                Else
                    CheckBox1.Value = False                  ' Unheck the Select All checkbox one item is not selected
                End If
           Next cell
            
        End With
    
    End Sub

  11. #11
    Forum Contributor
    Join Date
    05-24-2006
    Location
    Los Angeles
    MS-Off Ver
    2019
    Posts
    328

    Re: Add Select All item to UserForm ListBox (created by Leth Ross)

    Oh, now this is very cool.

    The coding is cleaner and more elegant. The comments are a REAL help. AND you threw in a bonus...the ListBox1_Change code positions the selected item aligned with its source without the need for an added button/code. I (rather, ALL those who peruse this forum for solutions) now have two working options!!!

    What an education today.

    Cheers to the AlphaFrog!

  12. #12
    Forum Guru
    Join Date
    07-25-2011
    Location
    Florida
    MS-Off Ver
    Excel 2003
    Posts
    9,651

    Re: Add Select All item to UserForm ListBox (created by Leth Ross)

    You're welcome and thanks for the feedback.

  13. #13
    Forum Contributor
    Join Date
    05-24-2006
    Location
    Los Angeles
    MS-Off Ver
    2019
    Posts
    328

    Re: Add Select All item to UserForm ListBox (created by Leth Ross)

    AlphaFrog,

    Had a quick follow-up question. (BTW, thanks for letting me know about the notifications...mine needed to be switched on).

    In our code of pre-loading the already selected items on a UserForm ListBox, would it be possible to have the main list of items ("TheList") on a separate sheet than the selected items list ("TheListSelected")?

    Specifically, this line of code in the Userform_Initialize: If ListItem.Offset(, 2).Value = ListItem.Value Then.

    Private Sub UserForm_Initialize()
    
      Dim ListItem As Range
      
        'Define the list as a named range
        With Sheets("HappySheet")
            Application.Names.Add "TheList", .Range("A5", .Range("A" & Rows.Count).End(xlUp))
        End With
      
        CheckBox1.Value = True  'Default setting
      
        With ListBox1
        
           For Each ListItem In Range("TheList")                    ' Loop through each cell in the list
                .AddItem ListItem.Value                             ' Add items to the ListBox
                If ListItem.Offset(, 2).Value = ListItem.Value Then ' test if the item is in the Selected List
                    .Selected(.ListCount - 1) = True                ' Select the item in the Listbox
                Else
                    CheckBox1.Value = False                         ' Unheck the Select All checkbox if one item is not selected
                End If
           Next ListItem
            
        End With
    
    End Sub
    The reason I ask is because "TheList" is actually from a Pivot Table on another sheet than the sheet containing the selected items. So, I've been trying to figure out a way to say something like:

    Range("TheListSelected").Row(ListItem).Value = ListItem.Value Then

    But as you can see, that no worky.

    Thanks,

    Lawrence
    Last edited by skysurfer; 06-23-2012 at 03:15 AM.

  14. #14
    Forum Guru
    Join Date
    07-25-2011
    Location
    Florida
    MS-Off Ver
    Excel 2003
    Posts
    9,651

    Re: Add Select All item to UserForm ListBox (created by Leth Ross)

    If the two lists ("TheList" and "TheListSelected") are on two different sheets, do you want the "TheListSelected" to be a contiguous list of the selected items, or aligned with "TheList" with empty cells for non-selected items?

    One simple fix would be to duplicate "TheList" on Sheet2 and name it "TheListSelected".

    Private Sub UserForm_Initialize()
    
      Dim ListItem As Range
      
        'Define the list as a named range
        With Sheets("HappySheet")
            Application.Names.Add "TheList", .Range("A5", .Range("A" & Rows.Count).End(xlUp))
        End With
        
        'Define the Seletcted items list as a named range (Duplicate of "TheList")
        With Sheets("Sheet2")
            Application.Names.Add "TheListSelected", .Range("A2").Resize(Range("TheList").Count)
            .Range("A1:B1").Value = Array("The List", "Selected Items") 'Headers
            .Range("TheListSelected").Value = Range("TheList").Value    'Duplicate the list
        End With
    Then change the rest of the code to reference "TheListSelected" instead of "TheList"

  15. #15
    Forum Contributor
    Join Date
    05-24-2006
    Location
    Los Angeles
    MS-Off Ver
    2019
    Posts
    328

    Re: Add Select All item to UserForm ListBox (created by Leth Ross)

    AlphaFrog,

    Yes, simple works. I'll just make a copy of the Pivot Table list of items to the same sheet as the selected items. But a contiguous list of the selected items would ideal...it would make my subsequent lookup formulas so much less complicated. Is there a way to eliminate those spaces, if any?

    Lawrence

  16. #16
    Forum Guru
    Join Date
    07-25-2011
    Location
    Florida
    MS-Off Ver
    Excel 2003
    Posts
    9,651

    Re: Add Select All item to UserForm ListBox (created by Leth Ross)

    Quote Originally Posted by skysurfer View Post
    But a contiguous list of the selected items would ideal...it would make my subsequent lookup formulas so much less complicated. Is there a way to eliminate those spaces, if any?
    Private Sub CheckBox1_Click()
    
        'Select\Deselect All all items in ListBox1
        Dim i As Long
    
        If Not CheckBox1 Is ActiveControl Then Exit Sub
    
        With ListBox1
    
            'Selecet or Deselect each item in the Listbox
            For i = 0 To .ListCount - 1
                .Selected(i) = CheckBox1.Value
            Next i
    
            If CheckBox1.Value Then
                ' If Select All is checked, write all items to TheListSelected
                Range("TheListSelected").Value = .List
                
            Else
                ' Clear the selected list
                Range("TheListSelected").ClearContents
            End If
    
        End With
    
    End Sub
    
    Private Sub ListBox1_Change()
    
        Dim i As Long, r As Long
    
        If Not ListBox1 Is ActiveControl Then Exit Sub
    
        CheckBox1.Value = True  'Default setting for "Select All" checkbox
        Range("TheListSelected").ClearContents 'Clear "TheListSelected"
    
        'Write selected items to "TheListSelected"
        With ListBox1
    
            For i = 1 To .ListCount             ' Loop through each item in the ListBox
                If .Selected(i - 1) Then
                    'Add selected items to "TheListSelected"
                    r = r + 1
                    Range("TheListSelected")(r).Value = Range("TheList")(i)
                Else
                    ' Uncheck "Select All" checkbox
                    CheckBox1.Value = False
                End If
            Next i
    
        End With
    
    End Sub
    
    Private Sub UserForm_Initialize()
    
      Dim ListItem As Range
    
        'Define the list as a named range
        With Sheets("HappySheet")
            Application.Names.Add "TheList", .Range("A5", .Range("A" & Rows.Count).End(xlUp))
        End With
    
        'Define the selections from the list as a named range on sheet2
        With Sheets("Sheet2")
            Application.Names.Add "TheListSelected", .Range("A2").Resize(Range("TheList").Rows.Count)
        End With
    
        CheckBox1.Value = True  'Default setting
    
        With ListBox1
    
           For Each ListItem In Range("TheList")                    ' Loop through each cell in the list
                .AddItem ListItem.Value                             ' Add items to the ListBox
                ' test if the item is in the Selected List
                If WorksheetFunction.CountIf(Range("TheListSelected"), ListItem) Then
                    .Selected(.ListCount - 1) = True                ' Select the item in the Listbox
                Else
                    CheckBox1.Value = False                         ' Unheck the Select All checkbox if one item is not selected
                End If
           Next ListItem
    
        End With
    
    End Sub

  17. #17
    Forum Contributor
    Join Date
    05-24-2006
    Location
    Los Angeles
    MS-Off Ver
    2019
    Posts
    328

    Re: Add Select All item to UserForm ListBox (created by Leth Ross)

    AlphaFrog,

    This is great stuff. I'm going to post my completed "reference" file that I keep in my bag of tricks folder for others searching for this feature.

    There is one bug...the second ListBox requires TWO mouse clicks to make an item selection. Half the time the UserForm is loaded! Very wierd. I had thought that was a file corruption issue in the large file I was adding the AlphaFrog feature to, but then the bug popped up in the reference file I had built from scratch. Wonder if it's a focus issue???

    Thanks!

    Lawrence

  18. #18
    Forum Guru Andy Pope's Avatar
    Join Date
    05-10-2004
    Location
    Essex, UK
    MS-Off Ver
    O365
    Posts
    20,480

    Re: Add Select All item to UserForm ListBox (created by Leth Ross)

    The following has .SetFocus to avoid the issue of somethings having to click twice.

    Private m_blnUpdating  As Boolean
    Private Function m_IsSelectAll(Lst As MSForms.ListBox) As Boolean
    
        Dim lngIndex As Long
        
        m_blnUpdating = True
        m_IsSelectAll = True
        
        For lngIndex = 0 To Lst.ListCount - 1
            If Not Lst.Selected(lngIndex) Then
                m_IsSelectAll = False
                Exit Function
            End If
        Next
    
    End Function
    
    Private Sub m_LoadSelection(Lst As MSForms.ListBox, SelectedItems As String)
    
        Dim vntItem As Variant
        
        m_blnUpdating = True
        For Each vntItem In Split(SelectedItems, ",")
            Lst.Selected(vntItem) = True
        Next
        m_blnUpdating = False
        
    End Sub
    Private Sub m_SelectAll(Lst As MSForms.ListBox, State As Boolean)
    
        Dim lngIndex As Long
        
        m_blnUpdating = True
        
        For lngIndex = 0 To Lst.ListCount - 1
            Lst.Selected(lngIndex) = State
        Next
        
        m_blnUpdating = False
        
    End Sub
    
    Private Function m_StoreSelection(Lst As MSForms.ListBox) As String
    
        Dim lngIndex As Long
        Dim strSelect As String
        
        For lngIndex = 0 To Lst.ListCount - 1
            If Lst.Selected(lngIndex) Then
                strSelect = strSelect & lngIndex & ","
            End If
        Next
        
        If Len(strSelect) > 0 Then
            strSelect = Left(strSelect, Len(strSelect) - 1)
        End If
        
        m_StoreSelection = strSelect
        
    End Function
    
    Private Sub CheckBox1_Change()
    
        If m_blnUpdating Then Exit Sub
        
        m_SelectAll ListBox1, CheckBox1.Value
    
    End Sub
    
    Private Sub CheckBox1_Click()
    
    End Sub
    
    Private Sub CheckBox2_Change()
    
        If m_blnUpdating Then Exit Sub
        
        m_SelectAll ListBox2, CheckBox2.Value
        
    
    End Sub
    
    
    
    
    Private Sub CommandButton1_Click()
        Unload Me
    End Sub
    
    
    Private Sub CommandButton2_Click()
    
        ThisWorkbook.Names("SELECTED_LIST1").RefersToRange.Value = m_StoreSelection(ListBox1)
        ThisWorkbook.Names("SELECTED_LIST2").RefersToRange.Value = m_StoreSelection(ListBox2)
    
        Unload Me
        
    End Sub
    
    
    Private Sub ListBox1_Change()
    
        If m_blnUpdating Then Exit Sub
        
        CheckBox1.Value = m_IsSelectAll(ListBox1)
        m_blnUpdating = False
        
    End Sub
    
    Private Sub ListBox1_Click()
    
    End Sub
    
    Private Sub ListBox2_AfterUpdate()
    
    
    End Sub
    
    Private Sub ListBox2_Change()
    
        If m_blnUpdating Then Exit Sub
        
        CheckBox2.Value = m_IsSelectAll(ListBox2)
        
        m_blnUpdating = False
        
    End Sub
    
    Private Sub ListBox2_Click()
    
    End Sub
    
    Private Sub UserForm_Initialize()
    
        Dim vntList As Variant
        
        m_blnUpdating = True
        ' Load list
        vntList = ThisWorkbook.Names("TheList").RefersToRange
        ListBox1.List = vntList
        ListBox2.List = vntList
        
        ListBox1.SetFocus
        m_LoadSelection ListBox1, ThisWorkbook.Names("SELECTED_LIST1").RefersToRange.Value
        ListBox2.SetFocus
        m_LoadSelection ListBox2, ThisWorkbook.Names("SELECTED_LIST2").RefersToRange.Value
    
        m_blnUpdating = False
        
        CommandButton1.SetFocus
        
        Me.Repaint
        DoEvents
        
    End Sub
    The selection choices of each list are store in a single cell as comma delimiter list.
    Attached Files Attached Files
    Cheers
    Andy
    www.andypope.info

  19. #19
    Forum Contributor
    Join Date
    05-24-2006
    Location
    Los Angeles
    MS-Off Ver
    2019
    Posts
    328

    Re: Add Select All item to UserForm ListBox (created by Leth Ross)

    Andy,

    WOW! That is a lot of programming to resolve the double click. Thank you!

    One question: I see that you modified the first UserForm (adding in SetFocus for each ListBox). Does that mean that either UserForm may now used without the double click issue?

    Lawrence

  20. #20
    Forum Guru Andy Pope's Avatar
    Join Date
    05-10-2004
    Location
    Essex, UK
    MS-Off Ver
    O365
    Posts
    20,480

    Re: Add Select All item to UserForm ListBox (created by Leth Ross)

    The .SetFocus resolves the two clicks to select item issue.
    The other code is to prevent cascading events and reading/storing selections of the worksheet.

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts

Search Engine Friendly URLs by vBSEO 3.6.0 RC 1