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

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

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

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

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

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

Шаг 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  
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
Добрый день. Можно ли сделать такой список из гиперссылок на листы? Щелкнул список, выбрал название листа - и оказался на нем. Желательно без макросов. Названия листов в список можно и руками вбить и изредка откорректировать, необязательно их макросом собирать.
12.11.2025 17:54:33
Добрый день! Безусловно, очень полезный макрос! Единственное, что огорчает, так это то, что вся эта конструкция теряет смысл без автоподстановки! Если список большой, то вбить значение ручками получится быстрее, чем искать его в списке без автоподстановки, да еще и без возможности увеличения шрифта в данном списке, хотя бы до размера шрифта в ячейке! Интересно, что в онлайн версии автоподстановка работает. Я думал, что в "Excel" такие фишки в порядке вещей, а оказывается, все нужно допиливать! Чем там разработчики занимались двадцать лет?!
Страницы: 1  2  3  
Наверх