The syntax you are looking for is
Me.Controls.Item("ComboBox" & j)
But leaving the user controls at their random default names is bad style. Give them appropriate names right from the start, so references to them in VBA code can actually be meaningful.
Here is a more refined approach: In your UserForm that contains the color combo boxes, edit their properties and name them ColorBox_0
through ColorBox_4
. Then, in the code for that UserForm, add this:
Option Explicit
Private Const COLOR_BOX_COUNT As Integer = 4 ' actually that's 5, as we count from 0
Private Sub UserForm_Initialize()
Dim cmb As ComboBox, i As Integer
' Prepare color combo boxes with actual RGB color codes and names
For i = 0 To COLOR_BOX_COUNT
Set cmb = Me.Controls.Item("ColorBox_" & i)
cmb.Clear
cmb.ColumnCount = 2
cmb.ColumnHeads = False
cmb.ColumnWidths = "0;"
cmb.AddItem "000000": cmb.Column(1, 0) = "Black"
cmb.AddItem "FF0000": cmb.Column(1, 1) = "Red"
cmb.AddItem "00FF00": cmb.Column(1, 2) = "Green"
cmb.AddItem "0000FF": cmb.Column(1, 3) = "Blue"
cmb.AddItem "FF00FF": cmb.Column(1, 4) = "Magenta"
cmb.AddItem "7C2927": cmb.Column(1, 5) = "Brown"
cmb.MatchRequired = True
cmb.Value = cmb.List(0) ' pre-select first entry
Next i
End Sub
Public Function GetSelectedColors() As Long()
Dim cmb As ComboBox, i As Integer
Dim result(COLOR_BOX_COUNT) As Long
For i = 0 To COLOR_BOX_COUNT
Set cmb = Me.Controls.Item("ColorBox_" & i)
If IsNull(cmb.Value) Then
result(i) = -1
Else
result(i) = GetColor(cmb.Value)
End If
Next i
GetSelectedColors = result
End Function
Note how GetSelectedColors()
returns an array of colors.
There also is a helper function to convert RGB color codes to a number (colors are Long
values in VBA, so if you would like to actually use the color in some way, like setting the BackColor
of a control, you can actually use that value straight-away):
Function GetColor(rgb As Variant) As Long
If Len(rgb) = 6 And IsNumeric("&H" & rgb) Then
GetColor = CLng("&H" & Right(rgb, 2) & Mid(rgb, 3, 2) & Left(rgb, 2))
End If
End Function
With all this, you don’t need magic constants (1 = Black, 3 = Red
) anymore, the UserForm bootstraps itself on start and global variables are gone as well, which is a good thing.
The only convention I made is that a color value of -1
means that the user has not selected an item in the ComboBox. This should not happen as the ComboBoxes start with the first entry pre-selected.
Now you can get the selected colors directly
Private Sub TestButton_Click()
Dim colors() As Long
colors = Me.GetSelectedColors
' do something with them'
End Sub
Or maybe
Private Sub ColorBox_1_Change()
ColorLabel_1.BackColor = GetColor(ColorBox_1.Value)
End Sub
Заполнение списка 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 выберутся автоматически.
1 / 1 / 0 Регистрация: 08.09.2017 Сообщений: 391 |
|
1 |
|
05.10.2019, 07:27. Показов 4054. Ответов 3
Доброго времени суток!
0 |
Заблокирован |
||||
05.10.2019, 09:06 |
2 |
|||
Baykal555, я угадал проблему?
0 |
Baykal555 1 / 1 / 0 Регистрация: 08.09.2017 Сообщений: 391 |
||||
05.10.2019, 20:08 [ТС] |
3 |
|||
Остап Бонд, Я подставил, но что-то все равно приходится значения из Combobox выставлять и каждый раз нажимать на кнопку:
0 |
Narimanych 2628 / 1634 / 744 Регистрация: 23.03.2015 Сообщений: 5,135 |
||||
05.10.2019, 22:09 |
4 |
|||
Baykal555, прикрепите файл… И вам легче и нас мучать не надо… Добавлено через 16 минут у него :
ComboBox1.List(i) у вас :
ComboBox1 Немного «прибрался » в вашем коде…
0 |
IT_Exp Эксперт 87844 / 49110 / 22898 Регистрация: 17.06.2006 Сообщений: 92,604 |
05.10.2019, 22:09 |
Помогаю со студенческими работами здесь Перебор значений циклом в ОЛАП сводной таблице Пишу макрос связанный с ОЛАП кубом. необходимо для начала получить количество… Перебор значений лотереи, контроль выпавших чисел Перебор значений в поле с добавлением в ComboBox Перебор комбинаций значений параметров с выводом и сохранением связанных с ними значений Такой вопрос: Реализовать перебор ComboBox перебор в 2ух combobox Искать еще темы с ответами Или воспользуйтесь поиском по форуму: 4 |
Kentavrik7 Пользователь Сообщений: 433 |
#1 22.11.2018 15:16:28 Добрый день имеются следующие значения в Combobox
Пользователь может выбрать один из месяцев например «МАРТ»
произойдет чудо и все заработает, чуда не было. Прошу опытный взгляд для решения тривиальной задачи
то есть задача сводится к тому что необходимо изменить значения которое будет выдавать комбо бокс. Изменено: Kentavrik7 — 22.11.2018 16:29:34 |
||||||
_Igor_61 Пользователь Сообщений: 3007 |
Kentavrik7,приложите файл с образцом данных и с Вашим комбобоксом. Может, Ваша задача решится другим способом. Например, на первый взгляд, мне кажется, что список для комбобокса можно хранить на листе, тогда и заморочек типа «CombBox1.ListIndex» можно будет избежать |
Dima S Пользователь Сообщений: 2063 |
Kentavrik7, столько текста с описанием вашего каламбура, а так и непонятно что нужно на выходе. |
Юрий М Модератор Сообщений: 60570 Контакты см. в профиле |
#4 23.11.2018 07:16:10
Что следует понимать под обработкой? И покажите Ваш файл-пример — не рисовать же нам форму с этим ComboBox. |
||
БМВ Модератор Сообщений: 21376 Excel 2013, 2016 |
#5 23.11.2018 08:12:51 В целом метод не поддержу, так как он меняет значение комбо. У вас надо попроавить
Ну или
Но, как уже сказал , значение комбо останется последним и его или надо вернуть, предварительно запомнив выбор, или менять подход. Изменено: БМВ — 23.11.2018 08:13:05 По вопросам из тем форума, личку не читаю. |
||||
Kentavrik7 Пользователь Сообщений: 433 |
#6 23.11.2018 09:28:00
нет на листе не получитсмя
Нужно чтобы при выборе значения с комбобокса можно было прогнать по всему коду сначала его, потом следующее значение потом следующее. и при выборе в комбобоксе пользователем например «1 квартал», пройти циклом по коду, сначала «январь» затем «февраль» потом «март». |
||||
Nordheim Пользователь Сообщений: 3154 |
Прочитал несколько раз , так и не понял что нужно сделать. Приложите файл пример с кодом который есть, и вкратце что вы хотите иметь на выходе. Только не нужно очередной раз писать ComboBox.ListIndex (а то уже глаза мозолит). «Все гениальное просто, а все простое гениально!!!» |
БМВ Модератор Сообщений: 21376 Excel 2013, 2016 |
Kentavrik7, я вам написал, как сделать чтоб работало. По вопросам из тем форума, личку не читаю. |
Jack Famous Пользователь Сообщений: 10846 OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome |
#9 23.11.2018 10:08:28
ответ по цитате, не вникая в суть (вдруг угадал): смотрите, если массивы равны, то второго цикла не нужно, поскольку, зная индекс выбранного элемента, например arr_1(5), мы сможем вытянуть по нему (индексу) соответствующий элемент другого массива, например arr_2(5) Изменено: Jack Famous — 23.11.2018 10:09:50 Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄ |
||
ZVI Пользователь Сообщений: 4328 |
#10 23.11.2018 10:11:15 Если на листе/форме размещен ComboBox1, то код в модуле этого же листа/формы:
Изменено: ZVI — 23.11.2018 10:20:02 |
||
Юрий М Модератор Сообщений: 60570 Контакты см. в профиле |
Kentavrik7, а если выбрали предпоследний, последний — что тогда? |
Kentavrik7 Пользователь Сообщений: 433 |
#12 23.11.2018 10:44:14 ZVI,спасибо большое буду пробовать) |