Мгновенная фильтрация на лету

Представьте, что вам часто приходится фильтровать одну и ту же таблицу по одному или (что гораздо хуже) нескольким столбцам, в попытках найти там частичное совпадение с заданным текстом. Например, вот в такой таблице с данными о доставках находить людей по фамилии или имени, причем нужный человек может оказаться как в столбце Отправитель, так и Получатель:

Исходный список для фильтрации

Само собой, можно включить классический фильтр через Данные - Фильтр (Data - Filter), развернуть выпадающий список в столбце Отправитель и ввести имя требуемого человека в поле поиска, но ведь потом придётся куда-то скопировать результаты, очистить фильтрацию и повторить поиск ещё раз в столбце Получатель. А если столбцов для поиска будет не 2, а больше? Тоска зелёная, правда?

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

Добавляем текстовое поле ввода ActiveX

Во-первых, давайте конвертируем нашу исходную таблицу в динамическую "умную", используя сочетание клавиш Ctrl+T или команду Главная - Форматировать как таблицу (Home - Format as Table). Это не обязательно, но упростит нам дальнейшую работу и написание формул.

Во-вторых, для вставки текстового поля и последующей его настройки нам потребуется вкладка Разработчик (Developer). Если у вас её не видно, то щёлкните правой кнопкой мыши по любому месту ленты и выберите команду Настройка ленты (Customize ribbon), а затем включите соответствующий флажок.

После этого разверните выпадающий список Вставить (Insert) и выберите оттуда текстовое поле из блока ActiveX (не перепутайте с похожим полем из блока Элементы управления формы):

Вставка элемента ActiveX

Нарисуйте поле ввода в любом удобном месте. Если при этом удерживать нажатой клавишу Alt, то рисование будет происходить ровно по границам ячеек.

 !  Если при вставке поля у вас возникает сообщение об ошибке, то возможно у вас отключены элементы ActiveX по настройкам безопасности. Чтобы их разрешить выберите Файл - Параметры - Центр управления безопасностью - Параметры центра управления безопасностью - Параметры ActiveX (File - Options - Trust Center - Trust Center options - ActiveX settings)

Теперь щёлкните правой кнопкой мыши по нарисованному полю и выберите команду Свойства (Properties) - откроется панель со списком всех настроек, которые есть у этого элемента. Здесь можно, при желании, поменять его дизайн (параметры BackColor, BorderColor, Font), ограничить длину вводимого текста (параметр MaxLenght) и т.д. Но главное свойство, которое нас интересует - это связанная ячейка (LinkedCell): 

Панель свойств

Введите в это поле адрес любой свободной ячейки (например A1) и нажмите Enter. Панель свойств после этого можно закрыть.

Чтобы протестировать как работает наше текстовое поле ввода, нам нужно переключиться из режима конструктора (т.е. режима разработки, где мы сейчас находимся) в рабочий режим. Для этого необходимо отжать соответствующую кнопку на вкладке Разработчик:

Кнопка режима конструктора

Теперь при вводе любых символов в поле они будут передаваться в связанную ячейку, причем - мгновенно, без дополнительных нажатий на Enter или щелчков мышью, как это бывает при вводе в ячейку с клавиатуры или использовании фильтра. А значит Excel будет автоматически запускать на листе пересчёт формул, которыми мы дальше и воспользуемся для фильтрации.

Фильтруем нужные строки

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

Если у вас Excel версии 2021 или новее, то всё просто - достаточно использовать новую функцию ФИЛЬТР для решения этой задачи. Для начала давайте проверим отправителя:

Ищем отправителей

Первый аргумент функции ФИЛЬТР - это фильтруемый массив, т.е. наша исходная таблица Заказы

Второй аргумент - это критерий отбора, т.е. формула, возвращающая логические значения ИСТИНА или ЛОЖЬ, определяющие нужно ли включать очередную строку в результаты фильтрации. Здесь мы проверяем, входит ли подстрока из А1 в отправителя с помощью функции ПОИСК (SEARCH), которая возвращает либо число - порядковый номер символа, начиная с которого текст был найден, либо ошибку - если искомая подстрока в тексте не содержится. Этот факт мы проверяем с помощью функции ЕЧИСЛО (ISNUMBER) и используем как критерий для отбора нужных строк.

Чтобы выполнять поиск не по одному, а сразу по нескольким столбцам, проще всего склеить их значения в общую строку, используя символ сцепки & и любой подходящий символ как разделитель (например, дефис или подчеркивание). Так можно легко добавить в формулу проверку не только отправителя, но и получателя одновременно:

Добавляем получателя в поиск

После этого ввод любого фрагмента текста в наше поле ActiveX приведёт к изменению ячейки А1, что, в свою очередь, вызовет пересчёт формул и обновление результатов фильтрации на лету. 

Заодно можно легко посчитать количество найденных строк, используя функцию ЧСТРОК (ROWS) и ссылку на весь динамический массив с результатами фильтрации, начинающийся с ячейки B5:

Считаем количество найденных строк

Для перехвата ошибки #ВЫЧИСЛ! в тех случаях, когда введённый текст не найден ни в одной строке данных, можно использовать третий аргумент функции ФИЛЬТР:

=ФИЛЬТР(Заказы ; ЕЧИСЛО(ПОИСК(A1;Заказы[Отправитель]&"-"&Заказы[Получатель])) ; "нет данных")

Если нет функции ФИЛЬТР

Если вы используете старые версии Excel (2019 или древнее), где ещё не было функции ФИЛЬТР (FILTER), то для отбора нужных строк придётся действовать похитрее.

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

Во-вторых, формула для фильтрации нужных строк только будет выглядеть так:

Отбираем строки без функции ФИЛЬТР

Здесь:

  1. Функция ЕСЛИ (IF) проверяет вхождение фрагмента из ячейки А1 в имя отправителя с помощью функций ПОИСК (SEARCH) и ЕЧИСЛО (ISNUMBER) и возвращает номер строки в таблице, где вхождение было найдено. Номер строки нам даёт функция СТРОКА (ROW), результат которой мы уменьшаем на 4, т.к. над таблицей у нас 3 пустых строки плюс шапка.
  2. Функция НАИМЕНЬШИЙ (SMALL) последовательно выдаёт все номера строк, где было найдено совпадение.
  3. Функция ИНДЕКС (INDEX) извлекает данные по очереди из каждого столбца таблицы по номерам строк, которые выдала функция НАИМЕНЬШИЙ.
  4. Поскольку мы заранее не можем знать, сколько именно совпадений найдется, то эту формулу (и нумерацию слева) придётся протянуть вниз с запасом. Чтобы на лишних строчках не появлялась ошибка - заворачиваем всю нашу эпическую формулу в функцию ЕСЛИОШИБКА (IFERROR).

Бонус

Вдогон к удобной мгновенной фильтрации бонусом идёт ещё один момент. Дело в том, что функция ПОИСК (SEARCH) поддерживает спецсимволы * (звездочка - любое количество любых символов) и ? (вопросительный знак - один любой символ). Соответственно, мы спокойно можем использовать их в поле ввода и искать не просто вхождение текста, а более сложные случаи. Например, запрос М*А найдет нам все фрагменты, начинающиеся на "М" и заканчивающиеся на "А", т.е. Марину, Машу, Милену, Максима и т.п. Мелочь, а приятно.

Также учтите, что функция ПОИСК не чувствительна к регистру. Если нужно искать строго с учётом регистра, то её можно заменить на аналогичную функцию НАЙТИ (FIND).

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



Спасибо.
В 'Без функции ФИЛЬТР'!E2 всё же =СУММПРОИЗВ(--(B5:B1000<>"")).
28.03.2025 10:10:14
О да, спасибо! :like:
30.05.2025 12:10:45
Или просто Сумм в Е2: =СУММ(--(B5:B1000<>""))
27.03.2025 10:12:52
Очень полезная штука и в моём случае как нельзя кстати!
Огромная благодарность!!!

Отдельное спасибо за, и, восхищение даром лаконичного, доходчивого повествования!!!
28.03.2025 10:10:24
Спасибо! :)
Очень полезная информация!  И как нельзя вовремя : как раз задумывалась на днях о реализации такой фильтрации в своем стареньком экселе на работе. Спасибо за подробное изложение.
28.03.2025 09:37:35
Забавно у меня все добавляется но в само поле написать ничего нельзя а если пишешь в A1 то в поле этом инфа копируется , то есть наоборот походу работает
28.03.2025 10:09:51
А режим Конструктора выключен?
28.03.2025 10:37:42
да, я еще раз протестил: в этом поле нельзя поставить курсор - когда пишешь там вслепую то в A1 текст сразу дублируется  а в этом поле текст  появляется если щелкнуть по другой ячейки
28.03.2025 12:45:21
А вы случайно текстовое поле из Элементов управления формы не вставили вместо поля из раздела ActiveX?
28.03.2025 14:52:29
сейчас повторил все тоже самое и заработало, уверен до этого тоже вставлял  из ActiveX
28.03.2025 14:58:59
кстати в свойствах можно настроить размер шрифта в этом поиске? - почему то нигде не нашел , сам шрифт есть , цвет есть  а размера нет
30.03.2025 18:11:17
Спасибо, Николай! Очень нравится смотреть Ваши уроки и быть в курсе Ваших изысканий на планете Эксель! 😀
Доброго дня! Очень здорово, но есть момент, например Арина, она же Карина, Дарина, Ларина
03.04.2025 08:28:44
Само собой - мы же ищем вхождение введённого текста в любом месте ФИО. Как вариант, можно искать с учётом регистра - тогда используйте вместо функции ПОИСК функцию НАЙТИ.
Благодарю за инструмент! А подскажите как прописать, чтобы учитывались в поиске и фильтрации все поля, кроме указанного в поле ввода?
23.05.2025 16:52:26
СПАСИБО огромное!!!! Но все же есть допополнительный вопрос . Для примера , есть столбец с номерами накладных от 1 до 15000.
И я делаю  отдельный фильтр конкретно на 1 столбец. Ищу накладную 31 , в итоге получаю список всех накладных , в которых есть сочетание 31 (31,131,231 и тд).
Суть вопроса , какую функцию можно внедрить чтоб при вводе числа 31 фильтр выдал список только с накладной 31?

На листе созданы 2 поля ввода для фильтра посредством одной формулы для одной и той же таблицы.

=ФИЛЬТР(Таблица1;ЕЧИСЛО(ПОИСК(B2;Таблица1[Цена]&"-"&Таблица1[Серийный номер]&"-"&Таблица1[Название]&"-"&Таблица[От кого];ПОИСК(J2;Таблица1[Накладная]&"-"&Таблица1[Номер документа])));"НЕТ данных")

Все работает как надо , но в случае 1-го фильтра ,в котором склеяно большенство столбцов , все устраивает . А вот во втором есть необходимость искать строго вводимые значения.
24.06.2025 18:02:22
Попробуйте так:

=ЕСЛИ($C$5="";
                            ЕСЛИ($C$2="";
                            ФИЛЬТР(Заказы;ЕЧИСЛО(ПОИСК($C$4;Заказы[Отправитель]&"-"&Заказы[Получатель]&"-"&Заказы[Стоимость]));"Нет данных");
                            ФИЛЬТР(Заказы;ЕЧИСЛО(ПОИСК($C$4;ДВССЫЛ("Заказы["&$C$2&"]")));"Нет данных"));
ФИЛЬТР(Заказы;Заказы[Код]=$C$5;"Код не найден"))

Немного расширил функционал поиска, т.к. полей для поиска в моих таблицах больше чем две.
Добавил возможность выбора полей поиска отдельно сохранив возможность поиска по всем полям таблицы кроме поля "Код". А также добавил точный поиск по полю "Код". К сожалению поиск точного совпадения, через единое поле не получается: ActiveX возвращает текст, а ФИЛЬТР его не распознает как число. Поэтому пришлось добавить приоритетное поле для точного поиска по полю "Код".

С5 - ячейка для поиска по "Коду"
С2 - Выпадающий список полей таблицы (Отправитель, Получатель, Стоимость)
С полем AcviveX связана ячейка С4
Наверх