Выпадающий список с добавлением новых элементов

Предположим, что у нас есть справочник с именами сотрудников и таблица, куда этих сотрудников нужно вносить:

Исходные данные

Задача состоит из двух частей:

  • Сделать выпадающий список, причем так, чтобы при дописывании новых людей к справочнику - они автоматически появлялись и в выпадающем списке.
  • Реализовать возможность добавления новых людей в список и с другой стороны - при вводе нового имени в любую из жёлтых ячеек оно должно автоматически добавляться к справочнику (и в выпадающий список в будущем, само-собой).

Такая вот двухсторонняя связь справочника и выпадающего списка.

Шаг 1. Создаем умную таблицу

Сначала превратим справочник в "умную" таблицу, чтобы воспользоваться одним из главных её преимуществ - динамической автоподстройкой размеров при добавлении новых данных.

Для этого выделим весь справочник (ячейки A1:A7) и нажмём сочетание клавиш Ctrl+T или выберем Главная - Форматировать как таблицу (Home - Format as Table). В следующем окне можно смело жать ОК:

Создаем умную таблицу

Шаг 2. Создаем динамический именованный диапазон

Теперь создадим именованный диапазон, указывающий на заполненные именами ячейки в нашем справочнике. Для этого выделим в справочнике уже только имена без шапки (ячейки A2:A7) и в левой части строки формул (там будет имя таблицы) введём имя для нашего диапазона (например Люди):

Создаем резиновый именованный диапазон

После ввода имени обязательно нужно нажать на клавишу Enter - слово Люди исчезнет из этого поля, но диапазон будет создан.

Хитрость тут в том, что поскольку мы выделяли столбец уже в "умной" таблице, то и именованный диапазон у нас получился завязанным на колонку [Справочник], а не на конкретные выделенные ячейки. Убедиться в этом можно, если выбрать на вкладке Формулы команду Диспетчер имен (Formulas - Name Manager) и посмотреть куда ссылается имя Люди:

Диспетчер имен

Таким образом, при дописывании новых имен к справочнику будет расширяться наша "умная" Таблица1, а за ней и наш именованный диапазон Люди.

Шаг 3. Создаем выпадающий список в ячейке

Выделяем жёлтые ячейки и жмем на вкладке Данные (Data) кнопку Проверка данных (Data Validation) 

Далее выбираем из выпадающего списка Тип данных (Allow) позицию Список (List) и вводим в строку Источник (Source) ссылку на созданный на шаге 1 именованный диапазон (не забудьте перед именем диапазона поставить знак равенства!):

Создаем выпадающий список

Чтобы Excel позволил нам в будущем ввести в список и новые имена, снимем галочки на вкладках Сообщение для ввода (Input Message) и Сообщение об ошибке (Error Alert) и нажмем ОК. Выпадающий список готов!

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

Пополняем справочник

Шаг 4. Добавляем простой макрос

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

Щёлкаем правой кнопкой мыши по ярлычку нашего листа и выбираем Просмотреть код (View Source). Откроется модуль листа в редакторе Visual Basic, куда надо скопировать такой код:

Private Sub Worksheet_Change(ByVal Target As Range)
    Set p = Range("Люди")
    If Target.Cells.Count > 1 Then Exit Sub
    If IsEmpty(Target) Then Exit Sub
    If Not Intersect(Target, Range("D2:D10")) Is Nothing Then
        If WorksheetFunction.CountIf(p, Target) = 0 Then
            r = MsgBox("Добавить новое имя в справочник?", vbYesNo)
            If r = vbYes Then p.Cells(p.Rows.Count + 1) = Target
        End If
    End If
End Sub

Теперь при попытке ввести новое имя в любую из жёлтых ячеек Excel будет спрашивать:

Вопрос о добавлении

... и при утвердительном ответе пользователя автоматически добавлять новое имя к справочнику и в выпадающий список в дальнейшем.

Ссылки по теме


Страницы: 1  2  3  
подскажите пожалуйста, а как можно прописать этот пример на combobox?
13.11.2017 08:37:06
есть даные на 1 и 2 лист Excel  правери их если есть одинакивае даны то ответь паказат на 3 листь как это делаеть. Пажалуста ответе скарй.
04.01.2018 07:50:26
Здравствуйте! Спасибо большое за информацию!!! Подскажите пожалуйста как делать зависимый выпадающий список таким же как и у вас, с возможностью вносить изменения. Заранее благодарю!
29.03.2018 18:32:48
Здравствуйте! Помогите пожалуйста. Есть  список на одном листе, ячейка с выпадающем списком для выбора на другом листе. В списке порядка 200 строк, активно пользуются примерно 50, как скрыть временно не нужные строки в списке, что бы они не мешались при выборе. Если скрыть в списке строки любым  путем,  они все равно видны при выборе.
06.04.2018 12:13:35
Добрый день, форумчане!
Помогите, пожалуйста, объединить два макроса в один


Private Sub Worksheet_Change(ByVal Target As Range)

Dim lReply As Long

   If Target.Cells.Count > 1 Then Exit Sub
   If Target.Address = "$D$2" Then
    If IsEmpty(Target) Then Exit Sub
If WorksheetFunction.CountIf(Range("People", Target) = 0 Then
   lReply = MsgBox("Добавить введенное имя " & _
Target & " в выпадающий список?", vbYesNo + vbQuestion)
   If lReply = vbYes Then
 Range("People".Cells(Range("People".Rows.Count + 1, 1) = Target
   End If
End If
    End If
End Sub



И


Private Sub Worksheet_Change(ByVal Target As Range)
For Each cell In Target   '
If Not Intersect(cell, Range("A3:A100" Is Nothing Then  '
 With cell.Offset(0, 1)   '
   Application.Calculation = xlManual
   .Value = Now
   Application.Calculation = xlAutomatic
End With
  End If
 Next cell
  For Each cell In Target   '
If Not Intersect(cell, Range("F3:F100" Is Nothing And cell Like "Устранено*" Then  '
With cell.Offset(0, 1)   '
   Application.Calculation = xlManual
   .Value = Now
   Application.Calculation = xlAutomatic
   End With
    End If
Next cell
End Sub
Запилил макрос с список с поиском по буквам и вводом новых значений на другой лист

Option Explicit
Option Compare Text
Dim bu As Boolean

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.CountLarge > 1 Then Exit Sub
If Target.Row = 1 Then Me.TextBox1.Visible = False: Me.ListBox1.Visible = False: Exit Sub
If Target.Column = 3 Then ' номер столбца, в который вносим значения
    bu = True
    With Me.TextBox1
        .Top = Target.Top: .Text = Target.Value: .Activate
    End With
    With Me.ListBox1
        .Top = Target.Top + 5
        If (.Top + .Height + ActiveWindow.PointsToScreenPixelsY(0) * Application.InchesToPoints(1) * 15 / 1440) > _
           (ActiveWindow.Application.Height + ActiveWindow.Application.Top) Then _
           .Top = .Top - .Height + Target.Height    '* ActiveWindow.Zoom / 100
        .Clear
    End With
    bu = False
    Me.TextBox1.Visible = True: Me.ListBox1.Visible = True
Else
    Me.TextBox1.Visible = False: Me.ListBox1.Visible = False
End If
End Sub

Private Sub TextBox1_Change()
If Len(TextBox1.Text) = 0 Or bu Then Exit Sub    'при отсутствии символов для поиска - выход
Dim x, i As Long, txt As String, lt As Long, s As String
txt = TextBox1.Text: lt = Len(TextBox1.Text)
'Где ищем значения
x = Sheets("номенклатура";).Columns(1).SpecialCells(2).Offset(1).Value
 ' For i = 1 To UBound(x, 1)    ' поиск по первым буквам
    'If txt = Mid(x(i, 1), 1, lt) Then s = s & x(i, 1) & "~"
For i = 1 To UBound(x, 1) 'поиск по любому вхождению
 If InStr(x(i, 1), txt) Then s = s & "~" & x(i, 1)
Next i
ListBox1.List = Split(s, "~";)
End Sub

Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
If KeyCode = 13 Or KeyCode = 9 Then
    With Me.TextBox1
        ActiveCell.Value = .Value
        .Visible = False: ListBox1.Visible = False
    End With
    ActiveCell(2, 1).Select
End If
End Sub

Private Sub ListBox1_Click()
If ListBox1.ListIndex = -1 Then Exit Sub
Application.EnableEvents = False
bu = True
With Me.ListBox1
    ActiveCell.Value = .Value
    Me.TextBox1.Text = .Value
    Me.TextBox1.Visible = False: .Visible = False
End With

Application.EnableEvents = True
bu = False
End Sub

Private Sub Worksheet_Change(ByVal Target As Range)

Dim lReply As Long

    If Target.Column = 2 Then Exit Sub
        If Not Intersect(Target, Range("C2:C100000";)) Is Nothing Then
            If IsEmpty(Target) Then Exit Sub
                If WorksheetFunction.CountIf(Sheets("номенклатура";).Columns(1), Target) = 0 Then
                    lReply = MsgBox("Добавить введенное имя  " & Target & " в выпадающий список", vbYesNo + vbQuestion)
                        If lReply = vbYes Then
                            Worksheets("номенклатура";).Range("номенклатура";).Cells(Worksheets("номенклатура";).Range("номенклатура";).Rows.Count + 1, 1) = Target
                        End If
                End If
        End If
    Sheets("номенклатура";).Range("номенклатура";).Sort Key1:=Sheets("номенклатура";).Range("A1";), Order1:=xlAscending, Header:=xlGuess, _
    OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
    DataOption1:=xlSortNormal 'этот код и поможет отсортировать в алфавитном порядке'
End Sub
13.02.2024 10:25:30
Здравствуйте, а подскажите есть файл примера, можете прислать
01.07.2018 11:54:41
Ничего не получается. У меня чуть чуть отличается таблица - и всё, уже ничего не работает. Жаль что нету пошагового видео на эту тему.
22.02.2019 20:34:28
Добрый вечер. Помогите, пожалуйста. Был создан выпадающий список и все было прекрасно. Но сейчас, по какой-то причине, я не могу добавить новое значение. Встаю на ячейку, куда необходимо внести новое значение, добавляю в Источник через ;, Ставлю Галку Распространить изменения на другие ячейки и ничего не происходит :( Выделения всего столбца не происходит. Новое значение в списке не появляется.  В других столбцах, где тоже есть списки, все работает. Что я не так делаю? Спасибо!
14.06.2019 18:47:34
Добрый вечер.
Помогите написать правильно в макрос формулу ВПР это для того, чтобы при выборе в выпадающем списке "формула" происходило вычисление по заданной формуле.
У меня все таблицы с данными:
- Искомое значение в ВПР находиться на том же листе что и ячейка с выпадающим списком F2, то есть "Заявка" столбец "Серийный номер компонента" в нем первое значение "E2"
- Таблица находиться на другом листе "ActiveComponentDetails" диапазон  A:BA
- Номер столбца на том же листе - 37
В данном виде выделяет данную строчку желтым.
Спасибо большое.

Private Sub Worksheet_Change(ByVal Target As Range)
   If Target <> [F2] Then Exit Sub
   If Target.Value = "формула" Then Target.Formula = "=ЕСЛИОШИБКА(ВПР([@[Серийный номер компонента]];ActiveComponentDetails!A:BA;37;0);"""
End Sub
27.09.2019 22:02:41
пару месяцев назад тут писал вариант выпадающего списка с добавлением новых элементов с помощью UDF, было бы неплохо дополнить статью данным приемом
21.12.2019 18:38:47
Добрый день,
можно ли сделать на одном листе несколько раскрывающихся списков и под каждый из списков будет свой справочник на том же листе?
что  надо в макросе менять (кроме ссылок на диапазоны)?
14.01.2020 07:57:00
Очень полезный урок! Но что если "справочник" находится на одном листе, а рабочая таблица на другом?
Мне данная кодировка не помогает. Что там нужно менять? Поможете?
13.02.2020 12:30:26
Добрый день. А можно ли чтобы Справочник находился в другом файле(книге) на листе. Чтобы динамический диапазон и справочник находился в разных файлах.Как изменится макрос. Если не трудно написать макрос в этой теме
07.08.2022 16:28:59
Добрый день!!
И меня это интересует.
23.11.2020 20:09:25
Здравствуйте! Николай подскажите пожалуйста в чем ошибка ?
Private Sub Workbook_SheetChange(ByVal Target As Range)
   Set p = Range("Источник2")
   If Target.Cells.Count > 1 Then Exit Sub
   If IsEmpty(Target) Then Exit Sub
   If Not Intersect(Target, Range ("c2:c1000,d2:d1000") Is Nothing Then
           If WorksheetFunction.CountIf(p, Target) = 0 Then
           r = MsgBox("Taze sozi gosjakmy?", vbYesNo)
           If r = vbYes Then p.Cells(p.Rows.Count + 1) = Target
       End If
   End If
End Sub
18.01.2021 20:46:34
Здравствуйте, у меня такая проблема: на иконке стоит восклицательный знак и даже ваш скаченный лист не работает. У меня эксель 2019 года. Помогите плиз
Добрый день. Помогите, пожалуйста:( Первый раз пишу макрос, не получается
В моем файле на листе 1 Справочник-Именованный список "Сырье_и_Материалы". На листе 2 калькуляция с добавлением элементов из выпадающего списка, таких листов будет множество. Макрос не срабатывает, ошибка Run time error "1004". Подсвечивает ошибку Set p = Range("Сырье_и_Материалы"). Думаю, что нужно указывать листы, но не знаю, как...помогите, пожалуйста
 Private Sub Worksheet_Change(ByVal Target As Range)
    Set p = Range("Сырье_и_Материалы")
    If Target.Cells.Count > 1 Then Exit Sub
    If IsEmpty(Target) Then Exit Sub
    If Not Intersect(Target, Range("A2:A100")) Is Nothing Then
        If WorksheetFunction.CountIf(p, Target) = 0 Then
            r = MsgBox("Добавить новое имя в справочник?", vbYesNo)
            If r = vbYes Then p.Cells(p.Rows.Count + 1) = Target
        End If
    End If
End Sub
21.04.2021 19:13:03
Здравствуйте!
А можете подсказать, как макрос (добавления в список) сохранить не на листе (конфликтует еще с одним макросом), а в книге или отдельно в модуле?
Спасибо.
01.10.2021 05:46:21
Николай, напишите, пожалуйста, макрос, когда именованный диапазон с данными находится на другом листе книги.
20.10.2021 00:31:09
Николай Павлов, здравствуйте!
Полностью повторила Ваш макрос, но не работает в excel-2019 (при вводе нового имени в ячейке с выпад списком, оно не появляется в справочнике). Никаких ошибок не выдает. Во вкладке безопасности запретов нет. Это проблема в версии?
30.01.2022 14:30:39
Николай, добрый день, спасибо вам огромное за красивый, изящный сайт. Много полезной информации
07.08.2022 16:30:33
Спасибо!
27.02.2023 11:08:02
есть хороший пример реализации выпадающего списка с подстановкой :
автозаполнение при вводе в раскрывающемся списке Excel
23.04.2023 11:17:48
Не пойму. Как сделать, чтобы при добавлении выпадающего списка на листе2, при внесении нового имени на листе1, пополнялся список. Пытался править ваш макрос...ничего не выходит(
23.04.2023 11:19:26
Private Sub Workbook_SheetChange(ByVal Target As Range)
   Set p = Worksheets("Лист1").Range("Люди")
   If Target.Cells.Count > 1 Then Exit Sub
   If IsEmpty(Target) Then Exit Sub
   If Not Intersect(Target, Worksheets("Лист2").Range("C5")) Is Nothing Then
       If WorksheetFunction.CountIf(p, Target) = 0 Then
           r = MsgBox("Добавить новое имя в справочник?", vbYesNo)
           If r = vbYes Then p.Cells(p.Rows.Count + 1) = Target
       End If
   End If
End Sub
29.06.2023 07:02:43
Добрый день. Можно ли сделать такой список из гиперссылок на листы? Щелкнул список, выбрал название листа - и оказался на нем. Желательно без макросов. Названия листов в список можно и руками вбить и изредка откорректировать, необязательно их макросом собирать.
Страницы: 1  2  3  
Наверх