Заполнение списка ComboBox из кода VBA Excel по условию в зависимости от выбранного значения в другом элементе управления ComboBox на примере ФИО.
Описание примера по заполнению списка ComboBox по условию в зависимости от выбранного значения в другом элементе управления ComboBox.
1. Исходная таблица со списками фамилий, имен и отчеств для заполнения элементов управления ComboBox из кода VBA Excel:
Список ФИО отсортирован по алфавиту, что позволит без использования дополнительного кода VBA Excel заполнить ComboBox1 только уникальными фамилиями, а также облегчит поиск фамилии для выбора в раскрывающемся списке.
2. Пользовательская форма с элементами управления ComboBox1, ComboBox2 и ComboBox3 для фамилий, имен и отчеств с соответствующими им надписями:
3. Необходимо с помощью кода VBA Excel:
- заполнить список элемента ComboBox1 уникальными фамилиями;
- заполнить ComboBox2 именами, соответствующими выбранной фамилии в ComboBox1;
- заполнить ComboBox3 отчествами, соответствующими выбранной фамилии в ComboBox1 и выбранному имени в ComboBox2.
Условие заполнения следующего элемента ComboBox — выбранное значение в предыдущем поле со списком.
Заполнение ComboBox1 уникальными фамилиями
Заполняем список ComboBox1 фамилиями из таблицы с помощью кода VBA Excel при открытии пользовательской формы, используя событие UserForm_Initialize
:
Private Sub UserForm_Initialize() Dim arr() As Variant, n As Long, i As Long With Worksheets(«Лист5») ‘Определяем количество строк в таблице n = .Cells(1, 1).CurrentRegion.Rows.Count ‘Копируем фамилии из диапазона в массив arr = .Range(.Cells(1, 1), .Cells(n, 1)).Value End With For i = 2 To n ‘Условие используем для добавления в список уникальных фамилий If arr(i — 1, 1) <> arr(i, 1) Then ‘Добавляем очередную фамилию в список ComboBox1 ComboBox1.AddItem arr(i, 1) End If Next End Sub |
Фамилии из столбца таблицы копируются в массив для ускорения цикла, так как в массивах циклы работают быстрее, чем в диапазонах.
Заполнение ComboBox2 именами по условию
Когда мы выбираем значение в поле со списком ComboBox1, происходит событие ComboBox1_Change, которое будем использовать для автоматического заполнения элемента ComboBox2 именами, соответствующими выбранной фамилии:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
Private Sub ComboBox1_Change() Dim arr() As Variant, n As Long, i As Long With Worksheets(«Лист5») ‘Определяем количество строк в таблице n = .Cells(1, 1).CurrentRegion.Rows.Count ‘Копируем фамилии и имена из диапазона в массив arr = .Range(.Cells(1, 1), .Cells(n, 2)).Value End With ‘Очищаем ComboBox2 от элементов предыдущего списка ComboBox2.Clear For i = 2 To n ‘Условие используем для добавления в список имен, соответствующих выбранной фамилии If arr(i, 1) = ComboBox1.Value Then ‘Добавляем очередное имя в список ComboBox2 ComboBox2.AddItem arr(i, 2) End If Next With ComboBox2 ‘Если в списке один элемент, автоматически его выбираем If .ListCount = 1 Then .ListIndex = 0 End With End Sub |
Имена в ComboBox2 могут повторяться, так как отбор уникальных значений не производится. Если имена в списке ComboBox2 должны быть уникальными, можно сначала добавить их в объект Collection с отбором уникальных значений, а потом из объекта Collection скопировать имена с помощью цикла For Each ... Next
в ComboBox2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
Private Sub ComboBox1_Change() Dim arr() As Variant, n As Long, i As Long, myCollection As New Collection, myElement As Variant With Worksheets(«Лист5») ‘Определяем количество строк в таблице n = .Cells(1, 1).CurrentRegion.Rows.Count ‘Копируем фамилии и имена из диапазона в массив arr = .Range(.Cells(1, 1), .Cells(n, 2)).Value End With ‘Очищаем ComboBox2 от элементов предыдущего списка ComboBox2.Clear For i = 2 To n ‘Условие используем для добавления в список имен, соответствующих выбранной фамилии If arr(i, 1) = ComboBox1.Value Then ‘Добавляем очередное уникальное имя в Collection On Error Resume Next myCollection.Add CStr(arr(i, 2)), CStr(arr(i, 2)) On Error GoTo 0 End If Next With ComboBox2 ‘Заполняем список элемента ComboBox2 именами из коллекции For Each myElement In myCollection .AddItem myElement Next myElement ‘Если в списке один элемент, автоматически его выбираем If .ListCount = 1 Then .ListIndex = 0 End With End Sub |
Заполнение ComboBox3 отчествами по условию
Выбор одного из элементов в ComboBox2, как и автоматический выбор единственного элемента предыдущим кодом, вызывает событие ComboBox2_Change, которое будем использовать для автоматического заполнения элемента ComboBox3 отчествами, соответствующими выбранной фамилии в ComboBox1 и выбранному имени в ComboBox2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
Private Sub ComboBox2_Change() Dim arr() As Variant, n As Long, i As Long With Worksheets(«Лист5») ‘Определяем количество строк в таблице n = .Cells(1, 1).CurrentRegion.Rows.Count ‘Копируем фамилии, имена и отчества из диапазона в массив arr = .Range(.Cells(1, 1), .Cells(n, 3)).Value End With ‘Очищаем ComboBox3 от элементов предыдущего списка ComboBox3.Clear For i = 2 To n ‘Условие для добавления в список отчеств, соответствующих выбранным фамилии и имени If arr(i, 1) = ComboBox1.Value And arr(i, 2) = ComboBox2.Value Then ‘Добавляем очередное отчество в список ComboBox3 ComboBox3.AddItem arr(i, 3) End If Next With ComboBox3 ‘Если в списке один элемент, автоматически его выбираем If .ListCount = 1 Then .ListIndex = 0 End With End Sub |
Отчества в ComboBox3 повторяться не могут, так как это означало бы, что в таблице есть два или более совершенно одинаковых ФИО.
Один из результатов работы кода VBA Excel по заполнению полей со списком ComboBox в зависимости от выбранного значения в другом элементе управления ComboBox на примере ФИО:
Если фамилия в списке встречается один раз, и ей соответствует одно имя, а фамилии и имени — одно отчество, тогда при выборе этой фамилии в элементе управления ComboBox1, имя и отчество в ComboBox2 и ComboBox3 выберутся автоматически.
Actually, your code is correct, but your condition will be called only when your workbook will be opened (WorkBook_open()
) …
This code:
If Me.ComboBox1.Value = "Paris" Then
Range("A1").Value = 5
End If
should be in an other procedure.
Ex: If you want A1
to change when you select an item you can do:
Private Sub Workbook_open()
With Sheet1.ComboBox1
.AddItem "Paris"
.AddItem "New York"
.AddItem "London"
End With
End Sub
Private Sub ComboBox1_Change()
If Me.ComboBox1.Value = "Paris" Then
Range("A1").Value = 5
End If
End Sub
Actually ComboBox1_Change
is called every time ComboBox1
value changes (pretty obvious)
NOTE: This code is tested and works for me, but there are other ways to do, like adding a commandButton
and checking the condition only when this button is clicked.
Создание списка в Combobox с условием |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
ac1-caesar Пользователь Сообщений: 471 |
#1 22.01.2015 11:20:36 Уважаемые форумчане! Подскажите пожалуйста путь решения вопроса.
Действие выполняется по условию в If (m — m1) * (m — m2) <= 0 And A_check Изменено: ac1-caesar — 22.01.2015 11:21:40 |
||
ber$erk Пользователь Сообщений: 2735 |
#2 22.01.2015 11:43:00 Может что-то типа такого?
Изменено: ber$erk — 22.01.2015 11:43:43 Учимся сами и помогаем другим… |
||
Если бы было одно или два таких условия, то так и сделал бы. Но таких условий больше десятка. |
|
ber$erk Пользователь Сообщений: 2735 |
а условие только на неравенство? Учимся сами и помогаем другим… |
ac1-caesar Пользователь Сообщений: 471 |
#5 22.01.2015 13:29:10
нет, может быть и равенство. |
||
ber$erk Пользователь Сообщений: 2735 |
#6 22.01.2015 13:52:12 если есть равенство, то использовать 2 коллекции.
про какой именно вариант Вы говорите? я уже второй предложил. Учимся сами и помогаем другим… |
||
ac1-caesar Пользователь Сообщений: 471 |
#7 22.01.2015 13:55:16 Этот:
Изменено: ac1-caesar — 23.01.2015 03:03:05 |
||
ber$erk Пользователь Сообщений: 2735 |
Первый вариант предлагаю забыть. Второй более оптимален, ИМХО. Учимся сами и помогаем другим… |
Примером можете показать? |
|
ber$erk Пользователь Сообщений: 2735 |
Может все таки Вы свой файлик приложите? Учимся сами и помогаем другим… |
The_Prist Пользователь Сообщений: 14181 Профессиональная разработка приложений для MS Office |
#11 22.01.2015 14:24:42 Если всегда используется .Cells(r, 47), то можно через Evaluate:
Или как уже предложили, коллекциями/словарями/массивами:
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
||||
RAN Пользователь Сообщений: 7091 |
#12 22.01.2015 14:30:10 Мне тоже файла жалко
|
||
The_Prist, RAN, спасибо, буду пробовать. |
|
ac1-caesar Пользователь Сообщений: 471 |
#14 22.01.2015 15:57:36
The_Prist, подскажите пожалуйста, какую роль здесь играет переменная bTrue ? На сколько я понял, действие нужно вставлять после строчки If s <> avCond(li) Then? |
||
The_Prist Пользователь Сообщений: 14181 Профессиональная разработка приложений для MS Office |
#15 22.01.2015 16:10:36 М-да…Пошаговая отладка Вам неведома? For li = LBound(avCond) To UBound(avCond) скажет Вам — выполняются ли Ваши условия или нет. Следовательно именно после цикла надо проверять эту переменную и тогда уже смотреть что делать.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
||
ac1-caesar Пользователь Сообщений: 471 |
#16 22.01.2015 16:29:58 The_Prist, в моем случае наверное не If bTrue = True Then, а If bTrue = False Then ? Так как в случае неравенства должно происходить действие.
|
||
The_Prist Пользователь Сообщений: 14181 Профессиональная разработка приложений для MS Office |
#17 22.01.2015 17:09:46 Ну тут Вам виднее. Я показал лишь пример более краткой реализации. Использовать можно по-разному. Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
Below we will look at a program in Excel VBA which creates a Userform that contains dependent combo boxes. The Userform we are going to create looks as follows:
The user selects Animals from a drop-down list. As a result, the user can select an animal from a second drop-down list.
The user selects Sports from a drop-down list. As a result, the user can select a sport from a second drop-down list.
To create this Userform, execute the following steps.
1. Open the Visual Basic Editor. If the Project Explorer is not visible, click View, Project Explorer.
2. Click Insert, Userform. If the Toolbox does not appear automatically, click View, Toolbox. Your screen should be set up as below.
3. Add the combo boxes (first at the left, the second at the right) and command button. Once this has been completed, the result should be consistent with the picture of the Userform shown earlier. For example, create a combo box control by clicking on ComboBox from the Toolbox. Next, you can drag a combo box on the Userform.
4. You can change the names and the captions of the controls. Names are used in the Excel VBA code. Captions are those that appear on your screen. It is good practice to change the names of the controls, but it is not necessary here because we only have a few controls in this example. To change the caption of the Userform and command button, click View, Properties Window and click on each control.
5. To show the Userform, place a command button on your worksheet and add the following code line:
Private Sub CommandButton1_Click()
UserForm1.Show
End Sub
We are now going to create the Sub UserForm_Initialize. When you use the Show method for the Userform, this sub will automatically be executed.
6. Open the Visual Basic Editor.
7. In the Project Explorer, right click on UserForm1 and then click View Code.
8. Choose Userform from the left drop-down list. Choose Initialize from the right drop-down list.
9. Add the following code lines:
Private Sub UserForm_Initialize()
With ComboBox1
.AddItem «Animals»
.AddItem «Sports»
.AddItem «Food»
End With
End Sub
Explanation: These code lines fill the first combo box.
We have now created the first part of the Userform. Although it looks neat already, nothing will happen yet when we select an item from the first combo box.
10. In the Project Explorer, double click on UserForm1.
11. Double click on the first combo box.
12. Add the following code lines:
Private Sub ComboBox1_Change()
Dim index As Integer
index = ComboBox1.ListIndex
ComboBox2.Clear
Select Case index
Case Is = 0
With ComboBox2
.AddItem «Dog»
.AddItem «Cat»
.AddItem «Horse»
End With
Case Is = 1
With ComboBox2
.AddItem «Tennis»
.AddItem «Swimming»
.AddItem «Basketball»
End With
Case Is = 2
With ComboBox2
.AddItem «Pancakes»
.AddItem «Pizza»
.AddItem «Chinese»
End With
End Select
End Sub
Explanation: Excel VBA uses the value of the variable index to test each subsequent Case statement to see with which items the second combo box should be filled. Go through our Select Case program to learn more about the Select Case structure.
13. Double click on the Import button.
14. Add the following code line:
Private Sub CommandButton1_Click()
Range(«A1»).Value = ComboBox2.Value
End Sub
Result: