Все, кто сталкивался с функцией ВПР знают, что она умеет возвращать исключительно одно значений - первое найденное. Но что делать, когда надо видеть все значения? К примеру имеется такая таблица:
И из этой таблицы необходимо получить фамилии(поле ФИО) всех сотрудников из отдела Сбыта:
Тут два варианта:
Вариант 1: все значения необходимо получить в одной ячейке через разделитель(скажем запятую). Как и при помощи каких функций и инструментов это можно сделать я описывал детально в статье: Как сцепить несколько значений в одну ячейку по критерию? СцепитьЕслиВариант 2: каждое значение должно быть в отдельной ячейке. Этот вариант мы и рассмотрим более подробно в данной статье. Причем решать задачу будем без использования макросов - только встроенными функциями
. В результате получим что-то вроде:
Здесь надо сразу оговориться - при помощи непосредственно ВПР
Решение очень простое - использовать функцию динамических массивов
Аргументы функции:
- диапазон, в котором записаны все фамилииA12:A111 - диапазон с названиями отделовC12:C111 - критерий. Значение, на основании которого необходимо отбирать значения. В данном случае значение просматривается в столбце с отделами(I12 )C12:C111
Работа функции предельно проста: первым аргументом мы указываем столбец или таблицу, которые необходимо отфильтровать на основании условия. Само условие задается вторым аргументом в виде сравнения, примерно как в функции
А тем, у кого не самая "продвинутая" версия Excel, придется делать все это при помощи родственников функции ВПР - связки ИНДЕКС(ПОИСКПОЗ)
где:
- таблица с ФИО и всеми данными$A$12:$G$111 - ячейка с названием отдела$I$12 - столбец с названиями отделов в таблице$C$12:$C$111 $A$12:$G$111
Предлагаю сразу
Tips_All_VlookupAllVals.xls (84,5 КиБ, 27 125 скачиваний)
- Первое и самое главное - формула вводится в ячейку как формула массива. Это значит, что для приложенного к статье примера необходимо будет выделить ячейку
, записать в неё формулу и завершить ввод нажатием сразу трех клавиш: Ctrl+Shift+Enter. После этого скопировать ячейку, выделить диапазонJ12 и вставить туда скопированную ячейку.J13:J39 - За отбор ФИО указанного отдела отвечает этот кусок:
ЕСЛИ( $I$12 =$C$12:$C$111 ;СТРОКА($C$12:$C$111 )-11)
IF($I$12=$C$12:$C$111;ROW($C$12:$C$111)-11)
Как видно здесь идет сравнение отдела, записанного в со всеми отделами в таблице:$I$12 . Если отдел совпадает, то функция возвращает номер строки$C$12:$C$111 СТРОКА( . Но нам нужен не номер строки на листе, а номер строки внутри таблицы(потому что в формулу ИНДЕКС$C$12:$C$111 )(INDEX) у нас передан диапазон и если передать в его второй аргумент($A$12:$G$111 номер_строки ) 14, то получим неАлександров Иван , аАндреев Олег ). Поэтому отнимаем от номера строки 11, чтобы было возвращено число 3(а не 14). Т.к. формула записана формулой массива -ЕСЛИ возвращает массив из номеров строк и логического(IF) ЛОЖЬ (если отдел не совпадает):(FALSE)
шаг 1: ЕСЛИ({ЛОЖЬ:ЛОЖЬ:ИСТИНА :ЛОЖЬ:ЛОЖЬ:ИСТИНА :ЛОЖЬ:ЛОЖЬ:ЛОЖЬ};{12:13:14 :15:16:17 :18:19:20}-11)
шаг 2: ЕСЛИ({ЛОЖЬ:ЛОЖЬ:ИСТИНА :ЛОЖЬ:ЛОЖЬ:ИСТИНА :ЛОЖЬ:ЛОЖЬ:ЛОЖЬ};{1:2:3 :4:5:6 :7:8:9})
шаг 3: {ЛОЖЬ:ЛОЖЬ:3 :ЛОЖЬ:ЛОЖЬ:6 :ЛОЖЬ:ЛОЖЬ:ЛОЖЬ} - Т.к.
ЕСЛИ в данном случае возвращает массив значений, включая ненужные нам(IF) ЛОЖЬ - применяем(FALSE) НАИМЕНЬШИЙ , которая будет брать только числа (сначала 3, затем 6 и т.д.), а логические значения(SMALL) ЛОЖЬ будет игнорировать:(FALSE)
НАИМЕНЬШИЙ({ЛОЖЬ:ЛОЖЬ: 3 :ЛОЖЬ:ЛОЖЬ:6 :ЛОЖЬ:ЛОЖЬ:ЛОЖЬ};СТРОКА(A1))
SMALL({ЛОЖЬ:ЛОЖЬ: 3 :ЛОЖЬ:ЛОЖЬ:6 :ЛОЖЬ:ЛОЖЬ:ЛОЖЬ};ROW(A1))
ФункцияНАИМЕНЬШИЙ отбирает из указанного массива чисел наименьшее. При этом можно отобрать по рангу - первое наименьшее, второе наименьшее, третье наименьшее и т.д.(SMALL) - с первым аргументом разобрались - это уже отобранные записи, где число - строка в таблице с нужной ФИО и ненужные нам логические
ЛОЖЬ .(FALSE) - второй аргумент
СТРОКА(A1) для каждой следующей строки будет меняться. В приложенном примере первая ячейка с формулой - . В нейJ12 СТРОКА(A1) равна 1, т.е.НАИМЕНЬШИЙ вернет первое наименьшее из массива чисел -(SMALL) 3 . В ячейке это уже будетJ13 СТРОКА(A2) и она равна 2, а значитНАИМЕНЬШИЙ вернет второе наименьшее из массива чисел -(SMALL) 6 . И т.д. Когда все числа закончатся -НАИМЕНЬШИЙ вернет значение ошибки(SMALL) #ЧИСЛО! (#NUM!)
ячейка J12
шаг 1: НАИМЕНЬШИЙ({ЛОЖЬ:ЛОЖЬ:3 :ЛОЖЬ:ЛОЖЬ:6 :ЛОЖЬ:ЛОЖЬ:ЛОЖЬ};СТРОКА(A1))
шаг 2: НАИМЕНЬШИЙ({ЛОЖЬ:ЛОЖЬ:3 :ЛОЖЬ:ЛОЖЬ:6 :ЛОЖЬ:ЛОЖЬ:ЛОЖЬ};1)
шаг 3: НАИМЕНЬШИЙ(3 )
ячейка J13
шаг 1: НАИМЕНЬШИЙ({ЛОЖЬ:ЛОЖЬ:3 :ЛОЖЬ:ЛОЖЬ:6 :ЛОЖЬ:ЛОЖЬ:ЛОЖЬ};СТРОКА(A2))
шаг 2: НАИМЕНЬШИЙ({ЛОЖЬ:ЛОЖЬ:3 :ЛОЖЬ:ЛОЖЬ:6 :ЛОЖЬ:ЛОЖЬ:ЛОЖЬ};2)
шаг 3: НАИМЕНЬШИЙ(6 )
- с первым аргументом разобрались - это уже отобранные записи, где число - строка в таблице с нужной ФИО и ненужные нам логические
- И последний штрих - все это передается в функцию
ИНДЕКС . Для ячейки(INDEX) это будет значение ячейки, расположенной на пересечении 3-й строки и 1-го столбца диапазонаJ12 . На листе это ячейка$A$12:$G$111 . Т.е. третья сверху ячейка столбца А в диапазонеA14 -$A$12:$G$111 Александров Иван .
ячейка J12
шаг 1: =ИНДЕКС($A$12:$G$111 ;НАИМЕНЬШИЙ(3 );1)
шаг 2: =ИНДЕКС($A$12:$G$111 ;3;1)
шаг 3: Александров Иван
ячейка J13
шаг 1: =ИНДЕКС($A$12:$G$111 ;НАИМЕНЬШИЙ(6 );1)
шаг 2: =ИНДЕКС($A$12:$G$111 ;6;1)
шаг 3: Александров Петр
И в довершение неплохо бы убрать ошибку в случае, если ни одно значение не соответствует критерию или значений больше, чем ячеек с формулами. Более подробно подобное решение я описывал в этой статье: Как в ячейке с формулой вместо ошибки показать 0
Плюс к этому в приложенном к статье файле я привел формулу, которая возвращает список всех сотрудников выбранного отдела без повторений и формулу с возможностью просто поменять заголовок в результирующем столбце(в файле это столбец K, ячейка
Например, если вместо столбца
Tips_All_VlookupAllVals.xls (84,5 КиБ, 27 125 скачиваний)
Так же см.:
Как найти значение в другой таблице или сила ВПР
ВПР с поиском по нескольким листам
ВПР_МН
Огромное спасибо! Очень нужно! Возможно стоит дополнительные теги приписать)
Добрый день!
А можно ли в указанной формуле использовать несколько условий для отбора?
Скажем, нужно отобрать фамилии(поле ФИО) всех сотрудников из отдела Сбыта у которых оклад 16000р.?
Добрый день. Не могли бы вы прокомментировать формулу, в которой избавляемся от повторов? Что значит <code class="ЕСЛИ(($I$12=$C$12:$C$111)*(СЧЁТЕСЛИ($L$11:L13;$A$12:$A$111)=0"?
Дмитрий, а где в статье Вы нашли этот кусок? Вы точно там разместили комментарий?
Вариант 1 очень помог! Спасибо большое! :)
Добрый день, а как сложить несколько повторяющихся значений, т.е. у меня в первом столбце фамилии несколько раз повторяющиеся, а во втором цифры, которые нужно сложить для каждой фамилии.
Елена, вот здесь то, что Вам нужно:Функция СУММЕСЛИ, а так же СУММЕСЛИ по двум критериям
Попробовал, пока не понял/не понравилось, что если сначала протянуть формулу сверху вниз, взяв данные с другого листа (кстати, работает), но потом - дозаполнить таблицу данных, то есть - добавить еще одну строку, где критерий отбора оказывается выполненным - у меня эти данные в итоговый вывод не добавились, словно я ничего не добавлял. Или есть какая-то хитрость для обновления? В остальном работа функции понравилась.
Владимир, думаю, Вам лучше обратитьсяна форум , создав новую тему и приложив файл-пример данных, чтобы можно было понять проблему. По одному описанию невозможно понять, почему формула не видит новые данные. Возможно, неверно указан диапазон поиска, возможно, пересчет формул отключен, а может и иная причина.
Доброго дня! Могли бы подсказать как эту формулу прописать в пользовательской функции?
=INDEX($A$12:$G$111;SMALL(IF($I$12=$C$12:$C$111;ROW($C$12:$C$111)-11);ROW(A1));1)
"Индекс" и "наименьший" - превратил в Application.WorksheetFunction.INDEX/SMALL
А вот "если" и "строка" - не могу понять как преобразовать.
В пользовательской функции можно использовать встроенные конструкции IF и свойство диапазона Row.
Есть третий вариант для новых версий Ексель - функции Объединить + Фильтр.
Фильтром получаем список записей, и объединяем в строку с заданным разделителем.