Listbox vba excel колонки

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

Элемент управления ListBox на пользовательской форме

UserForm.ListBox – это элемент управления пользовательской формы, предназначенный для передачи в код VBA информации, выбранной пользователем из одностолбцового или многостолбцового списка.

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

Использование полос прокрутки уменьшает преимущество ListBox перед элементом управления ComboBox, которое заключается в том, что при открытии формы все позиции для выбора на виду без дополнительных действий со стороны пользователя. При выборе информации из большого списка удобнее использовать ComboBox.

Элемент управления ListBox позволяет выбрать несколько позиций из списка, но эта возможность не имеет практического смысла. Ввести информацию в ListBox с помощью клавиатуры или вставить из буфера обмена невозможно.

Свойства списка

Свойство Описание
ColumnCount Указывает количество столбцов в списке. Значение по умолчанию = 1.
ColumnHeads Добавляет строку заголовков в ListBox. True – заголовки столбцов включены, False – заголовки столбцов выключены. Значение по умолчанию = False.
ColumnWidths Ширина столбцов. Значения для нескольких столбцов указываются в одну строку через точку с запятой (;).
ControlSource Ссылка на ячейку для ее привязки к элементу управления ListBox.
ControlTipText Текст всплывающей подсказки при наведении курсора на ListBox.
Enabled Возможность выбора элементов списка. True – выбор включен, False – выключен*. Значение по умолчанию = True.
Font Шрифт, начертание и размер текста в списке.
Height Высота элемента управления ListBox.
Left Расстояние от левого края внутренней границы пользовательской формы до левого края элемента управления ListBox.
List Позволяет заполнить список данными из одномерного или двухмерного массива, а также обращаться к отдельным элементам списка по индексам для записи и чтения.
ListIndex Номер выбранной пользователем строки. Нумерация начинается с нуля. Если ничего не выбрано, ListIndex = -1.
Locked Запрет возможности выбора элементов списка. True – выбор запрещен**, False – выбор разрешен. Значение по умолчанию = False.
MultiSelect*** Определяет возможность однострочного или многострочного выбора. 0 (fmMultiSelectSingle) – однострочный выбор, 1 (fmMultiSelectMulti) и 2 (fmMultiSelectExtended) – многострочный выбор.
RowSource Источник строк для элемента управления ListBox (адрес диапазона на рабочем листе Excel).
TabIndex Целое число, определяющее позицию элемента управления в очереди на получение фокуса при табуляции. Отсчет начинается с 0.
Text Текстовое содержимое выбранной строки списка (из первого столбца при ColumnCount > 1). Тип данных String, значение по умолчанию = пустая строка.
TextAlign Выравнивание текста: 1 (fmTextAlignLeft) – по левому краю, 2 (fmTextAlignCenter) – по центру, 3 (fmTextAlignRight) – по правому краю.
Top Расстояние от верхнего края внутренней границы пользовательской формы до верхнего края элемента управления ListBox.
Value Значение выбранной строки списка (из первого столбца при ColumnCount > 1). Value – свойство списка по умолчанию. Тип данных Variant, значение по умолчанию = Null.
Visible Видимость списка. True – ListBox отображается на пользовательской форме, False – ListBox скрыт.
Width Ширина элемента управления.

* При Enabled в значении False возможен только вывод информации в список для просмотра.
** Для элемента управления ListBox действие свойства Locked в значении True аналогично действию свойства Enabled в значении False.
*** Если включен многострочный выбор, свойства Text и Value всегда возвращают значения по умолчанию (пустая строка и Null).

В таблице перечислены только основные, часто используемые свойства списка. Еще больше доступных свойств отображено в окне Properties элемента управления ListBox, а все методы, события и свойства – в окне Object Browser.

Вызывается Object Browser нажатием клавиши «F2». Слева выберите объект ListBox, а справа смотрите его методы, события и свойства.

Свойства BackColor, BorderColor, BorderStyle отвечают за внешнее оформление списка и его границ. Попробуйте выбирать доступные значения этих свойств в окне Properties, наблюдая за изменениями внешнего вида элемента управления ListBox на проекте пользовательской формы.

Способы заполнения ListBox

Используйте метод AddItem для загрузки элементов в список по одному:

With UserForm1.ListBox1

  .AddItem «Значение 1»

  .AddItem «Значение 2»

  .AddItem «Значение 3»

End With

Используйте свойство List, чтобы скопировать одномерный массив значений в элемент управления ListBox.

UserForm1.ListBox1.List = Array(«Текст 1», _

«Текст 2», «Текст 3», «Текст 4», «Текст 5»)

Вместо функции Array можно использовать переменные одномерных и двухмерных массивов. При загрузке значений из двухмерного массива, требуется предварительно указать количество столбцов в списке.

Используйте свойство RowSource, чтобы загрузить в список значения из диапазона ячеек рабочего листа:

UserForm1.ListBox1.RowSource = «Лист1!A1:A6»

При загрузке данных из диапазона, содержащего более одного столбца, требуется предварительно указать количество столбцов в списке:

With UserForm1.ListBox1

  ‘Указываем количество столбцов

  .ColumnCount = 5

  .RowSource = «‘Лист со списком’!A1:E10»

End With

В качестве имени листа используется имя ярлыка. Если имя листа содержит пробелы, оно заключается в одинарные кавычки.

Подробнее о заполнении элемента управления ListBox вы можете ознакомиться в отдельной статье с наглядными примерами.

Привязка списка к ячейке

Для привязки списка к ячейке на рабочем листе используется свойство ControlSource. Суть привязки заключается в том, что при выборе строки в элементе управления, значение свойства Value копируется в привязанную ячейку.

Если привязанная к списку ячейка содержит значение одной из строк элемента управления ListBox, то при запуске пользовательской формы список откроется с выделенной строкой, содержащей это значение. Если привязанная ячейка при загрузке формы пустая, то список откроется без выделения какой-либо строки.

В случае, когда при открытии формы в привязанной к списку ячейке содержится значение, которого нет ни в одной из строк элемента управления ListBox, будет сгенерирована ошибка.

Привязать ячейку к списку можно, указав адрес ячейки в поле свойства ControlSource в окне Properties элемента управления ListBox. Или присвоить адрес ячейки свойству ControlSource в коде VBA Excel:

UserForm1.ListBox1.ControlSource = «Лист1!A2»

Теперь значение выбранной строки в списке автоматически копируется в ячейку «A2» на листе «Лист1»:

Элемент управления ListBox с привязанной ячейкой

В окне Properties адрес указывается без двойных кавычек. Если имя листа содержит пробелы, оно заключается в одинарные кавычки.

Извлечение информации из списка

Первоначально элемент управления ListBox открывается со строками, ни одна из которых не выбрана. При выборе (выделении) строки, ее значение записывается в свойства Value и Text.

Из этих свойств мы с помощью кода VBA Excel извлекаем информацию, выбранную в списке пользователем:

Dim myVar as Variant, myTxt As String

myVar = UserForm1.ListBox1.Value

‘или

myTxt = UserForm1.ListBox1.Text

Вторую строку кода можно записать myVar = UserForm1.ListBox1, так как Value является свойством списка по умолчанию.

Если ни одна позиция в списке не выбрана, свойство Value возвращает значение Null, а свойство Text – пустую строку. Если выбрана строка в многостолбцовом списке, в свойства Value и Text будет записана информация из первого столбца.

Что делать, если понадобятся данные из других столбцов многостолбцового списка, кроме первого?

Для получения данных из любого столбца элемента управления ListBox используется свойство List, а для определения выбранной пользователем строки – ListIndex.

Для тестирования приведенного ниже кода скопируйте таблицу и вставьте ее в диапазон «A1:D4» на листе с ярлыком «Лист1»:

Звери Лев Тапир Вивера
Птицы Грач Сорока Филин
Рыбы Карась Налим Парусник
Насекомые Оса Жук Муравей

Создайте в редакторе VBA Excel пользовательскую форму и добавьте на нее список с именем ListBox1. Откройте модуль формы и вставьте в него следующие процедуры:

Private Sub UserForm_Initialize()

With Me.ListBox1

  ‘Указываем, что у нас 4 столбца

  .ColumnCount = 4

  ‘Задаем размеры столбцов

  .ColumnWidths = «50;50;50;50»

  ‘Импортируем данные

  .RowSource = «Лист1!A1:D4»

  ‘Привязываем список к ячейке «F1»

  .ControlSource = «F1»

End With

End Sub

Private Sub UserForm_Click()

MsgBox Me.ListBox1.List(Me.ListBox1.ListIndex, 2)

End Sub

В процедуре UserForm_Initialize() присваиваем значения некоторым свойствам элемента управления ListBox1 перед открытием пользовательской формы. Процедура UserForm_Click() при однократном клике по форме выводит в MsgBox значение из третьего столбца выделенной пользователем строки.

Результат извлечения данных из многостолбцового элемента управления ListBox

Теперь при выборе строки в списке, значение свойства Value будет записываться в ячейку «F1», а при клике по форме функция MsgBox выведет значение третьего столбца выделенной строки.

Обратите внимание, что при первом запуске формы, когда ячейка «F1» пуста и ни одна строка в ListBox не выбрана, клик по форме приведет к ошибке. Это произойдет из-за того, что свойство ListIndex возвратит значение -1, а это недопустимый номер строки для свойства List.

Если для списка разрешен многострочный выбор (MultiSelect = fmMultiSelectMulti или MultiSelect = fmMultiSelectExtended), тогда, независимо от количества выбранных строк, свойство Value будет возвращать значение Null, а свойство Text – пустую строку. Свойство ListIndex будет возвращать номер строки, которую кликнули последней, независимо от того, что это было – выбор или отмена выбора.

Иногда перед загрузкой в ListBox требуется отобрать уникальные элементы из имеющегося списка. Смотрите, как это сделать с помощью объектов Collection и Dictionary.

1014 / 118 / 2

Регистрация: 26.08.2011

Сообщений: 1,113

Записей в блоге: 2

1

28.03.2012, 12:05. Показов 35421. Ответов 12


Студворк — интернет-сервис помощи студентам

Есть ListBox с 4 столбцами (ColumnCount = 4)
Есть 4 массива данных: элементу 1 первого массива соответствует элемент 1 второго, третьего и четвертого массивов. AddItem в ListBox нужно делать так, чтобы соответствующие элементы располагались в ListBox в строчку.
Еще один момент: возможно ли в верхней строке листбокса организовать заголовки столбцов? или поместить перый элемент в поля заголовков



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

28.03.2012, 12:05

12

Gibboustooth

735 / 203 / 11

Регистрация: 23.06.2011

Сообщений: 440

28.03.2012, 12:29

2

Цитата
Сообщение от AndreA SN
Посмотреть сообщение

Есть 4 массива данных: элементу 1 первого массива соответствует элемент 1 второго, третьего и четвертого массивов. AddItem в ListBox нужно делать так, чтобы соответствующие элементы располагались в ListBox в строчку.

Visual Basic
1
2
3
4
5
6
7
8
9
    With UserForm1.ListBox1
        For i = 0 To UBound(Array1)
            .AddItem
            .Column(0, i) = Array1(i)
            .Column(1, i) = Array2(i)
            .Column(2, i) = Array3(i)
            .Column(3, i) = Array4(i)
        Next i
    End With

Цитата
Сообщение от AndreA SN
Посмотреть сообщение

Еще один момент: возможно ли в верхней строке листбокса организовать заголовки столбцов? или поместить перый элемент в поля заголовков

Насколько я изучал этот вопрос — нет. Я использую в качестве заголовков обычные TextBox-ы.



3



Апострофф

Заблокирован

28.03.2012, 12:32

3

Visual Basic
1
2
3
4
5
6
For i = LBound(a1) To UBound(a1)
  ListBox1.AddItem a1(i)
  ListBox1.List(ListBox1.ListCount - 1, 1) = a2(i)
  ListBox1.List(ListBox1.ListCount - 1, 2) = a3(i)
  ListBox1.List(ListBox1.ListCount - 1, 3) = a4(i)
Next

Цитата
Сообщение от AndreA SN
Посмотреть сообщение

элементу 1 первого массива соответствует элемент 1 второго, третьего и четвертого массивов.

Проще сделать двумерный массив. Тогда и листбокс можно будет одной строчкой кода заполнить.



1



AndreA SN

1014 / 118 / 2

Регистрация: 26.08.2011

Сообщений: 1,113

Записей в блоге: 2

28.03.2012, 13:12

 [ТС]

4

пр двумерный массив думал. там действительно одна строчка кода нужна типа

Visual Basic
1
Me.ListBox5.List() = spisok()

Но проблема заключается в использовании динамического массива.
У меня данные располагаются в строках, количество которых меняется. Количество столбцов не меняется (4). Правила объявления динамического массива и последующего использования Preserve требуют, чтоб массив объявлялся как mass(столбцы,строки), где число строк — изменяемое, а число столбцов — нет.
А использование list подразмевает положение mass(строки, столбцы)
Может я просто не совсем понимаю, как организовать тут работу?

Добавлено через 9 минут
Побовал оба варианта. Сверху остается пустая строка в ListBox. В чём может быть причина? Заголовки в ListBox отключены



0



Апострофф

Заблокирован

28.03.2012, 13:40

5

Цитата
Сообщение от AndreA SN
Посмотреть сообщение

Сверху остается пустая строка в ListBox. В чём может быть причина?

Причина наверняка в том, что нижняя граница массивов по умолчанию равна нулю, а заполняли вы их с единицы, т.е. фактически — со второго элемента массива.



0



AndreA SN

1014 / 118 / 2

Регистрация: 26.08.2011

Сообщений: 1,113

Записей в блоге: 2

28.03.2012, 14:12

 [ТС]

6

Апострофф))) спасибо за оплеуху по моему самомнению))))
ноль в массиве — это для меня привычно, можно сказать по-домашнему уютно)))
НО! Может кто-то также влипнет. Перепутал местами строки присвоения значения и увеличения динамического массива на 1.
Было

Visual Basic
1
2
3
            
ReDim Preserve NN(UBound(NN) + 1)
NN(UBound(NN)) = j

а должно было быть

Visual Basic
1
2
NN(UBound(NN)) = j
ReDim Preserve NN(UBound(NN) + 1)

В результате действительно элементы массива начинались с 1, а в 0 — было пусто. Куда высылать пару пива?))))



0



Апострофф

Заблокирован

28.03.2012, 15:43

7

Цитата
Сообщение от AndreA SN
Посмотреть сообщение

а должно было быть

Visual Basic
1
2
NN(UBound(NN)) = j
ReDim Preserve NN(UBound(NN) + 1)

Таким образом мы развернули грабли на 180г, но не вокруг черенка (зубья всё равно наверху)
Теперь пустая строка будет внизу списка.

Проще завести глобальный счётчик типа

Visual Basic
1
public NN_Count as long

и

Visual Basic
1
2
3
ReDim Preserve NN(NN_Count)
NN(NN_Count) = j
NN_Count=NN_Count+1



1



AndreA SN

1014 / 118 / 2

Регистрация: 26.08.2011

Сообщений: 1,113

Записей в блоге: 2

28.03.2012, 17:27

 [ТС]

8

Я по другому сделал. Чтоб не париться с глобальным счетчиком — я просто проверяю — не является ли элемент первым в списке. Если не является — то перед добавкой нового элемента увеличиваем массив на 1

Visual Basic
1
2
3
4
If Klih(0) <> Empty Then
    ReDim Preserve Klih(UBound(Klih) + 1)
End If
Klih(UBound(Klih)) = Elem

В результате ушел от счетчиков вообще))) и всю логику сохранил в одном месте



0



Апострофф

Заблокирован

28.03.2012, 18:38

9

Visual Basic
1
2
3
4
5
6
7
8
9
10
Option Explicit
 
Dim Klih()
 
Sub AddKlih()
If Klih(0) <> Empty Then
  ReDim Preserve Klih(UBound(Klih) + 1)
End If
Klih(UBound(Klih)) = 1 'Elem
End Sub

О_о Error 9 Недопустимый индекс. Т.е. Вы что-то недоговариваете и не всё так просто…

А ещё можно у Гугла спросить —

Размерность динамического не инициализированного массива

— первая ссылка.



1



Dragokas

Эксперт WindowsАвтор FAQ

17991 / 7617 / 890

Регистрация: 25.12.2011

Сообщений: 11,351

Записей в блоге: 17

28.03.2012, 23:23

10

Именно. Поэтому берем и сразу после объявления инициализируем:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
Option Explicit
 
Dim Klih()
 
Sub AddKlih()
Redim Klih(0)
If Klih(0) <> Empty Then
  ReDim Preserve Klih(UBound(Klih) + 1)
End If
Klih(UBound(Klih)) = 1 'Elem
End Sub

Добавлено через 12 минут
…понятно, значит вопрос в том, чтобы как раз не инициализировать?

Добавлено через 8 минут
Тогда вот я одному студенту впаял — инициализация двухмерного массива внутри цикла на основе преобразования типов:
На том сайте, что ты давал, кстати, до такого не додумались (правда здесь тип можно только Variant и Вариант — не совсем массив .



0



1014 / 118 / 2

Регистрация: 26.08.2011

Сообщений: 1,113

Записей в блоге: 2

29.03.2012, 00:24

 [ТС]

11

Апострофф, я тоже инициализировал массив раньше приведенного мной кода
Diskretor всю мою логику полностью здесь повторил.
Я извиняюсь, что всё кучей не публикнул — мусора навалом рядышком накидано с этим кодом. Вот я и забыл о том, что инициализировал массив ранее. За сегодня уже раз 50 прогнал код — ошибок не возникало



0



Апострофф

Заблокирован

29.03.2012, 09:22

12

Цитата
Сообщение от AndreA SN
Посмотреть сообщение

Чтоб не париться с глобальным счетчиком — я просто проверяю — не является ли элемент первым в списке. Если не является — то перед добавкой нового элемента увеличиваем массив на 1

Мне кажется, проще один раз попариться с объявлением глобального счётчика, чем потом всю дорогу плясать с бубнами вокруг If Klih(0) <> Empty.
А если по логике программы некоторые элементы массива могут пустыми?
Новый велосипед изобретать будем

Наглядный пример —

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
Option Explicit
Dim a() As Byte
 
Sub qqq()
ReDim a(0)
Dim I As Byte
For I = 0 To 9
  If a(0) <> Empty Then
    ReDim Preserve a(UBound(a) + 1)
  End If
  a(UBound(a)) = I
Next I
End Sub

Куда же ноль пропал?



1



Alex77755

11482 / 3773 / 677

Регистрация: 13.02.2009

Сообщений: 11,145

29.03.2012, 14:25

13

Я бы сделал уточнение: В вопросе не указано где этот VBA.
Недавно убил целый день на решение аналогичной задачи в Access.
Там в список добавить значения по колонкам метод, предложенный Апострофф, не работает.
Долго искал. Может кому ещё понадобится:

Visual Basic
1
2
3
4
5
6
7
Private Sub Form_Open(Cancel As Integer)
    Dim R, C, N
    For R = 1 To 10
    N = N + 1
          Form_Форма1.ListBox1.AddItem N & ";" & N + 1 & ";" & N + 2 & ";" & N + 3 & ";" & N + 4
    Next R
End Sub



1



In this article I will explain how you can work with a listbox with multiple columns. In the figure below you can see an example of what a multi column listbox would look like:

MultiColumn LIstbox VBA


Creating Multi Column Listboxes:

There are several methods for creating a multi column listbox.

Method 1,  Using the property window:

After inserting a listbox onto the userform, you can define the number of columns using the property window. Change the Column Count Property to the number of columns you wish to have:

Column Count, LIstbox VBA
Method 2, Through VBA Code:

If you don’t know the number of columns you will be needing before runtime, you can set the number of columns using VBA through the ColumnCount property. The code below will create 3 columns for our listbox:

ListBox1.ColumnCount = 3


Modifying Column Width:

Again there are several methods for modifying the width of the columns:

Method 1,  using the property window:

In this method the column widths are defined by modifying the ColumnWidths property in the property windows. The width of each column is separated using a semicolon.  For a listbox with 3 columns, the expression below would change the width of the leftmost column to 30 and the middle column to 20. Note that the last column will take up any space that is left. The values are from left to right:

30;20

MultiColumn Listbox, Column Width, VBA

Note: When working in Excel, the width unit will be in points while in access it will be in inches.

Method 2, Through VBA Code:

Another method for changing the column widths is using VBA at runtime. This is specially useful when you don’t know the size of your columns before running the code. The columns widths can be changed using the ColumnWidths property. The code below will change the width of the left most column to 30 and the next column to 20. The last column will always take up whatever space there is left:

ListBox1.ColumnWidths = "30;20"


Modify Listbox Data:

The items in a multi column listbox can be accessed using the .List member. This member accepts two parameters as input:

ListBox1.List(RowIndex, ColumnIndex)

RowIndex: The row index of the record we want to access. Note the rows in a listbox are zero based. Therefor the index of the first row is “0” (zero).

ColumnIndex: The column index of the field we want to access. Note the columns in a multi column listbox are also zero indexed. Therefore the first column has an index of “0” (zero).

Example: 

Lets say we have a listbox with the following data:

MultiColumn LIstbox VBA
The code below will change the value in the first column of the second row to “NEWNAME”:

ListBox1.List(1, 0) = "NEWNAME"

Result:

The row “Allen Mathews 478-4578” was changed to “NEWNAME Mathews 478-4578”:

MultiColumn Listbox Modify Value


Filling a Multi Column Listbox With Data:

In order to fill a multi column listbox with data there are 2 steps:

Step 1, Create a new row:

This can be done using the code below:

ListBox1.AddItem

Step 2, Modify the new row:

Using the method explained in the previous section the fields of the new row are be modified.

Example:

The code below will do the follwing:

  1. Change ListBox1 to a 4 column listbox.
  2. Modify its column widths
  3. Add values to the 4 columns.

Sub main()
Dim i As Integer
'define 4 column listbox
ListBox1.ColumnCount = 4
'change column widhts
ListBox1.ColumnWidths = "20;40;60"

'assing values to the columns
For i = 1 To 9
    ListBox1.AddItem
    ListBox1.List(i - 1, 0) = i
    ListBox1.List(i - 1, 1) = i * 10
    ListBox1.List(i - 1, 2) = i * 100
    ListBox1.List(i - 1, 3) = i * 1000
Next i
End Sub

Result:

VBA Multicolumn listbox, add rows


Get Selected Items, From Columns:

In order to determine the selected items in a listbox, the .Selected property of the list box could be used:

ListBox1.Selected(RowIndex)

The expression above returns true if the user has selected the row with the index “RowIndex”. One way to determine the selected indices is to loop through all the rows, and use the .Selected property to determine if the current row is selected or not.

After determining if the items is selected or not, you can use the .List member to get the value from the desired column.

Example:

Lets say we have the userform below:

MultiColumn LIstbox VBA
The function below will store the values in the second column of the selected rows in the array, arrLastNames:

Sub Example2()
Dim arrLastName(1 To 100) As String
Dim i As Integer
Dim counter As Integer

counter = 1
'loop through the values in the listbox
For i = 1 To ListBox1.ListCount
    'check if the current value is selected
    If ListBox1.Selected(i - 1) = True Then
        'add the value in the last name column to the
        'array
        arrLastName(counter) = ListBox1.List(i - 1, 1)
        counter = counter + 1
    End If
Next i
End Sub

Assume the following values have been selected in the list box:

VBA Listbox, Selected Items, Multi Column
Result:
Values selected from drop down list

You can download the file and code related to this article from the links below:

  • Listbox_GetSelected.xlsm
  • ListBox_Fill.xlsm

See also:

  • ListBox Object Members (MSDN)

If you need assistance with your code, or you are looking for a VBA programmer to hire feel free to contact me. Also please visit my website www.software-solutions-online.com

This may be a cheap question for some but I’m totally confused on how to populate my listbox.

form with listbox

Using this line I can populate the listbox as shown below:
ListBox1.List = Sheets("Sheet1").Cells(1, 1).CurrentRegion.Value

or

Dim rngName As Range
Dim ws As Worksheet
Dim i As Integer
Set ws = Worksheets("Sheet1")
    For i = 1 To ws.Cells(ws.Rows.Count, 1).End(xlUp).Row Step 1
        If ws.Cells(i, 1).Value <> vbNullString Then Me.ListBox1.AddItem 
        ws.Cells(i, 1).Value
Next i

form with listbox 1 column output

Below is the data I’m planning to use to populate the list box and is progressive. Only the column has the fix count.
Data

Someone please enlighten me on how to populate a list box adapative to multiple columns and rows using FOR LOOP as shown in my code above. Any help appreciated. Thanks.

Community's user avatar

asked Nov 28, 2017 at 9:55

Serversta's user avatar

20

Methods

  1. It’s always better to loop through an array than a range — it’s much faster.
  2. It’s even faster to create a variant data field array with a one liner instead of redimensioning a predeclared array and fill it in an extra loop as proposed by Siddharth Rout (though a good method :-) Note: The code below is based on his Approach referenced in the above comment just to demonstrate the difference.
  3. Fill ListBox1.List with the array (same method, but reverse direction).

Code

Private Sub CommandButton1_Click()
' Purpose:  fill listbox with range values after clicking on CommandButton1
'           (code could be applied to UserForm_Initialize(), too)
' Note:     based on @Siddharth-Rout 's proposal at https://stackoverflow.com/questions/10763310/how-to-populate-data-from-a-range-multiple-rows-and-columns-to-listbox-with-vb
'           but creating a variant data field array directly from range in a one liner
'           (instead of filling a redimensioned array with range values in a loop)
Dim ws      As Worksheet
Dim rng     As Range
Dim MyArray                 ' variant, receives one based 2-dim data field array
'~~> Change your sheetname here
Set ws = Sheets("Sheet1")

'~~> Set you relevant range here
Set rng = ws.Range("A1:C" & ws.Range("A" & ws.Rows.Count).End(xlUp).Row)

With Me.ListBox1
    .Clear
    .ColumnHeads = False
    .ColumnCount = rng.Columns.Count

    '~~> create a one based 2-dim datafield array
     MyArray = rng

    '~~> fill listbox with array values
    .List = MyArray

    '~~> Set the widths of the column here. Ex: For 5 Columns
    '~~> Change as Applicable
    .ColumnWidths = "50;50;50"
    .TopIndex = 0
End With
End Sub

Additional hints

  • Another advantage of the array method — it overcomes the built-in limitation of only 10 columns when using the .AddItem method.

  • Furthermore, keep in mind that listbox indexing is zero based, so for example you get the e-mail address (column 3, index 2) of your first item row (index 0) via ListBox1.List(0, 2), whereas the data field array becomes automatically a one based 2-dim array.

  • You aren’t restricted to use the .List method to get Information out of the listbox, you can reverse the row — column order by using ListBox1.Column" or even create a new array out of it, which remains a 2-dim object, even if there is only ONE item (note: theApplication.Transpose` method would redim a 2 dimensional array with only one row to a 1-dim array).

  • A last point: you can easily dump back again the whole listbox to an Excel sheet via rng = ListBox1.List, but take care to define the correct range.

answered Nov 28, 2017 at 12:17

T.M.'s user avatar

T.M.T.M.

9,2293 gold badges32 silver badges57 bronze badges

2

How about this:

Sub foo()
Dim rngName As Range
Dim ws As Worksheet
Dim i As Integer
Set ws = Worksheets("Sheet1")
ListBox1.Clear
ListBox1.columnCount = 3
Dim LastRow As Long
LastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
    For i = 1 To LastRow
        If ws.Cells(i, 1).Value <> vbNullString Then ListBox1.AddItem ws.Cells(i, 1).Value
        If ws.Cells(i, 2).Value <> vbNullString Then ListBox1.List(i - 1, 1) = ws.Cells(i, 2).Value
        If ws.Cells(i, 3).Value <> vbNullString Then ListBox1.List(i - 1, 2) = ws.Cells(i, 3).Value
    Next i
End Sub

answered Nov 28, 2017 at 11:20

Xabier's user avatar

XabierXabier

7,5771 gold badge8 silver badges20 bronze badges

1

 

Azakia

Пользователь

Сообщений: 297
Регистрация: 30.10.2015

Доброго здоровья всем!
Ребят, такая проблема:
Пытался сделать листбокс на 12 колонок и не получилось. Узнал что листбокс поддерживает только от 0 до 9 колонок но видел формы с большим количеством колонок…или нет…или показалось…
В общем если есть какой метод для большего количества колонок научите пожалуйста!
вот моя книга если что…

 

Ronin751

Пользователь

Сообщений: 924
Регистрация: 10.04.2013

#2

27.04.2016 10:43:26

А Вы не пробовали так?

Код
...
On Error Resume Next
    With Me.ListBox1
           For i = 1 To LastRow
...

Там пустые значения, вот и бьет ошибку. И зачем Вам 12 колонок, если настраиваете на меньшее количество?

Код
Private Sub UserForm_Initialize()'Так проще
ListBox1.ColumnWidths = "60,60,60,60,60"
End Sub

Изменено: Ronin75127.04.2016 10:44:08

 

Azakia

Пользователь

Сообщений: 297
Регистрация: 30.10.2015

Ronin751, эрор не помогает мне загрузить оставшиеся данные для полной картины — необходимо 12-13 скажем таких данных…пустые колонки могут быть тоже заполнены но в листбокс необходимо вывести только эти самые 12-13 ячеек
с шириной колонок конечно да — так проще))))))) намного))))))

 

Azakia

Пользователь

Сообщений: 297
Регистрация: 30.10.2015

Ronin751, эрор просто пропустит и не выбьет ошибку это мне не поможет

 

Doober

Пользователь

Сообщений: 2201
Регистрация: 09.04.2013

#5

27.04.2016 11:21:41

Цитата
Azakia написал:
если есть какой метод

Есть такой

Прикрепленные файлы

  • List 12.xlsb (24.19 КБ)

<#0>

 

Юрий М

Модератор

Сообщений: 60570
Регистрация: 14.09.2012

Контакты см. в профиле

#6

27.04.2016 11:41:19

Цитата
Azakia написал:
Пытался сделать листбокс на 12 колонок и не получилось.

Метод, который Вы использовали, позволяет создавать только 10 столбцов.

Цитата
Ronin751 написал:
Там пустые значения, вот и бьет ошибку

Пустые значения тут не виноваты: не может такой метод работать с бОльшим количеством столбцов.

 

Azakia

Пользователь

Сообщений: 297
Регистрация: 30.10.2015

#7

27.04.2016 12:06:38

Юрий М, да да я написал

Цитата
Узнал что листбокс поддерживает только от 0 до 9 колонок но видел

просто интересуюсь можно ли преодолеть это

Doober, все равно колонку последнюю не подбирает!

 

Ronin751

Пользователь

Сообщений: 924
Регистрация: 10.04.2013

#8

27.04.2016 12:07:01

Цитата
Метод, который Вы использовали, позволяет создавать только 10 столбцов

Интересно, что если Прямым свойством RowSource указывать, то 15 столбцов показывает. ?!?  

Как вариант, может некоторые значения объединять в одном столбце?

Изменено: Ronin75127.04.2016 12:07:59

 

Azakia

Пользователь

Сообщений: 297
Регистрация: 30.10.2015

Doober,  а нет! понял почему! исправил!

 

Azakia

Пользователь

Сообщений: 297
Регистрация: 30.10.2015

Ronin751, изначально я так и решал проблему например сцеплять № заявки с её датой и также последний № свода с его датой (т.е. это последние 4 столбца) но я вроде как видел формы с большими listbox’ами и поэтому возник вопрос

 

Юрий М

Модератор

Сообщений: 60570
Регистрация: 14.09.2012

Контакты см. в профиле

Ronin751, мы же не про свойства говорим, а про программное заполнение.

 

Юрий М

Модератор

Сообщений: 60570
Регистрация: 14.09.2012

Контакты см. в профиле

Лично я собирал бы данные в массив и уже его скармливал ЛистБоксу )

 

Azakia

Пользователь

Сообщений: 297
Регистрация: 30.10.2015

Юрий М, я такого не знаю)))

 

Юрий М

Модератор

Сообщений: 60570
Регистрация: 14.09.2012

Контакты см. в профиле

Уже знаете: Doober ведь показал ))

 

Azakia

Пользователь

Сообщений: 297
Регистрация: 30.10.2015

Doober, спасибо! и всем всем тоже спасибо!

 

Кроме Листбокса есть еще ListView. Пример:  

MS Office 2007,2010
<#0>
ЛЕНЬ-двигатель прогресса!

 

Azakia

Пользователь

Сообщений: 297
Регистрация: 30.10.2015

devilkurs_now, LV_G1 выбивает ошибку! говорит мол не поддерживается объект этой машиной

 

Проверьте подключенные библиотеки в VBA — Tools- References
Библиотека : Microsoft Windows Common Controls 6.0 (SP6)

Изменено: devilkurs_now27.04.2016 14:18:20

MS Office 2007,2010
<#0>
ЛЕНЬ-двигатель прогресса!

 

Или Библиотека   Microsoft Forms 2.0
Не помню..

MS Office 2007,2010
<#0>
ЛЕНЬ-двигатель прогресса!

 

Azakia

Пользователь

Сообщений: 297
Регистрация: 30.10.2015

#20

28.04.2016 12:30:45

Цитата
devilkurs_now написал:
Microsoft Windows Common Controls 6.0 (SP6)

я даже не нашёл в списке…или не заметил…
Юрий М,
а как присвоить к этому массиву конкретный листбокс? если например у меня два листа и два листбокса но одно значение для поиска
т.е. после ввода значения он собирает массив с одного листа и загружает в первый литсбокс и загружает следующий с другого листа во второй листбокс и визуально на форме два заполненных бокса…или это невозможно?

з.ы. наверно надо создать новую тему?

Изменено: Azakia28.04.2016 12:35:15

 

Azakia

Пользователь

Сообщений: 297
Регистрация: 30.10.2015

Юрий М, эээ… нууу…вообщем я вроде понял…наверно))))

 

Azakia

Пользователь

Сообщений: 297
Регистрация: 30.10.2015

Юрий М, да! понял — сделал

 

Юрий М

Модератор

Сообщений: 60570
Регистрация: 14.09.2012

Контакты см. в профиле

 

Azakia

Пользователь

Сообщений: 297
Регистрация: 30.10.2015

#24

28.04.2016 16:21:24

Юрий М, ага)))

Понравилась статья? Поделить с друзьями:
  • Listbox value in excel vba
  • Listbox rowsource vba excel примеры
  • List of forms of word play
  • List of files in a folder excel
  • List of files and folders in excel