Excel vba if listbox not selected

  • #1

I have a listbox that may or may not be populated with items. If it is populated then the users can select multiple items in the listbox. How do I go about checking if nothing has been selected in the listbox when its empty or has items in there? Can this be done without looping through every item in the list to check if it has been selected?

Thanks

What did Pito Salas invent?

Pito Salas, working for Lotus, popularized what would become to be pivot tables. It was released as Lotus Improv in 1989.

  • #2

Where is the ListBox located at… on a UserForm or on a worksheet? If on a worksheet, what kind of ListBox is it… a Forms control or an ActiveX control?

  • #3

Where is the ListBox located at… on a UserForm or on a worksheet? If on a worksheet, what kind of ListBox is it… a Forms control or an ActiveX control?

It is located on a userform named userform1 inside a frame called frame1. SOrry I should have been more specific!

RoryA

RoryA

MrExcel MVP, Moderator


  • #4

Can this be done without looping through every item in the list to check if it has been selected?

No, I don’t believe so.

  • #5

If I were to just loop through, do you have any code on hand to do this?

  • #6

Assuming your listbox is named ListBox1, put this in whatever procedure you want to use to check the listbox from…

Code:

Dim X As Long, FoundOne As Boolean
For X = 0 To ListBox1.ListCount
  If ListBox1.Selected(X) Then
    FoundOne = True
    Exit For
  End If
Next
If FoundOne Then
  MsgBox "At least one item is selected"
Else
  MsgBox "No items are selected"
End If

  • #7

Its strange Visual basic has a method to check without looping through and vba doesnt but I guess this will do! Thanks for the code!

  • #8

Assuming your listbox is named ListBox1, put this in whatever procedure you want to use to check the listbox from…

Code:

Dim X As Long, FoundOne As Boolean
For X = 0 To ListBox1.ListCount
  If ListBox1.Selected(X) Then
    FoundOne = True
    Exit For
  End If
Next
If FoundOne Then
  MsgBox "At least one item is selected"
Else
  MsgBox "No items are selected"
End If

One question though. Why do we not have to subtract 1 for the listbox1.listcount? Say there was 2 items in the listbox then technically it should be such that listcount gives 3 so .selected(3) shouldnt work since that starts 0 to 2 I thought. Its not drawing an error and I cannot figure out why.

  • #9

One question though. Why do we not have to subtract 1 for the listbox1.listcount? Say there was 2 items in the listbox then technically it should be such that listcount gives 3 so .selected(3) shouldnt work since that starts 0 to 2 I thought. Its not drawing an error and I cannot figure out why.

Thank you for noting that… yes, it should be ListBox1 — 1 and for the reason you stated.

Last edited: May 31, 2017

Young Grasshopper

Young Grasshopper

Avatar of andy7789

andy7789

 asked on 6/29/2009

Hi x-perts,

how can I check if  none of the listbox items for a multiselect box are selected?

For a single select box I can use

listBox.ListIndex <> -1

But for a multiSelect box it has a value 0, if nothing is selected as well as the first item is selected

Thanks

Visual Basic ClassicVB ScriptMicrosoft Excel

Avatar of undefined

Try this:

Private Function IsRowSelected() as Boolean
Dim i as Integer

IsRowSelected = False
For i = 0 to listbox.ListCount-1
  If listbox.Selected(i) = True Then IsRowSelected = True
  Exit For
Next i
End Function

Sorry, should be this:

Private Function IsRowSelected() as Boolean
Dim i as Integer
 
IsRowSelected = False
For i = 0 to listbox.ListCount-1
  If listbox.Selected(i) = True Then 
    IsRowSelected = True
    Exit For
  End If
Next i
End Function

Open in new window

Well, it could work, but I cannot afford looping here just to see that nothing is selected, because that list may be huge.

I need to find something to check it instantly. probably, i should check what the listbox.value is if nothing is selected….

Of course!!

Try:
If listbox.Selected(listbox.ListIndex) = True Then

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.

View this solution by signing up for a free trial.

Members can start a

7-Day free trial

and enjoy unlimited access to the platform.

Sorry, your code returns false, if nothing is selected OR the first item is selected.

Did you try it like this?

If listbox.Selected(listbox.ListIndex) = False Then

yes, i did — see my previous comment. Your code cannot distinguish between «nothing selected» and «first item selected»

Добрый день.
Блин простейшая задача, но не могу найти ответ.
Случайно столкнулся с тем что:
Имеется визуальная форма с листбокс и одной кнопкой,

Код
Option Explicit
Public Mesec As Integer
Public Ploho As Integer


Private Sub CommandButton1_Click()

Mesec = ListBox1.ListIndex
Me.Hide

End Sub

Private Sub UserForm_initialize()
   'Массив визуальной формы, окна выбора пользователем
    UserForm1.ListBox1.List = Array("Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь")

End Sub
 

Вылезла форма при запуске, все хорошо, выбираешь работает, но если нажать на закрытие формы, по автомату выберется месяц январь listindex = 0 будет хотя я читал на excelworld что если не выбрано значение должна быть -1. Думал прописать условие если Listindex = -1 then exit sub но такое не получилось.

Необходимо чтобы если пользователь нажал на закрытие визуальной формы, работа макроса прекратилась полностью


    • #1

    In Excel 2007 I need to determine when a multi-select listbox in a userform has no items selected. I have tired a number of different methods that I found online without success. Such as:

    If Me.ListRegion.ItemsSelected.Count = 0 Then

    «itemsSelected» gives «Method or data member not found»

    If Me.ListRegion.ListIndex = -1 Then

    When I debug the value for .listindex is always 0, if items are selected or not.

    I’m using the listbox to set pivotitems .visible true or false and because all the items can not be set to false I want to remove the pivotfield when no items are selected. If there is a better way to do this or a work around I’m all for it.

    • #2

    Re: Need to determine when no items are selected in a multi-select listbox on a userf

    Try

    If Me.ListBox1.ListIndex < 0 Then
    • #3

    Re: Need to determine when no items are selected in a multi-select listbox on a userf

    That one doesn’t seem to do the trick either. In debugging the value of .listindex is equal to 0 if zero or one item is selected and equal to 2 if two items and so on. I read somewhere that I could do it with Me.ListRegion.SelectedItem(Index), but I don’t know how to.

    In case I’ve been messing something up with my code. Here is the code I’ve been using with this list box…

    Private Sub ListBoxRegion()
    
    
        Dim Item As Range
        Dim ws As Worksheet
        Set ws = ThisWorkbook.Worksheets("Menu")
        
        'Populate ListBox "Select Region" with data from named range "ST"
        For Each Item In ws.Range("ST")
            With Me.ListRegion
                .AddItem Item.Value
            End With
        Next Item
    
    
    End Sub
    
    
    Dim lbItem As Long
        Set pt = ThisWorkbook.Sheets("Pivot").PivotTables("PivotTable1")
        On Error Resume Next
    
    
        'Region
        Set pf = ThisWorkbook.Worksheets("Pivot").PivotTables("PivotTable1").PivotFields("ST")
        pt.PivotFields("ST").Orientation = xlPageField
        For lbItem = 0 To Me.ListRegion.ListCount - 1
            If Me.ListRegion.Selected(lbItem) = False Then
                pf.PivotItems(Me.ListRegion.List(lbItem)).Visible = False
            Else
                pf.PivotItems(Me.ListRegion.List(lbItem)).Visible = True
                 With Me.ListSTValue
                    .AddItem Me.ListRegion.List(lbItem)
                 End With
            End If
        Next lbItem
            
        If Me.ListRegion.ListIndex = -1 Then
            pt.PivotFields("ST").Orientation = xlHidden 'Removes PivotField if no items were selected
        End If

    Display More

    Thanks for the help!

    • #4

    Re: Determine when no items are selected in a multi-select listbox on a userform

    For i = 0 To ListBox1.ListCount - 1
            If ListBox1.Selected(i) Then j = j + 1
        Next i
    If j = 0 Then MsgBox " No items selected"
    • #5

    Re: Determine when no items are selected in a multi-select listbox on a userform

    Note: AAE’s code only works on a single item mode listbox. A multi select mode list box returns a 0 if no items selected and returns the largest item number selected if one or more items have been selected. If the first item only is selected it will return a 0

    • #6

    Re: Determine when no items are selected in a multi-select listbox on a userform

    Thank you that does the trick!

    If you don’t mind I’m a bit of a novice to VBA and have a couple of questions for about your solution.

    If ListRegion.Selected(i) Then

    You use an if statement, but I don’t see any sort of question ie: if A = x then…
    Is this the same code as:

    If ListRegion.Selected(i) = False Then

    I take it with a multi-listbox there isn’t a built in way or a way without looping through each item to see if no items are selected?

    The reason I’m still curious is that my userform has seven multi-listboxes and one of them has a lot of data(like 9000+ items). It’s the best way we could come up with to selected this field.

    Thanks again for the help!

    • #7

    Re: Determine when no items are selected in a multi-select listbox on a userform

    No. It defaultes to «True»
    I know of no other way to check if any item was selected.

    • #8

    Re: Determine when no items are selected in a multi-select listbox on a userform

    I made a mistake when typing, it should have read True.

    Thank you very much for all your help.

    • #9

    Re: Determine when no items are selected in a multi-select listbox on a userform


    Quote from Bill Rockenbach;543661

    For i = 0 To ListBox1.ListCount - 1
            If ListBox1.Selected(i) Then j = j + 1
        Next i
    If j = 0 Then MsgBox " No items selected"

    Above works but time consuming for long lists. More straight foward:

    On Error Resume Next
    x = ListBox1.ItemsSelected(0)  'Will throw error if no items selected.
    ErrNo = Err.Number
    On Error Goto 0 'Or your error handler.
    If ErrNo = 0 then 'One or more items selected.
    • #10

    Re: Determine when no items are selected in a multi-select listbox on a userform


    Quote from Ty0;761223

    Above works but time consuming for long lists. More straight foward:

    On Error Resume Next
    x = ListBox1.ItemsSelected(0)  'Will throw error if no items selected.
    ErrNo = Err.Number
    On Error Goto 0 'Or your error handler.
    If ErrNo = 0 then 'One or more items selected.

    I’m getting an error with «ItemsSelected». I have added the MS Office 15.0 Access database engine object Library in order to make things work without success.

    Can this code work in Excel ? Thanks!

    • #11

    Re: Determine when no items are selected in a multi-select listbox on a userform


    Quote from sb44;762864

    I’m getting an error with «ItemsSelected». I have added the MS Office 15.0 Access database engine object Library in order to make things work without success.

    Can this code work in Excel ? Thanks!

    ItemsSelected is not valid property recognized by Excel for ListBox, it’s only valid for Access. I tested setting a reference just like you to Access and it doesn’t work still, so I guess it cannot be used. There is no shortcut to avoid looping through each of the ListBox items, to determine whether an item in a multi-selection ListBox was selected or not.

    I also made a Google search on it just to make sure and no results whatsoever: «.ItemsSelected(0)» Excel -Access

    • #12

    It is possible to count the number of selections in a multi-selection ListBox. I use a listbox called lstFound on a userform in Excel 2016. In the properties of the lstFound change ‘MultiSelect’ to ‘2 — fmMultiSelectExtended’ . Write a vba code for lstFound_Change(). This code has to be written in the userform, not as a separate module. In the userform there is also a label lblSelected (at startup lblSelected.Caption = «No items selected». The caption is changed accordingly. Of course it is possible to use a MsgBox instead of a label on the userform.

    Private Sub lstFound_Change()
    Dim sel As Long, total As Long
    With Me.lstFound
        For sel = 0 To .ListCount - 1   'Check all items
            If .Selected(sel) = True Then total = total + 1
        Next
    End With
        If total > 0 Then
            lblSelected.Caption = total & IIf(total > 1, " items selected", " item selected")
        Else
            lblSelected.Caption = "No items selected"
        End If
    End Sub

    Display More

    • #13

    It is possible to count the number of selections in a multi-selection ListBox. I use a listbox called lstFound on a userform in Excel 2016. In the properties of the lstFound change ‘MultiSelect’ to ‘2 — fmMultiSelectExtended’ . Write a vba code for lstFound_Change(). This code has to be written in the userform, not as a separate module. In the userform there is also a label lblSelected (at startup lblSelected.Caption = «No items selected». The caption is changed accordingly. Of course it is possible to use a MsgBox instead of a label on the userform. Even with a list of 500 entries, it replies instantly.

    Private Sub lstFound_Change()
    Dim sel As Long, total As Long
    With Me.lstFound
        For sel = 0 To .ListCount - 1   'Check all items
            If .Selected(sel) = True Then total = total + 1
        Next
    End With
        If total > 0 Then
            lblSelected.Caption = total & IIf(total > 1, " items selected", " item selected")
        Else
            lblSelected.Caption = "No items selected"
        End If
    End Sub

    Display More

  • Home
  • Forum
  • VBA Code & Other Help
  • Excel Help
  • Solved: Test for Null in Listbox Value

  1. 12-13-2006, 08:23 AM


    #1

    Solved: Test for Null in Listbox Value

    How do you test for when a person has not selected any item in a listbox?

    I have a listbox on a userform with two command buttons, one for submit and one for cancel. I am trying to check for the situation when a user fails to select a listbox item, but presses the submit instead of the cancel button. I have tested the following ways and all fail:

    If userform1.listbox1.value = vbNull then
    .Error code?
    End if
    If userform1.listbox1.value = ?? or _
    userform1.listbox1.value = ? ? then
    ?error code?
    End if
    If isNull(userform1.listbox1.value) then
    ?error code?
    End if
    If isEmpty(userform1.listbox1.value) then
    ?error code?
    End if
    If isblank(userform1.listbox1.value) then
    ?error code?
    End if

    There must be a trick I do not know in my limited knowledge. Any help would be greatly appreciated.

    Lawson


  2. 12-13-2006, 08:32 AM


    #2

    you could use the on_click event of the listbox. Disable the ok button when form loads and enable it when clicked in listbox.

    Charlize


  3. 12-13-2006, 09:14 AM


    #3

    Charlize,

    Thanks for your quick response. I tried what you suggested and on click can occur even when you just click anywhere in the listbox — you do not have to click on a listed item. I am trying to make sure they have selected an item listed unless they select the cancel button.

    The little things like this will drive me crazy until I get an answer. I have been working on this for two days. Sometimes when you get into something like this you need to just stop, go away and come with a fresh approach.

    When I tried the following statement again it worked. I do not know what I did outside of I totally shut down Excel, took a long break and came back and it worked.

    xSelected = userform1.listbox1.value
    if isnull(xSelected) then
    'error
    End If

    Thanks for the help.

    Lawson


  4. 12-13-2006, 09:24 AM


    #4

    [vba]

    If Userform1.Listbox.ListIndex = -1 Then
    ‘…
    [/vba]

    Last edited by Bob Phillips; 12-13-2006 at 11:55 AM.



Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
  • BB code is On
  • Smilies are On
  • [IMG] code is On
  • [VIDEO] code is On
  • HTML code is Off

Forum Rules

Skip to content

Excel VBA UserForm Listbox

  • Excel VBA UserForm CheckBox

ListBox is one of the UserForm control. You can select and drag ListBox on the UserForm. This control is used to display list of items to a list. This is used on the UserForm. Please find more details about ListBox_Control in the following chapter. You can see how to load items to listbox_Control, how to move items from one listbox to another listbox, how to select items from a listbox_Control, etc..,

  • VBA ListBox_Control on the UserForm
  • Add Dynamic ListBox_Control on the UserForm Using VBA
  • Add Items to ListBox_Control Using VBA
  • Clear Items from the ListBox_Control Using VBA
  • Check if a ListBox Item is Selected or not Using VBA
  • VBA ListBox Default Values in Excel
  • Get the total count of ListBox Items
  • Move all Items from ListBox1 to ListBox2
  • Get Selected Items from ListBox1 to ListBox2
  • Make ListBox to Select Multiple Items
  • Populate ListBox from an Array
  • More Details About the ListBox_Control

VBA ListBox_Control on the UserForm

Please find more details about VBA ActiveX ListBox_Control and how we are adding it on the UserForm.

    1. Go To Developer Tab and then click Visual Basic from the Code or Press Alt+F11.
    2. Go To Insert Menu, Click UserForm. Please find the screenshot for the same.

Excel VBA UserForm CheckBox

    1. Drag Listbox_Control on the Userform from the Toolbox. Please find the screen shot for the same.

List Box Excel ActiveX Control _Im10

    1. Double Click on the UserForm, and select the Userform event as shown in the below screen shot.

Excel VBA ListBox ActiveX Control

    1. Now can see the following code in the module.
Private Sub UserForm_Initialize()

End Sub
    1. Now, add the following code to the in between procedure.

Code:

Private Sub UserForm_Initialize()
    ListBox1.AddItem "MBA"
    ListBox1.AddItem "MCA"
    ListBox1.AddItem "MSC"
    ListBox1.AddItem "MECS"
    ListBox1.AddItem "CA"
End Sub
    1. Now, Press ‘F5’ to run the code. You can see the following Output. It is shown in the following Screen Shot.

Excel VBA ListBox ActiveX Control1

Add dynamic ListBox_Control on the UserForm using VBA

Please find the following steps and example code, it will show you how to add dynamic list box control on the userform.

    1. Add command button on the userform from the toolbox.
    2. Right click on the command button, click properties
    3. Change the command button caption to ‘Create_Listbox’
    4. Double click on the command button
    5. Now, it shows following code.
Private Sub CommandButton1_Click()
 
End Sub
    1. Call the below procedure named ‘Add_Dynamic_Listbox’ and find the below procedure to run.
Private Sub CommandButton1_Click()
    Call Add_Dynamic_Listbox
End Sub

Procedure to call in the Command Button:

Sub Add_Dynamic_Listbox()
      'Add Dynamic List Box and assign it to object 'LstBx'
    Set LstBx = UserForm3.Controls.Add("Forms.ListBox.1")
        
    'List Box Position
    LstBx.Left = 20
    LstBx.Top = 10
End Sub
    1. Now, click F5 to run the macro, click ‘Create_Listbox’ button to see the result.
    2. You can see the created dynamic checkbox in the following screen shot.

output:

Excel VBA ListBox ActiveX Control2

Add Items to ListBox_Control using VBA

Please find the following code, it will show you how to add list items to list box.

Private Sub Insert _Items _To_LstBox ()
    ListBox1.AddItem "Item 1"
    ListBox1.AddItem "Item 2"
    ListBox1.AddItem "Item 3"
    ListBox1.AddItem "Item 4"
    ListBox1.AddItem "Item 5"
End Sub

In the above code ListBox1 is the name of the listbox_Control. Where additem is the property of listbox.

Clear Items from the ListBox using VBA

Please find the following code, it will show you how to clear the list box items. The below code clears the list box1 items on the UserForm1.

Sub Clr_LstBx()
    UserForm3.ListBox1.Clear
End Sub

Check if a List box item is selected or not using VBA

Please find the below code to know how to check if a List box is selected or not using VBA. In the below example (0) is the index number.

Sub Chk_Item_SelectOrNot()
    If UserForm3.ListBox1.Selected(0) = True Then
        MsgBox "First item has selected in the ListBox."
    Else
        MsgBox "First item has not selected in the ListBox."
    End If
End Sub

VBA ListBox Default Values in Excel

Here is the VBA list box default values in Excel. After adding items to list box by using any of the below code you can define the default value.

Code 1:

The below code is useful to select blank option in list box. Where ‘-1’ is the index number.

Sub LstBx_Dflt_Val_Ex1()
     UserForm3.ListBox1.ListIndex = -1
End Sub

Code 2:

The below code is useful to select first item in the list box from the available list. . Where ‘0’ is the index number.

Sub LstBx_Dflt_Val_Ex2()
     UserForm3.ListBox1.ListIndex = 0
End Sub

Code 3:

The below code is useful to select second item in the list box from the available list. Where ‘1’ is the index number.

Sub LstBx_Dflt_Val_Ex3()
     UserForm3.ListBox1.ListIndex = 1
End Sub

Code 4:

The below code is useful to select the last item in the list box from the available list. Where ‘1’ is the index number.

Sub LstBx_Dflt_Val_Ex4()
     UserForm3.ListBox1.ListIndex = UserForm3.ListBox1.Count - 1
End Sub

Get the total count of Listbox Items

Here is the following example, it will show you how to get the total count of items in a list box. In the below example ListBox1 is the list box name and ListCount is the property of list box.

Sub Get_Ttl_Cnt()
    MsgBox "Total Items in a ListBox is " & UserForm3.ListBox1.ListCount
End Sub

Output:

Excel VBA ListBox ActiveX Control3

Move all Items from ListBox1 to ListBox2

Please find the below example code, it shows how to Move all Items from ListBox1 to ListBox2. In the below example ‘ListBox1 and ListBox2’ are the list box names.

Sub Move_ListBox_Items()
    'Variable declaration
    Dim iCnt As Integer
    
    'Moving ListBox1 Items to ListBox2
    For iCnt = 0 To ListBox1.ListCount - 1
        ListBox2.AddItem ListBox1.List(iCnt)
    Next iCnt
    
    'Then Clear the ListBox1 Items
    ListBox1.Clear
End Sub

Get Selected Items from ListBox1 to ListBox2

Please find the below example code, it shows how to Get Selected Items from ListBox1 to ListBox2. In the below example ‘ListBox1 and ListBox2’ are the list box names.

Sub Get_ListBox_Selected_Items()
    'Variable declaration
    Dim iCnt As Integer
    
    'Get Selcted Items from ListBox1 to ListBox2
    For iCnt = 0 To ListBox1.ListCount - 1
        'Check ListBox Item has selcted or not
        If ListBox1.Selected(iCnt) = True Then
            ListBox2.AddItem ListBox1.List(iCnt)
        End If
    Next
End Sub

Make ListBox to Select Multiple Items

Please find the below example code, it shows how to make ListBox to Select Multiple Items. In the below example ‘ListBox1’ is the list box name.

Sub Multiple_ListBox_Selection()
    ListBox1.MultiSelect = fmMultiSelectMulti
End Sub

Populate ListBox from an Array

Please find the below example code, it shows how to populate ListBox from an Array. In the below example ‘arrList’ is the array name. And ‘ListBox1’ is the list box name.

Sub Load_ListBox_From_Array()
    'Load Items to an Array
    arrList = Array("Item 1", "Item 2", "Item 3")
    
    'Load an Array Items to ListBox
    ListBox1.List = arrList
End Sub

More Details About the ListBox_Control

VBA ListBox Excel Macros Examples Codes Adding Clearing Multiple Items

Please find the following link for more details about VBA ListBox Excel Macros Examples and Codes Adding and Clearing Multiple Items.

Read More …

VBA to Remove Duplicates in ListBox Excel

Please find more details about Remove Duplicates in ListBox in Excel VBA.

Read More …

Excel VBA FAQs: Frequently Asked Questions

Please find the most frequently asked questions and answers for your reference. These are explained more detailed way with examples.
Read More …

Effortlessly Manage Your Projects and Resources
120+ Professional Project Management Templates!

A Powerful & Multi-purpose Templates for project management. Now seamlessly manage your projects, tasks, meetings, presentations, teams, customers, stakeholders and time. This page describes all the amazing new features and options that come with our premium templates.

Save Up to 85% LIMITED TIME OFFER
Excel VBA Project Management Templates
All-in-One Pack
120+ Project Management Templates
Essential Pack
50+ Project Management Templates

Excel Pack
50+ Excel PM Templates

PowerPoint Pack
50+ Excel PM Templates

MS Word Pack
25+ Word PM Templates

Ultimate Project Management Template

Ultimate Resource Management Template

Project Portfolio Management Templates

VBA Reference

Effortlessly
Manage Your Projects

120+ Project Management Templates

Seamlessly manage your projects with our powerful & multi-purpose templates for project management.

120+ PM Templates Includes:
By PNRaoLast Updated: March 2, 2023

Effectively Manage Your
Projects and  Resources

With Our Professional and Premium Project Management Templates!

ANALYSISTABS.COM provides free and premium project management tools, templates and dashboards for effectively managing the projects and analyzing the data.

We’re a crew of professionals expertise in Excel VBA, Business Analysis, Project Management. We’re Sharing our map to Project success with innovative tools, templates, tutorials and tips.

Project Management
Excel VBA

Download Free Excel 2007, 2010, 2013 Add-in for Creating Innovative Dashboards, Tools for Data Mining, Analysis, Visualization. Learn VBA for MS Excel, Word, PowerPoint, Access, Outlook to develop applications for retail, insurance, banking, finance, telecom, healthcare domains.

Analysistabs Logo

Page load link

Go to Top

Я пытаюсь выяснить, как лучше всего использовать Excel ListBox с несколькими вариантами выбора и имеют простой код VBA для фильтрации нескольких листов на основе того, что выбрано в ListBox.

Код, который у меня есть сейчас, ниже. На данный момент он делает именно то, что мне нужно — проверяет, есть ли какой-либо фильтр на листах, очищает его, если это так, а затем отфильтровывает выбранные значения. Но что мне нужно сделать, это то, что значение не выбрано вообще, оно должно очистить фильтры на 4 листах и ​​выйти из sub.

Дело в том, что я получаю ошибку «недопустимая процедура», если пытаюсь запустить ее, когда ничего не выбрано. Я пытался добавить заявление Else и еще один, если проверить If .Listindex = -1, но оба варианта дали одинаковую ошибку. Поскольку это должен быть список с множественным выбором, я обнаружил, что он также должен выполнять цикл при проверке, если ничего не выбрано, но, опять же, возникла та же ошибка.

Как я могу улучшить этот код и добавить необходимые функции?

Sub filter1()

Dim MyArray() As String
Dim Cnt As Long
Dim r As Long

Cnt = 0
With Me.ListBox1
    If .ListIndex <> -1 Then
        For r = 0 To .ListCount - 1
            If .Selected(r) Then
                Cnt = Cnt + 1
                ReDim Preserve MyArray(1 To Cnt)
                MyArray(Cnt) = .List(r)
            End If
        Next r
    End If
End With

With Sheet1
    If .FilterMode Then .ShowAllData
    .Range("A2:Y1037").AutoFilter field:=2, Criteria1:=MyArray, Operator:=xlFilterValues
End With

With Sheet3
    If .FilterMode Then .ShowAllData
    .Range("A2:AB1037").AutoFilter field:=2, Criteria1:=MyArray, Operator:=xlFilterValues
End With

With Sheet4
    If .FilterMode Then .ShowAllData
    .Range("A2:Z1037").AutoFilter field:=2, Criteria1:=MyArray, Operator:=xlFilterValues
End With

With Sheet5
    If .FilterMode Then .ShowAllData
    .Range("A2:Z1037").AutoFilter field:=2, Criteria1:=MyArray, Operator:=xlFilterValues
End With

End Sub

The VBA ListBox is a very useful control. If you are creating any kind of UserForm application you will most likely use it.

In this post, I’m going to show you everything you need to know about the VBA ListBox so you can avoid the common pitfalls and get up and running quickly and easily.

VBA ListBox multi

What is the VBA ListBox used for?

The ListBox is used to display a list of items to the user so that the user can then select one or more. The ListBox can have multiple columns and so it is useful for tasks like displaying records.

VBA ListBox versus the VBA ComboBox

The ListBox is very similar to the ComboBox which also allows the user to select an item from a list of items. The main differences are:

  1. The Listbox allows multiple selections. The Combobox only allows one selection.
  2. Items in the ListBox are always visible. The Combobox items are only visible when you click on the “down” icon.
  3. The ComboBox has the ability to filter the contents when you type.

The VBA ListBox Properties Quick Guide

Function Operation Example
AddItem Add an item listbox.AddItem «Spain»
Clear Remove all Items listbox.Clear
ColumnCount Set the number of visible columns ComboBox1.ColumnCount = 2
ColumnHeads Make the column row visible ComboBox1.ColumnHeads = True
List Range to Listbox
ListBox to Range
Listbox.List = Range(«A1:A4»).Value
Range(«A1:A4»).Value = Listbox.List
List Update a column value Listbox.List(1,2) = «New value»
ListCount Get the number of items cnt = listbox.ListCount
ListIndex Get/set selected item Idx = listbox.ListIndex
combo.ListIndex = 0
RemoveItem Remove an item listbox.Remove 1
RowSource Add a range of values from a worksheet ComboBox1.RowSource = Sheet1.Range(«A2:B3»).Address
Value Get the value of selected Item Dim sCountry As String
sCountry = listbox.Value

How to Add Items to the ListBox

There are 3 ways to add items to the VBA Listbox:

  1. One at a time using the AddItem property.
  2. Adding an array/range using the List property.
  3. Adding a Range using the RowSource property.

The List and RowSource properties are the most commonly used. The table below provides a quick comparison of these properties:

Task RowSource List
Column Headers Yes No
Update values in ListBox No Yes
Add new items No Yes
Data type Range Array(including Range.Value)
If source data changes Listbox is automatically updated. ListBox is not updated.

VBA ListBox List Property

The List property allows you to add to contents of an array to a ListBox. As Range.Value is an array you can copy the contents of any range to the Listbox.

Here are some examples of using the List property:

' Add the contents of an array
ListBox1.List = Array("Apple", "Orange", "Banana")

' Add the contents of a Range
ListBox1.List = Range("A1:E5").Value

You can also use the List property to write from the ListBox to an array or range:

Range("A1:B3").Value = ListBox1.List

Important Note: If there is only one item in a range then VBA doesn’t covert it to an array. Instead, it converts the range to a string/double/date etc.

Sheet1.Range("A1:A2").Value ' Array
Sheet1.Range("A1").Value ' Single value variable

In this case, you need to use AddItem to add the value to the ListBox:

 If myRange.Count = 1 Then
    ListBox1.AddItem myRange
 Else
    ListBox1.List = myRange.Value
 End If

The List Property and Column Headers

The ListBox only displays column headers if you use RowSource. Otherwise, they are not available. The best way to add column headers(and it’s not a great way) is to add Labels above the ListBox columns. One advantage is that you can use the click event of the Label if you want to implement something like sorting.

Updating Items using the List Property

You can update individual items in the ListBox using the List Property.

Imagine we have a ListBox with data like this:

If we want to change Nelson in row 3, column 2 we do it like this:

ListBox1.List(2, 1) = "SMITH"

The result we get is:

The List property rows and columns are zero-based so this means row 1 is 0, row 2 is 1, row 3 is 2 and so on:

VBA ListBox RowSource

The RowSource property allows us to add a range to the ListBox. This is different from the List Property in that the Range is linked to the ListBox. If data in the Range changes then the data in the ListBox will update automatically.

When we use RowSource the data in the ListBox is read-only. We can change the RowSource range but we cannot change the values in the ListBox.

How to use RowSource

We add the RowSource range as a string like this:

 ListBox1.RowSource = "Sheet1!A1:A5"

If you don’t specify the sheet the VBA will use the active sheet

 ListBox1.RowSource = "A1:A5"

If you are using the Address of a range object with RowSource then it is important to use the External parameter. This will ensure that RowSource will read from the  sheet of the range rather than the active sheet:

 ' Get the range
 Dim rg As Range
 Set rg = Sheet1.Range("A1:A5")

 ' Address will be $A$1:$A$5 which will use the active sheet
 ListBox1.RowSource = rg.Address
 Debug.Print ListBox1.RowSource

 ' Address will be [Book2]Sheet1!$A$1:$A$5 which will use Sheet1
 ListBox1.RowSource = rg.Address(External:=True)
 Debug.Print ListBox1.RowSource

RowSource Column Headers

Column headers are automatically added to the ListBox when you use the RowSource property. The ColumnHeads property must be set to True or the headers will not appear. You can set this property in the code or in the properties window of the ListBox.

  ListBox1.ColumnHeads = True

The column headers are taken from the row above the range used for the RowSource.  For example, if your range is A2 to C5 then the column header will use the range A1 to C1:

Here is an example: We want to add the data below to our ListBox and we want A1 to C1 to be the header.

We set the RowSource property to A2:C5 and set the ColumnHeads property to true:

With ListBox1
    .RowSource = "sheet1!A2:C5"
    .ColumnHeads = True
    .ColumnWidths = "80;80;80"
End With

The result will look like this:

VBA ListBox AddItem

It is very rare that you would use the AddItem property to fill the ListBox. List and RowSource are much more efficient. AddItem is normally used when the Listbox already has items and you want to add a new item.

The AddItem property is simple to use. You provide the item you want to add as a parameter. The ListBox will automatically add it as the last item:

With ListBox
    .AddItem "Apple"
    .AddItem "Orange"
End With

If you want to Insert the item at a certain position you can use the second parameter. Keep in mind that this is a zero-based position, so if you want the item in position one then the value is 0, position 2 the value is 1, and so on.

With ListBox1
    .AddItem "Apple"
    .AddItem "Orange"
    
    ' Add "Banana" to position 1(Index 0)
    .AddItem "Banana", 0
End With

The order will be:
Banana
Apple
Orange

If you want to add multiple columns with AddItem then you need to use the List property after you use AddItem:

 With listboxFruit
    .List = myRange.Value
    .AddItem "Banana"
    
    ' Add to the second column of 'Banana' row
    .List(2, 1) = "$2.99"
 End With

One reason for using AddItem  is if you are adding from data that isn’t sequential so you cannot use the List or RowSource properties:

 Dim cell As Range
 ' Fill items with first letter is A
 For Each cell In Sheet1.Range("A1:A50")
    If Left(cell.Value, 1) = "A" Then
        comboBoxFruit.AddItem cell.Value
    End If
 Next

Important Note: If you fill a ListBox with RowSource then you cannot use AddItem to add a new item. If you try you will get a “Runtime Error 70 – Permission Denied”.

VBA ListBox Selected Items

If only one item is selected then you can use ListIndex to get the selected row. Remember that it is zero-based so row 1 in the ListBox is at ListIndex 0, row 2 at ListIndex 1 and so on.

   MsgBox "The selected item is " & ListBox1.ListIndex

If the ListBox has multiple columns then you can use the ListIndex and List properties together to return a value in the selected row:

  ' Display the value from the second column of the selected row
  MsgBox ListBox1.List(ListBox1.ListIndex, 2)

If multiple items are selected then you can use the GetSelectedRows function which returns a collection of selected rows:

 Sub Example()
    
    ' Store the row numbers of selected items to a collection
    Dim selectedRows As Collection
    Set selectedRows = GetSelectedRows()
    
    ' Print the selected rows numbers to the Immediate Window
    Dim row As Long
    For Each row In selectedRows
        ' Print to the Immediate Window Ctrl + G
        Debug.Print row
    Next row

 End Sub

 ' Returns a collection of all the selected items
 Function GetSelectedRows() As Collection

    ' Create the collection
    Dim coll As New Collection

    ' Read through each item in the listbox
    Dim i As Long
    For i = 0 To listboxFruit.ListCount - 1
    
        ' Check if item at position i is selected
        If listboxFruit.Selected(i) Then
            coll.Add i
        End If
    Next i

    Set GetSelectedRows = coll

End Function

Reading Data from the VBA Listbox

To read data from the ListBox we can use the ListBox.Value property. This only works when the ListBox is set to only select one item i.e. MultiSelect is set to frmMultiSelectSingle(see the section VBA ListBox MultiSelect below for more about this).

Single selection only  with one column

When only one item is selected we can use the Value property to get the currently selected item:

 Dim fruit As String
 fruit = ListBox1.Value

Keep in mind that if there are multiple columns, Value will only return the value in the first column.

Single selection only with multiple columns

If the ListBox has Multiple columns you can use the Value property to get the value in the first column. You need to read through the List property to get the values in the other column(s). The List property is essentially an array so you can treat it like one.

In the example below we read through the columns of row 1(the index of row 1 is 0):

 With ListBox1
 
     For j = LBound(.List, 2) To UBound(.List, 2)
         ' Print the columns of the first row to the Immediate Window
         Debug.Print .List(0, j)
     Next j
     
 End With

Normally you want to print the values in the selected row. You can use the ListIndex property to get the selected item(Note that ListIndex returns the last selected items so it won’t work where there are multiple items selected):

 ' ExcelMacroMastery.com
 Sub ReadValuesFromSelectedRow()

    ' Write contents of the row to the Immediate Window(Ctrl G)
    With ListBox1 
        For j = LBound(.List, 2) To UBound(.List, 2) 
            ' Print the columns of the selected row to the Immediate Window 
            Debug.Print .List(.ListIndex, j) Next j 
    End With
 End Sub
 

Multiple selections

If the ListBox has multiple selections and you want to get all the data from each then you can use the GetSelectedRows() sub from the section VBA ListBox Selected Items. This will get a collection of all selected rows. You can use this to print the data from the selected rows:

Sub PrintMultiSelectedRows()

    ' Get all the selected rows
    Dim selectedRows As Collection
    Set selectedRows = GetSelectedRows(Me.ListBox1)

    Dim i As Long, j As Long, currentRow As Long
    ' Read through the selected rows
    For i = 1 To selectedRows.Count
        With ListBox1
            
            ' Get the current row
            currentRow = selectedRows(i)
            
            ' Print row header
            Debug.Print vbNewLine & "Row : " & currentRow
            
            ' Read items in the current row
            For j = LBound(.List, 2) To UBound(ListBox1.List, 2)
                ' Print the columns of the first row to the Immediate Window
                Debug.Print .List(currentRow, j)
            Next j
        
        End With
    Next i
    
End Sub

Function GetSelectedRows(currentListbox As MSForms.ListBox) As Collection

    ' Create the collection
    Dim coll As New Collection

    ' Read through each item in the listbox
    Dim i As Long
    For i = 0 To currentListbox.ListCount - 1
    
        ' Check if item at position i is selected
        If currentListbox.Selected(i) Then
            coll.Add i
        End If
    Next i

    Set GetSelectedRows = coll

End Function

VBA ListBox MultiSelect

We can use the MultiSelect property of the ListBox to allow the user to select either a single item or multiple items:

listbox multiselect

There are 3 selections:

  • 0 = frmMultiSelectSingle –  [Default]Multiple selection isn’t allowed.
  • 1 = frmMultiSelectMulti – Multiple items are selected or deselected by choosing them with the mouse or by pressing the Spacebar.
  • 2 = frmMultiSelectExtended – Multiple items are selected by holding down Shift and choosing them with the mouse, or by holding down Shift and pressing an arrow key to extend the selection from the previously selected item to the current item. You can also select items by dragging with the mouse. Holding down Ctrl and choosing an item selects or deselects that item.

VBA ListBox Columns

You can have multiple columns in a ListBox. For example, you can load a Range or two-dimensional array to a ListBox using List or RowSource.

Often when you load data with multiple columns only one column appears. This can be very confusing when you are using the Listbox. To get the columns to appear you have to set the ColumnCount property to the number of Columns.

You should also make sure that the ColumnWidths property is correct or one of the columns may not appear.

You can do it like this:

With listboxFruit
    .RowSource = "Sheet1!A2:B4"
    .ColumnCount = 2
    .ColumnWidths = "100,100"
End With

In a real-world application, you could set the RowSource and ColumnCount properties like this:

With listboxFruit
    .RowSource = myRange.Address(External:=True)
    .ColumnCount = myRange.Columns.Count
End With

See the AddItem section for how to add data to the other columns when you are using the AddItem property.

VBA ListBox Column Headers

Column Headers are another confusing element of the ListBox. If you use the RowSource property to add data to the ListBox then the line above the Range will be automatically used as the header.

For the Column headers to appear the ColumnHeads property must be set to true. You can do this in the properties window of the ListBox or in the code list this:

ListBox1.ColumnHeads = True

If you use the List or AddItem property to fill the ListBox then the column headers are not available. The best solution, albeit a frustrating one, is to use labels above the ListBox. I know it sounds crazy but that unfortunately is the reality. The one advantage is that you can use the Label click event which is useful if you plan to sort the data by a column.

Creating a ListBox Dynamically

Controls are normally created at design time but you can also create them dynamically at run time:

    Dim myListbox As MSForms.ListBox
    Set myListbox = Controls.Add("Forms.ListBox.1")

If you want to add an event to a dynamic control you can do it like this:

  1. First of all create a Class like this:
    Public WithEvents myListBox As MSForms.ListBox
    
    Private Sub myListBox_Change()
      MsgBox "Selection changed"
    End Sub
    
  2. Name the class clsListBoxEvents.  Create a variable of this class object in the UserForm like this:
    Private listBoxEvents As New clsListBoxEvents
    
  3.   Attach the events to the ListBox:
    Sub CreateDynamicListBox()
    
        ' Create the ListBox
        Dim newListBox As MSForms.ListBox
        Set newListBox = Controls.Add("Forms.ListBox.1")
        
        ' Add some items
        newListBox.List = Array("Apple", "Orange", "Pear")
       
        ' Connect the ListBox to the ListBox events class
        Set listBoxEvents.myListBox = newListBox
    
    End Sub
    

Note that you can attach events to any ListBox. It doesn’t have to be created dynamically to do this.

Loop through ListBoxes

If you want to loop through all the ListBoxes on a UserForm you can do it like this:

 Dim ctrl As Variant
 For Each ctrl In Me.Controls
    If TypeName(ctrl) = "ListBox" Then
        Debug.Print ctrl.Name
    End If
 Next ctrl

YouTube Video

Check out this video where I use the ListBox. The source code for the video is available from here

 

What’s Next?

Free VBA Tutorial If you are new to VBA or you want to sharpen your existing VBA skills then why not try out this Free VBA Tutorial.

Related Training: Get full access to the Excel VBA training webinars and all the tutorials.

(NOTE: Planning to build or manage a VBA Application? Learn how to build 10 Excel VBA applications from scratch.)

Понравилась статья? Поделить с друзьями:
  • Excel vba if in between
  • Excel vba if iif
  • Excel vba if find is error
  • Excel vba if file exist
  • Excel vba if condition or and