Содержание
- Функция ИНДЕКС в Excel и примеры ее работы с массивами данных
- Как работает функция ИНДЕКС в Excel?
- Функция ИНДЕКС в Excel пошаговая инструкция
- Описание примера как работает функция ИНДЕКС
- Примеры функции ИНДЕКС с пошаговой инструкцией скачать в Excel
- Пример работы функции ИНДЕКС в Excel от простого к сложному
- Функция ИНДЕКС двумерный и многомерный массив
- Пример формулы комбинации функций ИНДЕКС и СУММ
- Формула ИНДЕКС и ПОИСКПОЗ лучшая замена функции ВПР
- Функция ИНДЕКС в программе Microsoft Excel
- Использование функции ИНДЕКС
- Способ 1: использование оператора ИНДЕКС для массивов
- Способ 2: применение в комплексе с оператором ПОИСКПОЗ
- Способ 3: обработка нескольких таблиц
- Способ 4: вычисление суммы
Функция ИНДЕКС в Excel и примеры ее работы с массивами данных
Функция ИНДЕКС предназначена для выборки значений из таблиц Excel по их координатам. Ее особенно удобно использовать при работе с базами данных. Данная функция имеет несколько аналогов, такие как: ПОИСКПОЗ, ВПР, ГПР, ПРОСМОТР, с которыми может прекрасно сочетаться в сложных формулах. Но все же гибкость и простота в этой функции на первом месте.
Как работает функция ИНДЕКС в Excel?
Допустим мы работаем с большой таблицей данных с множеством строк и столбцов. Первая строка данной таблицы содержит заголовки столбцов. А в первом столбце соответственно находиться заголовки строк. Пример такой таблицы изображен ниже на рисунке:
Задача следующая: необходимо определить какое числовое значение относится к конкретному отделу и к конкретной статьи. Другими словами, необходимо получить значение ячейки на пересечении определенного столбца и строки.
Функция ИНДЕКС в Excel пошаговая инструкция
- Ниже таблицы данный создайте небольшую вспомогательную табличку для управления поиском значений:
- В ячейке B12 введите номер необходимого отдела, который потом выступит в качестве критерия для поискового запроса. Например, 3.
- В ячейке B13 введите номер статьи. Например, 7.
- В ячейку B14 введите следующую формулу:
В результате получаем значение на пересечении столбца 3 и строки 7:
Как видно значение 40 имеет координаты Отдел №3 и Статья №7. При этом функцией ИНДЕКС не учитываются номера строк листа Excel, а только строки и столбцы таблицы в диапазоне B2:G10.
Описание примера как работает функция ИНДЕКС
В первом аргументе функции указывается диапазон ячеек таблицы, по которому будет выполнен поиск значений на пересечении строк и столбцов. Во втором аргументе сначала указываем номер строки, а потом в третьем аргументе – номер столбца. На основе этой информации функция ищет соответствующее значение в таблице.
Внимание! Для функции ИНДЕКС номера строк и столбцов определяют высоту и ширину таблицы, указанной в ее первом аргументе. Они никак не связаны с номерами рабочего листа Excel и не обязаны соответствовать им.
Источник
Примеры функции ИНДЕКС с пошаговой инструкцией скачать в Excel
Функция ИНДЕКС помогает извлекать значение из массива данных. Массив может различаться своей структурой, количеством столбцов и строк и даже количество самих массивов может быть больше одного.
Пример работы функции ИНДЕКС в Excel от простого к сложному
Сначала рассмотрим самый простой пример применения. У нас есть несколько городов. Пусть нашей первой задачей будет извлечь пятый по счету город из нашей одномерной базы данных. Синтаксис нашей формулы будет следующий: ИНДЕКС(массив; номер_строки). Начинаем писать формулу (яч. B9). Первый аргумент – это все города B3:C7, а второй – необходимый нам номер ряда, в котором хранится информация, которую мы хотим получить – пятый город:
Функция возвратила значение с второго ряда нашей таблицы. Теперь дополним нашу таблицу информацией о туристах, посетивших город в 2017 году:
Для дальнейшего ознакомления работы функции расширим задачу до двухмерного массива исходных данных.
Функция ИНДЕКС двумерный и многомерный массив
Теперь наш массив двухмерный. Пусть теперешним заданием будет узнать количество туристов в Ливерпуле. В ячейке B19 пишем формулу. Синтаксис тоже видоизменится: ИНДЕКС(массив; номер_строки; номер_столбца), у нас добавится третий аргумент – номер столбца, в котором хранится нужные нам данные:
Аналогично функция работает с трёхмерными массивами, четырёхмерными и так далее. Теперь давайте рассмотрим, как решать задачи, когда таблиц несколько. Пусть у нас будут города трёх стран с количеством посетителей:
На этот раз у нас три двумерные таблицы – три страны с различными городами и их посетителями. Нам необходимо найти количество туристов в городе Ницца страны Франции или, если перефразировать под наш синтаксис, количество посетителей третьего ряда второй колонки второй таблицы. Первым делом, как и раньше, нам нужно выбрать диапазон. НО теперь их у нас три, а значит, все три мы и выбираем, предварительно взяв в скобки эту часть синтаксиса. После чего добавляем уже знакомые нам координаты искомой информации – строку и столбец, а также номер таблицы, которая содержит искомый нами диапазон:
И получаем готовую формулу с решением поставленной задачи:
Пример формулы комбинации функций ИНДЕКС и СУММ
Функцию ИНДЕКC так же можно комбинировать и с другими функциями. Например, наша база данных содержит дополнительно количество туристов Великобритании за 2018-2019 года, мы хотим узнать сумму туристов:
- за 2018 год.
- по городу Манчестер за весь период.
В этом нам поможет известная любому пользователю несложная функция СУММ. Она охватит результат поиска, сделанным ИНДЕКC и выполнит операцию сложения найденных значений. Чтобы выполнить первую задачу, для начала нам нужно выбрать диапазон с одними числами(без столбца с городами, поскольку будем суммировать численные значения C43:E47). Затем на месте, где мы прописывали номер строки, пишем 0. Благодаря этому ИНДЕКC не будет «искать» данные по строкам, а просто перейдет к следующей операции. А следующая операция – прописываем столбец 2 и получаем ответ на первый пункт:
Сумма туристов за 2018 год по пяти городам Великобритании составляет 40 987 людей.
Аналогично этой схеме мы ищем ответ на второй пункт. Только теперь нам нужно считать данные с ряда, поэтому ноль ставим на месте номера столбца:
И получаем ответ на второй пункт – всего посетителей за три года в Манчестере было 2 474 человека.
Для примера зачастую используются самые простые задачи и однотипные решения через функцию. Но в работе объем данных всегда больше и сложнее, поэтому для решения таких заданий используют несколько функций или их сочетание. Несколько таких примеров будем рассматривать дальше.
Формулировку функции можно видоизменять в зависимости от постановки задачи. Пусть нам нужно определить и показать сколько туристов вместе было в 2017-м году в первых трёх городах по списку – Кембридже, Манчестере и Лондоне. Тогда мы снова используем функцию СУММ, но в месте, где указывается конец диапазона значений, по которым мы проводим поиск, вставляем нашу ИНДЕКС. Проще говоря, диапазон для суммирования выглядит так: (начало:конец). Началом будет первая ячейка массива, как обычно, а конец мы заменим. Укажем количество городов, по которым будем считать людей (действие 1). Затем, когда будем составлять функцию ИНДЕКC, укажем, что первый аргумент – числовой диапазон всех пяти городов за 2017-й год, а второй – наше кол-во городов (ячейка D64):
Точно так же можно выполнить следующее задание: найти сумму посетителей Оксфорде за 2017-2018 года. В этом случае делаем всё точно так же, только выбираем горизонтальный диапазон C61:E61 :
В конце необязательно ссылаться на ячейку с написанным количеством искомых значений, можно сразу писать цифру 3 в первом примере и цифру 2 во втором примере, всё будет работать точно так же:
Комбинирование нескольких функций могут делать то же, что и одна отдельная функция, но при этом быть менее требовательными к расположению данных, к их размерам или количеству.
Формула ИНДЕКС и ПОИСКПОЗ лучшая замена функции ВПР
Существуют весьма весомые аргументы преимущества использования формулы ИНДЕКС и ПОИСКПОЗ в Excel лучше, чем функция ВПР. Если вы уже знакомы с функцией ВПР, то наверняка знаете, что для её корректной работы искомые данные всегда должны располагаться по правую сторону от критериев:
Получается, что для работы сначала нужно упорядочить столбцы в соответствии с требованиями, а только потом совершать действия. Но иногда сама структура отчета или сводки, с которой нам нужно иметь дело, не позволяет совершать перестановки. Тогда нам очень кстати пригодится ИНДЕКС в сочетании с функцией ПОИСКПОЗ. Синтаксис ИНДЕКСА: (массив; номер_строки; номер_столбца). На первой позиции у нас будет диапазон значений (туристы, 2017), вместо следующих двух пишем ПОИСКПОЗ (искомый критерий;диапазон критериев; 0 (для точного результата)):
Рассмотрим более наглядный и реальный пример, где можно заменить ВПР. У нас есть два отчета: один — о количестве продаж определенного товара, а второй – о цене на упаковку одного товара. И как раз вторая таблица имеет такое расположение столбцов, которое не позволяет использовать нам ВПР – первыми занимают место значения, а вторыми – критерии:
Для того чтобы выполнить заполнение первой таблицы, делаем точно также, как в предыдущем примере – в ячейке D88 пишем ИНДЕКС, первым делом указываем столбец, где находятся искомые значения (цена за упаковку). Затем нужно указать, где нам искать соответствующие критерию значения — подстраиваем ПОИСКПОЗ под наше решение: выбираем искомый критерий (Хепилор), затем массив искомых критериев со второй таблицы:
Теперь просто копируем формулу до конца столбца, но не забываем закрепить ссылки, иначе массив будет спускаться дальше и мы получим некорректные значения. Наша таблица готова:
Если у нас нет данных во второй таблице о цене и препаратах, у нас будет в ячейке ошибка #Н/Д. Теперь к нашим ранее использованным функциям добавим ЕСЛИОШИБКА, которая нам поможет изменить внешний вид отчета, сделать его более понятным для читателя. Опять же, поскольку у нас вторая таблица не соответствует требованиям ВПР, на помощь приходит ИНДЕКС+ПОИСКПОЗ. Усложняем уже имеющуюся формулу, добавляя ЕСЛИОШИБКА, указывая, что при отсутствии данных, мы хотим видеть прочерк:
Таким образом формула из комбинации функций ИНДЕКС и ПОИСПОЗ работают лучше популярной функции ВПР и не имеют никаких ограничений для выборки данных из таблицы даже по нескольким условиям.
Источник
Функция ИНДЕКС в программе Microsoft Excel
Одной из самых полезных функций программы Эксель является оператор ИНДЕКС. Он производит поиск данных в диапазоне на пересечении указанных строки и столбца, возвращая результат в заранее обозначенную ячейку. Но полностью возможности этой функции раскрываются при использовании её в сложных формулах в комбинации с другими операторами. Давайте рассмотрим различные варианты её применения.
Использование функции ИНДЕКС
Оператор ИНДЕКС относится к группе функций из категории «Ссылки и массивы». Он имеет две разновидности: для массивов и для ссылок.
Вариант для массивов имеет следующий синтаксис:
При этом два последних аргумента в формуле можно использовать, как вместе, так и любой один из них, если массив одномерный. При многомерном диапазоне следует применять оба значения. Нужно также учесть, что под номером строки и столбца понимается не номер на координатах листа, а порядок внутри самого указанного массива.
Синтаксис для ссылочного варианта выглядит так:
Тут точно так же можно использовать только один аргумент из двух: «Номер строки» или «Номер столбца». Аргумент «Номер области» вообще является необязательным и он применяется только тогда, когда в операции участвуют несколько диапазонов.
Таким образом, оператор ищет данные в установленном диапазоне при указании строки или столбца. Данная функция своими возможностями очень похожа на оператора ВПР, но в отличие от него может производить поиск практически везде, а не только в крайнем левом столбце таблицы.
Способ 1: использование оператора ИНДЕКС для массивов
Давайте, прежде всего, разберем на простейшем примере алгоритм использования оператора ИНДЕКС для массивов.
Имеем таблицу зарплат. В первом её столбце отображены фамилии работников, во втором – дата выплаты, а в третьем – величина суммы заработка. Нам нужно вывести имя работника в третьей строке.
- Выделяем ячейку, в которой будет выводиться результат обработки. Кликаем по значку «Вставить функцию», который размещен сразу слева от строки формул.
- Происходит процедура активации Мастера функций. В категории «Ссылки и массивы» данного инструмента или «Полный алфавитный перечень» ищем наименование «ИНДЕКС». После того, как нашли этого оператора, выделяем его и щелкаем по кнопке «OK», которая размещается в нижней части окна.
- Открывается небольшое окошко, в котором нужно выбрать один из типов функции: «Массив» или «Ссылка». Нужный нам вариант «Массив». Он расположен первым и по умолчанию выделен. Поэтому нам остается просто нажать на кнопку «OK».
В поле «Массив» нужно указать адрес обрабатываемого диапазона данных. Его можно вбить вручную. Но для облегчения задачи мы поступим иначе. Ставим курсор в соответствующее поле, а затем обводим весь диапазон табличных данных на листе. После этого адрес диапазона тут же отобразится в поле.
В поле «Номер строки» ставим цифру «3», так как по условию нам нужно определить третье имя в списке. В поле «Номер столбца» устанавливаем число «1», так как колонка с именами является первой в выделенном диапазоне.
После того, как все указанные настройки совершены, щелкаем по кнопке «OK». 
Мы разобрали применение функции ИНДЕКС в многомерном массиве (несколько столбцов и строк). Если бы диапазон был одномерным, то заполнение данных в окне аргументов было бы ещё проще. В поле «Массив» тем же методом, что и выше, мы указываем его адрес. В данном случае диапазон данных состоит только из значений в одной колонке «Имя». В поле «Номер строки» указываем значение «3», так как нужно узнать данные из третьей строки. Поле «Номер столбца» вообще можно оставить пустым, так как у нас одномерный диапазон, в котором используется только один столбец. Жмем на кнопку «OK».
Результат будет точно такой же, что и выше.
Это был простейший пример, чтобы вы увидели, как работает данная функция, но на практике подобный вариант её использования применяется все-таки редко.
Способ 2: применение в комплексе с оператором ПОИСКПОЗ
На практике функция ИНДЕКС чаще всего применяется вместе с аргументом ПОИСКПОЗ. Связка ИНДЕКС – ПОИСКПОЗ является мощнейшим инструментом при работе в Эксель, который по своему функционалу более гибок, чем его ближайший аналог – оператор ВПР.
Основной задачей функции ПОИСКПОЗ является указание номера по порядку определенного значения в выделенном диапазоне.
Синтаксис оператора ПОИСКПОЗ такой:
=ПОИСКПОЗ(искомое_значение, просматриваемый_массив, [тип_сопоставления])
- Искомое значение – это значение, позицию которого в диапазоне мы ищем;
- Просматриваемый массив – это диапазон, в котором находится это значение;
- Тип сопоставления – это необязательный параметр, который определяет, точно или приблизительно искать значения. Мы будем искать точные значения, поэтому данный аргумент не используется.
С помощью этого инструмента можно автоматизировать введение аргументов «Номер строки» и «Номер столбца» в функцию ИНДЕКС.
Посмотрим, как это можно сделать на конкретном примере. Работаем все с той же таблицей, о которой шла речь выше. Отдельно у нас имеется два дополнительных поля – «Имя» и «Сумма». Нужно сделать так, что при введении имени работника автоматически отображалась сумма заработанных им денег. Посмотрим, как это можно воплотить на практике, применив функции ИНДЕКС и ПОИСКПОЗ.
- Прежде всего, узнаем, какую заработную плату получает работник Парфенов Д. Ф. Вписываем его имя в соответствующее поле.
- Выделяем ячейку в поле «Сумма», в которой будет выводиться итоговый результат. Запускаем окно аргументов функции ИНДЕКС для массивов.
В поле «Массив» вносим координаты столбца, в котором находятся суммы заработных плат работников.
Поле «Номер столбца» оставляем пустым, так как мы используем для примера одномерный диапазон.
А вот в поле «Номер строки» нам как раз нужно будет записать функцию ПОИСКПОЗ. Для её записи придерживаемся того синтаксиса, о котором шла речь выше. Сразу в поле вписываем наименование самого оператора «ПОИСКПОЗ» без кавычек. Затем сразу же открываем скобку и указываем координаты искомого значения. Это координаты той ячейки, в которую мы отдельно записали фамилию работника Парфенова. Ставим точку с запятой и указываем координаты просматриваемого диапазона. В нашем случае это адрес столбца с именами сотрудников. После этого закрываем скобку.
После того, как все значения внесены, жмем на кнопку «OK». 

Способ 3: обработка нескольких таблиц
Теперь посмотрим, как с помощью оператора ИНДЕКС можно обработать несколько таблиц. Для этих целей будет применяться дополнительный аргумент «Номер области».
Имеем три таблицы. В каждой таблице отображена заработная плата работников за отдельный месяц. Нашей задачей является узнать заработную плату (третий столбец) второго работника (вторая строка) за третий месяц (третья область).
- Выделяем ячейку, в которой будет производиться вывод результата и обычным способом открываем Мастер функций, но при выборе типа оператора выбираем ссылочный вид. Это нам нужно потому, что именно этот тип поддерживает работу с аргументом «Номер области».
- Открывается окно аргументов. В поле «Ссылка» нам нужно указать адреса всех трех диапазонов. Для этого устанавливаем курсор в поле и выделяем первый диапазон с зажатой левой кнопкой мыши. Затем ставим точку с запятой. Это очень важно, так как если вы сразу перейдете к выделению следующего массива, то его адрес просто заменит координаты предыдущего. Итак, после введения точки с запятой выделяем следующий диапазон. Затем опять ставим точку с запятой и выделяем последний массив. Все выражение, которое находится в поле «Ссылка» берем в скобки.
В поле «Номер строки» указываем цифру «2», так как ищем вторую фамилию в списке.
В поле «Номер столбца» указываем цифру «3», так как колонка с зарплатой является третьей по счету в каждой таблице.
В поле «Номер области» ставим цифру «3», так как нам нужно найти данные в третьей таблице, в которой содержится информация о заработной плате за третий месяц.
После того, как все данные введены, щелкаем по кнопке «OK». 
Способ 4: вычисление суммы
Ссылочная форма не так часто применяется, как форма массива, но её можно использовать не только при работе с несколькими диапазонами, но и для других нужд. Например, её можно применять для расчета суммы в комбинации с оператором СУММ.
При сложении суммы СУММ имеет следующий синтаксис:
В нашем конкретном случае сумму заработка всех работников за месяц можно вычислить при помощи следующей формулы:
Но можно её немного модифицировать, использовав функцию ИНДЕКС. Тогда она будет иметь следующий вид:
В этом случае в координатах начала массива указывается ячейка, с которой он начинается. А вот в координатах указания окончания массива используется оператор ИНДЕКС. В данном случае первый аргумент оператора ИНДЕКС указывает на диапазон, а второй – на последнюю его ячейку – шестую.
Как видим, функцию ИНДЕКС можно использовать в Экселе для решения довольно разноплановых задач. Хотя мы рассмотрели далеко не все возможные варианты её применения, а только самые востребованные. Существует два типа этой функции: ссылочный и для массивов. Наиболее эффективно её можно применять в комбинации с другими операторами. Созданные таким способом формулы смогут решать самые сложные задачи.
Источник
Бывает у вас такое: смотришь на человека и думаешь «что за @#$%)(*?» А потом при близком знакомстве оказывается, что он знает пять языков, прыгает с парашютом, имеет семеро детей и черный пояс в шахматах, да и, вообще, добрейшей души человек и умница?
Так и в Microsoft Excel: есть несколько похожих функций, про которых фраза «внешность обманчива» работает на 100%. Одна из наиболее многогранных и полезных — функция ИНДЕКС (INDEX). Далеко не все пользователи Excel про нее знают, и еще меньше используют все её возможности. Давайте разберем варианты ее применения, ибо их аж целых пять.
Вариант 1. Извлечение данных из столбца по номеру ячейки
Самый простой случай использования функции ИНДЕКС – это ситуация, когда нам нужно извлечь данные из одномерного диапазона-столбца, если мы знаем порядковый номер ячейки. Синтаксис в этом случае будет:
=ИНДЕКС(Диапазон_столбец; Порядковый_номер_ячейки)

Этот вариант известен большинству продвинутых пользователей Excel. В таком виде функция ИНДЕКС часто используется в связке с функцией ПОИСКПОЗ (MATCH), которая выдает номер искомого значения в диапазоне. Таким образом, эта пара заменяет легендарную ВПР (VLOOKUP):

… но, в отличие от ВПР, могут извлекать значения левее поискового столбца и номер столбца-результата высчитывать не нужно.
Вариант 2. Извлечение данных из двумерного диапазона
Если диапазон двумерный, т.е. состоит из нескольких строк и столбцов, то наша функция будет использоваться немного в другом формате:
=ИНДЕКС(Диапазон; Номер_строки; Номер_столбца)

Т.е. функция извлекает значение из ячейки диапазона с пересечения строки и столбца с заданными номерами.
Легко сообразить, что с помощью такой вариации ИНДЕКС и двух функций ПОИСКПОЗ можно легко реализовать двумерный поиск:

Вариант 3. Несколько таблиц
Если таблица не одна, а их несколько, то функция ИНДЕКС может извлечь данные из нужной строки и столбца именно заданной таблицы. В этом случае используется следующий синтаксис:
=ИНДЕКС((Диапазон1;Диапазон2;Диапазон3); Номер_строки; Номер_столбца; Номер_диапазона)

Обратите особое внимание, что в этом случае первый аргумент – список диапазонов — заключается в скобки, а сами диапазоны перечисляются через точку с запятой.
Вариант 4. Ссылка на столбец / строку
Если во втором варианте использования функции ИНДЕКС номер строки или столбца задать равным нулю (или просто не указать), то функция будет выдавать уже не значение, а ссылку на диапазон-столбец или диапазон-строку соответственно:

Обратите внимание, что поскольку ИНДЕКС выдает в этом варианте не конкретное значение ячейки, а ссылку на диапазон, то для подсчета потребуется заключить ее в дополнительную функцию, например СУММ (SUM), СРЗНАЧ (AVERAGE) и т.п.
Вариант 5. Ссылка на ячейку
Общеизвестно, что стандартная ссылка на любой диапазон ячеек в Excel выглядит как Начало-Двоеточие-Конец, например A2:B5. Хитрость в том, что если взять функцию ИНДЕКС в первом или втором варианте и подставить ее после двоеточия, то наша функция будет выдавать уже не значение, а адрес, и на выходе мы получим полноценную ссылку на диапазон от начальной ячейки до той, которую нашла ИНДЕКС:

Нечто похожее можно реализовать функцией СМЕЩ (OFFSET), но она, в отличие от ИНДЕКС, является волатильной, т.е. пересчитывается каждый раз при изменении любой ячейки листа. ИНДЕКС же работает более тонко и запускает пересчет только при изменении своих аргументов, что ощутимо ускоряет расчет в тяжелых книгах по сравнению со СМЕЩ.
Один из весьма распространенных на практике сценариев применения ИНДЕКС в таком варианте — это сочетание с функцией СЧЁТЗ (COUNTA), чтобы получить автоматически растягивающиеся диапазоны для выпадающих списков, сводных таблиц и т.д.
Ссылки по теме
- Трехмерный поиск данных по нескольким листам (ВПР 3D)
- Поиск и подстановка по нескольким условиям (ВПР по нескольким столбцам)
- Подстановка данных из одной таблицы в другую с помощью функции ВПР (VLOOKUP)
Функция ИНДЕКС возвращает значение или ссылку на значение из таблицы или диапазона.
Функцию ИНДЕКС можно использовать двумя способами:
-
Если вы хотите возвращать значение указанной ячейки или массива ячеек, см. раздел Форма массива.
-
Если требуется возвращать ссылку на указанные ячейки, см. раздел Ссылочная форма.
Форма массива
Описание
Возвращает значение элемента в таблице или массиве, выбранное по индексам номеров строк и столбцов.
Если первый аргумент функции ИНДЕКС является константной массива, используйте форму массива.
Синтаксис
ИНДЕКС(массив; номер_строки; [номер_столбца])
Форма массива функции INDEX имеет следующие аргументы:
-
массив. Обязательный аргумент. Диапазон ячеек или константа массива.
-
Если массив содержит только одну строку или столбец, соответствующий аргумент номер_строки или номер_столбца является необязательным.
-
Если массив содержит более одной строки и более одного столбца и используется только номер_строки или номер_столбца, ИНДЕКС возвращает массив всей строки или столбца в массиве.
-
-
Номер_строки Обязательный, если column_num отсутствует. Выбирает строку в массиве, из которой требуется возвратить значение. Если номер_строки опущен, требуется номер_столбца.
-
Номер_столбца — необязательный аргумент. Выбирает столбец в массиве, из которого требуется возвратить значение. Если номер_столбца опущен, требуется номер_строки.
Замечания
-
Если используются аргументы номер_строки и номер_столбца, функция ИНДЕКС возвращает значение в ячейке на пересечении номеров_строки и номера_столбца.
-
row_num и column_num должны указывать на ячейку в массиве; в противном случае ИНДЕКС возвращает #ССЫЛКА! ошибку «#ЗНАЧ!».
-
Если задать для row_num или column_num значение 0 (ноль), ИНДЕКС возвращает массив значений для всего столбца или строки соответственно. Чтобы использовать значения, возвращаемые в виде массива, введите функцию ИНДЕКС как формулу массива.
Примечание: Если у вас есть текущая версия Microsoft 365, вы можете ввести формулу в верхнюю левую ячейку выходного диапазона, а затем нажать клавишу ВВОД, чтобы подтвердить формулу как формулу динамического массива. В противном случае формулу необходимо ввести как устаревшую формулу массива, сначала выбрав выходной диапазон, введите формулу в верхнюю левую ячейку выходного диапазона, а затем нажмите CTRL+SHIFT+ENTER для подтверждения. Excel автоматически вставляет фигурные скобки в начале и конце формулы. Дополнительные сведения о формулах массива см. в статье Использование формул массива: рекомендации и примеры.
Примеры
Пример 1
В этих примерах функция ИНДЕКС используется для поиска значения ячейки, находящейся на пересечении заданных строки и столбца.
Скопируйте образец данных из следующей таблицы и вставьте их в ячейку A1 нового листа Excel. Чтобы отобразить результаты формул, выделите их и нажмите клавишу F2, а затем — ВВОД.
|
Данные |
Данные |
|
|---|---|---|
|
Яблоки |
Лимоны |
|
|
Бананы |
Груши |
|
|
Формула |
Описание |
Результат |
|
=ИНДЕКС(A2:B3;2;2) |
Значение ячейки на пересечении второй строки и второго столбца в диапазоне A2:B3. |
Груши |
|
=ИНДЕКС(A2:B3;2;1) |
Значение ячейки на пересечении второй строки и первого столбца в диапазоне A2:B3. |
Бананы |
Пример 2
В этом примере функция ИНДЕКС используется в формуле массива для поиска значений двух заданных ячеек в массиве с диапазоном 2 x 2.
Примечание: Если у вас есть текущая версия Microsoft 365, вы можете ввести формулу в верхнюю левую ячейку выходного диапазона, а затем нажать клавишу ВВОД, чтобы подтвердить формулу как формулу динамического массива. В противном случае формулу необходимо ввести как устаревшую формулу массива, сначала выбрав две пустые ячейки, введите формулу в верхнюю левую ячейку выходного диапазона, а затем нажмите CTRL+SHIFT+ENTER для подтверждения. Excel автоматически вставляет фигурные скобки в начале и конце формулы. Дополнительные сведения о формулах массива см. в статье Использование формул массива: рекомендации и примеры.
|
Формула |
Описание |
Результат |
|---|---|---|
|
=ИНДЕКС({1;2:3;4};0;2) |
Значение ячейки на пересечении первой строки и второго столбца в массиве. Массив содержит значения 1 и 2 в первой строке и значения 3 и 4 во второй строке. |
2 |
|
Значение ячейки на пересечении второй строки и второго столбца в массиве, указанном выше. |
4 |
|
К началу страницы
Справочная форма
Описание
Возвращает ссылку на ячейку, расположенную на пересечении указанной строки и указанного столбца. Если ссылка состоит из несмежных выборок, вы можете выбрать выборку для поиска.
Синтаксис
ИНДЕКС(ссылка; номер_строки; [номер_столбца]; [номер_области])
Справочная форма функции ИНДЕКС имеет следующие аргументы:
-
ссылка — обязательный аргумент. Ссылка на один или несколько диапазонов ячеек.
-
Если вы вводите несмежный диапазон для ссылки, заключите ссылку в круглые скобки.
-
Если каждая область в ссылке содержит только одну строку или столбец, аргумент номер_строки или номер_столбца соответственно является необязательным. Например, для ссылки на единственную строку нужно использовать формулу ИНДЕКС(ссылка,,номер_столбца).
-
-
Номер_строки Обязательный аргумент. Номер строки в диапазоне, заданном аргументом «ссылка», из которого требуется возвратить ссылку.
-
Номер_столбца — необязательный аргумент. Номер столбца в диапазоне, заданном аргументом «ссылка», из которого требуется возвратить ссылку.
-
area_num Необязательный. Выбирает диапазон в ссылке, из которого возвращается пересечение row_num и column_num. Первая выбранная или введенная область имеет номер 1, вторая — 2 и так далее. Если номер_области опущен, ИНДЕКС использует область 1. Перечисленные здесь области должны располагаться на одном листе. Если вы укажете области, которые не находятся на одном листе друг с другом, это вызовет ошибку #ЗНАЧ! ошибку «#ВЫЧИС!». Если вам нужно использовать диапазоны, расположенные на разных листах друг от друга, рекомендуется использовать форму массива функции ИНДЕКС, а для вычисления диапазона, из которого состоит массив, использовать другую функцию. Например, вы можете использовать функцию ВЫБОР, чтобы вычислить, какой диапазон будет использоваться.
Например, если ссылка описывает ячейки (A1:B4,D1:E4,G1:H4), номер_области 1 – это диапазон A1:B4, номер_области 2 – это диапазон D1:E4, а номер_области 3 – диапазон G1:H4.
Замечания
-
После того, как ссылка и area_num выбрали конкретный диапазон, row_num и column_num выбирают конкретную ячейку: row_num 1 — это первая строка в диапазоне, column_num 1 — это первый столбец и так далее. Ссылка, возвращаемая INDEX, представляет собой пересечение row_num и column_num.
-
Если вы установите номер_строки или номер_столбца равным 0 (ноль), ИНДЕКС возвращает ссылку для всего столбца или строки соответственно.
-
row_num, column_num и area_num должны указывать на ячейку в пределах ссылки; в противном случае ИНДЕКС возвращает #ССЫЛКА! ошибку «#ЗНАЧ!». Если номер_строки и номер_столбца опущены, ИНДЕКС возвращает область в ссылке, указанную номером_области.
-
Результатом вычисления функции ИНДЕКС является ссылка, которая интерпретируется в качестве таковой другими функциями. В зависимости от формулы значение, возвращаемое функцией ИНДЕКС, может использоваться как ссылка или как значение. Например, формула ЯЧЕЙКА(«ширина»;ИНДЕКС(A1:B2;1;2)) эквивалентна формуле ЯЧЕЙКА(«ширина»;B1). Функция ЯЧЕЙКА использует значение, возвращаемое функцией ИНДЕКС, как ссылку. С другой стороны, такая формула, как 2*ИНДЕКС(A1:B2;1;2), преобразует значение, возвращаемое функцией ИНДЕКС, в число в ячейке B1.
Примеры
Скопируйте образец данных из следующей таблицы и вставьте их в ячейку A1 нового листа Excel. Чтобы отобразить результаты формул, выделите их и нажмите клавишу F2, а затем — клавишу Enter.
|
Фрукты |
Цена |
Количество |
|---|---|---|
|
Яблоки |
0,69 ₽ |
40 |
|
Бананы |
0,34 ₽ |
38 |
|
Лимоны |
0,55 ₽ |
15 |
|
Апельсины |
0,25 ₽ |
25 |
|
Груши |
0,59 ₽ |
40 |
|
Миндаль |
2,80 ₽ |
10 |
|
Кешью |
3,55 ₽ |
16 |
|
Арахис |
1,25 ₽ |
20 |
|
Грецкие орехи |
1,75 ₽ |
12 |
|
Формула |
Описание |
Результат |
|
=ИНДЕКС(A2:C6;2;3) |
Пересечение второй строки и третьего столбца в диапазоне A2:C6, т. е. содержимое ячейки C3. |
38 |
|
=ИНДЕКС((A1:C6;A8:C11);2;2;2) |
Пересечение второй строки и второго столбца во второй области (A8:C11), т. е. содержимое ячейки B9. |
1,25 |
|
=СУММ(ИНДЕКС(A1:C11;0;3;1)) |
Сумма третьего столбца в первой области диапазона (A1:C11) является суммой диапазона C1:C11. |
216 |
|
=СУММ(B2:ИНДЕКС(A2:C6;5;2)) |
Сумма значений из диапазона, начинающегося с ячейки B2 и заканчивающегося пересечением пятой строки и второго столбца диапазона A2:A6, т. е. сумма значений из диапазона B2:B6. |
2,42 |
К началу страницы
См. также
Функция ВПР
ПОИСКПОЗ
Функция ДВССЫЛ
Использование формул массива: рекомендации и примеры
Функции ссылки и поиска (справка)
Skip to content
В этом руководстве показано, как использовать ИНДЕКС и ПОИСКПОЗ в Excel и чем они лучше ВПР.
В нескольких недавних статьях мы приложили немало усилий, чтобы объяснить основы функции ВПР новичкам и предоставить более сложные примеры формул ВПР опытным пользователям. А теперь я постараюсь если не отговорить вас от использования ВПР, то хотя бы показать вам альтернативный способ поиска нужных значений в Excel.
- Краткий обзор функций ИНДЕКС и ПОИСКПОЗ
- Как использовать формулу ИНДЕКС ПОИСКПОЗ
- ИНДЕКС+ПОИСКПОЗ вместо ВПР?
- Поиск справа налево
- Двусторонний поиск в строках и столбцах
- ИНДЕКС ПОИСКПОЗ для поиска по нескольким условиям
- Как найти среднее, максимальное и минимальное значение
- Что делать с ошибками поиска?
Для чего это нужно? Потому что функция ВПР имеет множество ограничений, которые могут помешать вам получить желаемый результат во многих ситуациях. С другой стороны, комбинация ПОИСКПОЗ ИНДЕКС более гибкая и имеет много замечательных возможностей, которые во многих отношениях превосходят ВПР.
Функции Excel ИНДЕКС и ПОИСКПОЗ — основы
Поскольку целью этого руководства является демонстрация альтернативного способа выполнения поиска в Excel с использованием комбинации функций ИНДЕКС и ПОИСКПОЗ, мы не будем подробно останавливаться на их синтаксисе и использовании. Тем более, что это подробно рассмотрено в других статьях, ссылки на которые вы можете найти в конце этого руководства. Мы рассмотрим лишь минимум, необходимый для понимания общей идеи, а затем подробно рассмотрим примеры формул, раскрывающие все преимущества использования ПОИСКПОЗ и ИНДЕКС вместо ВПР.
Функция ИНДЕКС
Функция ИНДЕКС (в английском варианте – INDEX) возвращает значение в массиве на основе указанных вами номеров строк и столбцов. Синтаксис функции ИНДЕКС прост:
ИНДЕКС(массив,номер_строки,[номер_столбца])
Вот простое объяснение каждого параметра:
- массив — это диапазон ячеек, именованный диапазон или таблица.
- номер_строки — это номер строки в массиве, из которого нужно вернуть значение. Если этот аргумент опущен, требуется следующий – номер_столбца.
- номер_столбца — это номер столбца, из которого нужно вернуть значение. Если он опущен, требуется номер_строки.
Дополнительные сведения см. в статье Функция ИНДЕКС в Excel .
А вот пример формулы ИНДЕКС в самом простом виде:
=ИНДЕКС(A1:C10;2;3)
Формула выполняет поиск в ячейках с A1 по C10 и возвращает значение ячейки во 2-й строке и 3-м столбце, т. е. в ячейке C2.
Очень легко, правда? Однако при работе с реальными данными вы вряд ли когда-нибудь будете заранее знать, какие строки и столбцы вам нужны. Здесь вам пригодится ПОИСКПОЗ.
Функция ПОИСКПОЗ
Она ищет нужное значение в диапазоне ячеек и возвращает относительное положение этого значения в диапазоне.
Синтаксис функции ПОИСКПОЗ следующий:
ПОИСКПОЗ(искомое_значение, искомый_массив, [тип_совпадения])
- искомое_значение — числовое или текстовое значение, которое вы ищете.
- диапазон_поиска — диапазон ячеек, в которых будем искать.
- тип_совпадения — указывает, следует ли искать точное соответствие или наиболее близкое совпадение:
- 1 или опущено — находит наибольшее значение, которое меньше или равно искомому значению. Требуется сортировка массива поиска в порядке возрастания.
- 0 — находит первое значение, точно равное искомому значению. В комбинации ИНДЕКС/ПОИСКПОЗ вам почти всегда нужно точное совпадение, поэтому вы чаще всего устанавливаете третий аргумент вашей функции в 0.
- -1 — находит наименьшее значение, которое больше или равно искомому значению. Требуется сортировка массива поиска в порядке убывания.
Например, если диапазон B1:B3 содержит значения «яблоки», «апельсины», «лимоны», приведенная ниже формула возвращает число 3, поскольку «лимоны» — это третья по счету запись в этом диапазоне:
=ПОИСКПОЗ(«лимоны»;B1:B3;0)
Дополнительные сведения см . в статье Функция ПОИСКПОЗ в Excel .
На первый взгляд полезность функции ПОИСКПОЗ может показаться сомнительной. Кого волнует положение значения в диапазоне? Что мы действительно хотим определить, так это само значение.
Однако, относительная позиция искомого значения (т. е. номера строки и столбца, в которых оно находится) — это именно то, что нам нужно указать для аргументов номер_строки и номер_столбца функции ИНДЕКС. Как вы помните, ИНДЕКС может найти значение на пересечении заданной строки и столбца, но сама не может определить, какую именно строку и столбец ей нужно выбрать.
Вот поэтому совместное использование ИНДЕКС и ПОИСКПОЗ открывает перед нами массу возможностей для поиска в Excel.
Как использовать формулу ИНДЕКС ПОИСКПОЗ в Excel
Теперь, когда вы знаете основы, я считаю, что вы уже начали понимать, как ПОИСКПОЗ и ИНДЕКС работают вместе. Короче говоря, ИНДЕКС извлекает нужное значение по номерам столбцов и строк, а ПОИСКПОЗ предоставляет ей эти номера. Вот и все!
Для вертикального поиска вы используете функцию ПОИСКПОЗ только для определения номера строки, указывая диапазон столбцов непосредственно в самой формуле:
ИНДЕКС ( столбец для возврата значения ; ПОИСКПОЗ ( искомое значение ; столбец для поиска ; 0))
Все еще не совсем понимаете эту логику? Возможно, будет проще разобрать на примере. Предположим, у вас есть список национальных столиц и их население:
Чтобы найти население определенной столицы, скажем, Индии, используйте следующую формулу ПОИСКПОЗ ИНДЕКС:
=ИНДЕКС(C2:C10; ПОИСКПОЗ(“Индия”;A2:A10;0))
Теперь давайте проанализируем, что на самом деле делает каждый компонент этой формулы:
- Функция ПОИСКПОЗ ищет искомое значение «Индия» в диапазоне A2:A10 и возвращает число 2, поскольку это слово занимает второе место в массиве поиска.
- Этот номер поступает непосредственно в аргумент номер_строки функции ИНДЕКС, предписывая вернуть значение из этой строки.
Таким образом, приведенная выше формула превращается в ИНДЕКС(C2:C10;2), которая означает, что нужно искать в ячейках от C2 до C10 и извлекать значение из второй ячейки в этом диапазоне, то есть из C3, потому что мы начинаем отсчет со второй строки.
Но указывать название города в формуле не совсем правильно, так как для каждого нового поиска придется корректировать эту формулу. Введите его в какую-нибудь отдельную ячейку, скажем, F1, укажите ссылку на ячейку для ПОИСКПОЗ, и вы получите формулу динамического поиска:
=ИНДЕКС(C2:C10;ПОИСКПОЗ(F1;A2:A10;0))
Важное замечание! Количество строк в аргументе массив функции ИНДЕКС должно совпадать с количеством строк в аргументе просматриваемый_массив в ПОИСКПОЗ, иначе формула выдаст неверный результат.
Вы спросите: «А почему бы нам просто не использовать обычную формулу ВПР? Какой смысл тратить время на то, чтобы разобраться в хитросплетениях ИНДЕКС ПОИСКПОЗ в Excel?»
Вот как это будет выглядеть:
=ВПР(F1; A2:C10; 3; 0)
Конечно, так проще. Но этот наш элементарный пример предназначен только для демонстрационных целей, чтобы вы поняли, как именно функции ИНДЕКС и ПОИСКПОЗ работают вместе. Действительно, ВПР была бы здесь более уместна. Другие примеры, которые вы найдёте ниже, покажут вам реальную силу этой комбинации, которая легко справляется со многими сложными задачами, когда ВПР будет бессильна.
ИНДЕКС+ПОИСКПОЗ вместо ВПР?
Решая, какую функцию использовать для вертикального поиска, большинство знатоков Excel сходятся во мнении, что ПОИСКПОЗ+ИНДЕКС намного лучше, чем ВПР. Однако многие до сих пор остаются с ВПР, во-первых, потому что это проще, а, во-вторых, потому что они не до конца понимают все преимущества использования формулы ПОИСКПОЗ ИНДЕКС в Excel. Без такого понимания никто не захочет тратить свое время на изучение более сложного синтаксиса.
Ниже я укажу на ключевые преимущества ИНДЕКС ПОИСКПОЗ перед ВПР, а уж вам решать, является ли это достойным дополнением к вашему арсеналу знаний в Excel.
4 основные причины использовать ИНДЕКС ПОИСКПОЗ вместо ВПР
- Поиск справа налево. Как известно любому образованному пользователю, ВПР не может искать влево. Это означает, что искомое значение всегда должно находиться в крайнем левом столбце таблицы. А извлекать нужное значение мы будем из столбца, который находится правее. ИНДЕКС+ПОИСКПОЗ может легко выполнять поиск влево! Здесь это показано в действии: Как выполнить поиск значения слева в Excel .
- Можно безопасно вставлять или удалять столбцы. Формулы ВПР не работают или выдают неверные результаты, когда новый столбец удаляется из таблицы поиска или добавляется в нее, поскольку синтаксис ВПР требует указания порядкового номера столбца, из которого вы хотите извлечь данные. Естественно, когда вы добавляете или удаляете столбцы, этот номер в формуле автоматически не меняется, а нужный столбец уже оказывается на новом месте.
С функциями ИНДЕКС и ПОИСКПОЗ вы указываете диапазон возвращаемых столбцов, а не номер одного из них. В результате вы можете вставлять и удалять столько столбцов, сколько хотите, не беспокоясь об обновлении каждой связанной с ними формулы.
- Нет ограничений на размер искомого значения. При использовании функции ВПР общая длина ваших критериев поиска не может превышать 255 символов, иначе вы получите ошибку #ЗНАЧ!. Таким образом, если ваш набор данных содержит длинные строки, ИНДЕКС ПОИСКПОЗ — единственное работающее решение.
- Более высокая скорость обработки. Если ваши таблицы относительно небольшие, вряд ли будет какая-то существенная разница в производительности Excel. Но если ваши рабочие листы содержат сотни или тысячи строк и, следовательно, сотни или тысячи формул, ИНДЕКС ПОИСКПОЗ будет работать намного быстрее, чем ВПР. Причина в том, что Excel будет обрабатывать только столбцы поиска и возврата, а не весь массив таблицы.
Влияние ВПР на производительность Excel может быть особенно заметным, если ваша книга содержит сложные формулы массива. Чем больше значений содержит ваш массив и чем больше формул массива содержится в книге, тем медленнее работает Excel.
ИНДЕКС ПОИСКПОЗ в Excel – примеры формул
Уяснив, почему все же стоит изучать ИНДЕКС ПОИСКПОЗ, давайте перейдем к самому интересному и посмотрим, как можно применить теоретические знания на практике.
Формула для поиска справа налево
Как уже упоминалось, ВПР не может получать значения слева от столбца поиска. Таким образом, если ваши значения поиска не находятся в самом левом столбце, нет никаких шансов, что формула ВПР принесет вам желаемый результат. Функция ПОИСКПОЗ ИНДЕКС в Excel более универсальна и не имеет особого значения, где расположены столбцы поиска и возврата.
Для этого примера мы добавим столбец «Ранг» слева от нашей основной таблицы и попытаемся выяснить, какое место занимает столица России по численности населения среди других перечисленных столиц.
Записав искомое значение в G1, используйте следующую формулу для поиска в C2:C10 и возврата соответствующего значения из A2:A10:
=ИНДЕКС(A2:A10; ПОИСКПОЗ(G1;C2:C10;0))
Совет. Если вы планируете использовать формулу ПОИСКПОЗ ИНДЕКС более чем для одной ячейки, обязательно зафиксируйте оба диапазона абсолютными ссылками (например, $A$2:$A$10 и $C$2:$C$10), чтобы они не изменялись при копировании формулы.
Двусторонний поиск в строках и столбцах
В приведенных выше примерах мы использовали ИНДЕКС ПОИСКПОЗ вместо классической функции ВПР, чтобы вернуть значение из точно указанного столбца. Но что, если вам нужно искать в нескольких строках и столбцах? То есть, сначала нужно найти подходящий столбец, а уж потом извлечь из него значение? Другими словами, что, если вы хотите выполнить так называемый матричный или двусторонний поиск?
Это может показаться сложным, но формула очень похожа на базовую функцию ПОИСКПОЗ ИНДЕКС в Excel, но с одним отличием.
Просто используйте две функции ПОИСКПОЗ, вложенных друг в друга: одну – для получения номера строки, а другую – для получения номера столбца.
ИНДЕКС(массив; ПОИСКПОЗ(значение_поиска1 ; столбец_поиска ; 0); ПОИСКПОЗ(значение_поиска2 ; столбец_поиска ; 0))
А теперь, пожалуйста, взгляните на приведенную ниже таблицу и давайте составим формулу двумерного поиска, чтобы найти население (в миллионах) в данной стране за данный год.
С целевой страной в G1 (значение_поиска1) и целевым годом в G2 (значение_поиска2) формула принимает следующий вид:
=ИНДЕКС(B2:D11; ПОИСКПОЗ(G1;A2:A11;0); ПОИСКПОЗ(G2;B1:D1;0))
Как работает эта формула?
Всякий раз, когда вам нужно понять сложную формулу Excel, разделите ее на более мелкие части и посмотрите, что делает каждая отдельная функция:
ПОИСКПОЗ(G1;A2:A11;0); – ищет в A2:A11 значение из ячейки G1 («США») и возвращает его позицию, которая равна 3.
ПОИСКПОЗ(G2;B1:D1;0) – просматривает диапазон B1:D1, чтобы получить позицию значения из ячейки G2 («2015»), которая равна 3.
Найденные выше номера строк и столбцов становятся соответствующими аргументами функции ИНДЕКС:
ИНДЕКС(B2:D11, 3, 3)
В результате вы получите значение на пересечении 3-й строки и 3-го столбца в диапазоне B2:D11, то есть из D4. Несложно?
ИНДЕКС ПОИСКПОЗ для поиска по нескольким условиям
Если у вас была возможность прочитать наши материалы по ВПР в Excel, вы, вероятно, уже протестировали формулу для ВПР с несколькими условиями . Однако существенным недостатком этого подхода является необходимость добавления вспомогательного столбца. Хорошей новостью является то, что функция ПОИСКПОЗ ИНДЕКС в Excel также может выполнять поиск по нескольким условиям без изменения или реструктуризации исходных данных!
Вот общая формула ИНДЕКС ПОИСКПОЗ с несколькими критериями:
{=ИНДЕКС( диапазон_возврата; ПОИСКПОЗ (1; ( критерий1 = диапазон1 ) * ( критерий2 = диапазон2 ); 0))}
Примечание. Это формула массива , которую необходимо вводить с помощью сочетания клавиш Ctrl + Shift + Enter.
Предположим, что в таблице ниже вы хотите найти значение на основе двух критериев: Покупатель и Товар.
Следующая формула ИНДЕКС ПОИСКПОЗ отлично работает:
=ИНДЕКС(C2:C10; ПОИСКПОЗ(1; (F1=A2:A10) * (F2=B2:B10); 0))
Где C2:C10 — это диапазон, из которого возвращается значение, F1 — это критерий1, A2:A10 — это диапазон для сравнения с критерием 1, F2 — это критерий 2, а B2:B10 — это диапазон для сравнения с критерием 2.
Не забудьте правильно ввести формулу, нажав Ctrl + Shift + Enter, и Excel автоматически заключит ее в фигурные скобки, как показано на скриншоте ниже:
Рис5
Если вы не хотите использовать формулы массива, добавьте в формулу в F4 еще одну функцию ИНДЕКС и завершите ее ввод обычным нажатием Enter:
=ИНДЕКС(C2:C10; ПОИСКПОЗ(1; ИНДЕКС((F1=A2:A10) * (F2=B2:B10); 0; 1); 0))
Разберем пошагово, как это работает.
Здесь используется тот же подход, что и в обычном сочетании ИНДЕКС ПОИСКПОЗ, где просматривается один столбец. Чтобы оценить несколько критериев, вы создаете два или более массива значений ИСТИНА и ЛОЖЬ, которые представляют совпадения и несовпадения для каждого отдельного критерия, а затем перемножаете соответствующие элементы этих массивов. Операция умножения преобразует ИСТИНА и ЛОЖЬ в 1 и 0 соответственно и создает массив, в котором единицы соответствуют строкам, которые удовлетворяют всем условиям. Функция ПОИСКПОЗ со значением поиска 1 находит первую «1» в массиве и передает ее позицию в ИНДЕКС, которая возвращает значение в этой позиции из указанного столбца.
Вторая формула без массива основана на способности функции ИНДЕКС работать с массивами. Второй вложенный ИНДЕКС имеет 0 в номер_строки , так что он будет передавать весь массив столбцов в ПОИСКПОЗ.
Среднее, максимальное и минимальное значение при помощи ИНДЕКС ПОИСКПОЗ
Microsoft Excel имеет специальные функции для поиска минимального, максимального и среднего значения в диапазоне. Но что, если вам нужно получить значение из другой ячейки, связанной с этими значениями? Например, получить название города с максимальным населением или узнать товар с минимальными продажами? В этом случае используйте функцию МАКС , МИН или СРЗНАЧ вместе с ИНДЕКС ПОИСКПОЗ.
Максимальное значение.
Предположим, нам нужно в списке городов найти столицу с самым большим населением. Чтобы найти наибольшее значение в столбце С и вернуть соответствующее ему значение из столбца В, находящееся в той же строке, используйте эту формулу:
=ИНДЕКС(B2:B10; ПОИСКПОЗ(МАКС(C2:C10); C2:C10; 0))
Скриншот с примером находится чуть ниже.
Минимальное значение
Теперь найдём город с самым маленьким населением в списке. Чтобы найти наименьшее число в столбце С и получить соответствующее ему значение из столбца В:
=ИНДЕКС(B2:B10; ПОИСКПОЗ(МИН(C2:C10); C2:C10; 0))
Ближайшее к среднему
Теперь мы находим город, население которого наиболее близко к среднему значению. Чтобы вычислить позицию, наиболее близкую к среднему значению показателя, рассчитанному из D2:D10, и получить соответствующее значение из столбца C, используйте следующую формулу:
=ИНДЕКС(B2:B10; ПОИСКПОЗ(СРЗНАЧ(C2:C10); C2:C10; -1 ))
В зависимости от того, как организованы ваши данные, укажите 1 или -1 для третьего аргумента (тип_совпадения) функции ПОИСКПОЗ:
- Если ваш столбец поиска (столбец D в нашем случае) отсортирован по возрастанию , поставьте 1. Формула вычислит наибольшее значение, которое меньше или равно среднему значению.
- Если ваш столбец поиска отсортирован по убыванию , введите -1. Формула вычислит наименьшее значение, которое больше или равно среднему значению.
- Если ваш массив поиска содержит значение , точно равное среднему, вы можете ввести 0 для точного совпадения. Никакой сортировки не требуется.
В нашем примере данные в столбце D отсортированы в порядке убывания, поэтому мы используем -1 для типа соответствия. В результате мы получаем «Токио», так как его население (13 189 000) является ближайшим, превышающим среднее значение (12 269 006).
Что делать с ошибками поиска?
Как вы, наверное, заметили, если формула ИНДЕКС ПОИСКПОЗ в Excel не может найти искомое значение, она выдает ошибку #Н/Д. Если вы хотите заменить это стандартное сообщение чем-то более информативным, оберните формулу ПОИСКПОЗ ИНДЕКС в функцию ЕСНД . Например:
=ЕСНД(ИНДЕКС(C2:C10; ПОИСКПОЗ(F1;A2:A10;0)); «Не найдено»)
И теперь, если кто-то вводит значение, которое не существует в диапазоне поиска, формула явно сообщит пользователю, что совпадений не найдено:
Если вы хотите перехватывать все ошибки, а не только #Н/Д, используйте функцию ЕСЛИОШИБКА вместо ЕСНД:
=ЕСЛИОШИБКА(ИНДЕКС(C2:C10; ПОИСКПОЗ(F1;A2:A10;0)); «Что-то пошло не так!»)
Пожалуйста, имейте в виду, что во многих ситуациях было бы не совсем правильно скрывать все такие ошибки, потому что они предупреждают вас о возможных проблемах в вашей формуле.
Итак, еще раз об основных преимуществах формулы ИНДЕКС ПОИСКПОЗ.
-
Возможен ли «левый» поиск?
-
Повлияет ли на результат вставка и удаление столбцов?
Вы можете вставлять и удалять столько столбцов, сколько хотите. На результат ИНДЕКС ПОИСКПОЗ это не повлияет.
-
Возможен ли поиск по строкам и столбцам?
Можно сначала найти подходящий столбец, а уж потом извлечь из него значение. Общий вид формулы:
ИНДЕКС(массив; ПОИСКПОЗ(значение_поиска1 ; столбец_поиска ; 0); ПОИСКПОЗ(значение_поиска2 ; столбец_поиска ; 0))
Подробную инструкцию смотрите здесь. -
Как сделать поиск ИНДЕКС ПОИСКПОЗ по нескольким условиям?
Можно выполнять поиск по двум или более условиям без добавления дополнительных столбцов. Вот формула массива, которая решит проблему:
{=ИНДЕКС( диапазон_возврата; ПОИСКПОЗ (1; ( критерий1 = диапазон1 ) * ( критерий2 = диапазон2 ); 0))}
Вот как можно использовать ИНДЕКС и ПОИСКПОЗ в Excel. Я надеюсь, что наши примеры формул окажутся полезными для вас.
Вот еще несколько статей по этой теме:
Содержание
- Использование функции ИНДЕКС
- Способ 1: использование оператора ИНДЕКС для массивов
- Способ 2: применение в комплексе с оператором ПОИСКПОЗ
- Способ 3: обработка нескольких таблиц
- Способ 4: вычисление суммы
- Вопросы и ответы
Одной из самых полезных функций программы Эксель является оператор ИНДЕКС. Он производит поиск данных в диапазоне на пересечении указанных строки и столбца, возвращая результат в заранее обозначенную ячейку. Но полностью возможности этой функции раскрываются при использовании её в сложных формулах в комбинации с другими операторами. Давайте рассмотрим различные варианты её применения.
Использование функции ИНДЕКС
Оператор ИНДЕКС относится к группе функций из категории «Ссылки и массивы». Он имеет две разновидности: для массивов и для ссылок.
Вариант для массивов имеет следующий синтаксис:
=ИНДЕКС(массив;номер_строки;номер_столбца)
При этом два последних аргумента в формуле можно использовать, как вместе, так и любой один из них, если массив одномерный. При многомерном диапазоне следует применять оба значения. Нужно также учесть, что под номером строки и столбца понимается не номер на координатах листа, а порядок внутри самого указанного массива.
Синтаксис для ссылочного варианта выглядит так:
=ИНДЕКС(ссылка;номер_строки;номер_столбца;[номер_области])
Тут точно так же можно использовать только один аргумент из двух: «Номер строки» или «Номер столбца». Аргумент «Номер области» вообще является необязательным и он применяется только тогда, когда в операции участвуют несколько диапазонов.
Таким образом, оператор ищет данные в установленном диапазоне при указании строки или столбца. Данная функция своими возможностями очень похожа на оператора ВПР, но в отличие от него может производить поиск практически везде, а не только в крайнем левом столбце таблицы.
Способ 1: использование оператора ИНДЕКС для массивов
Давайте, прежде всего, разберем на простейшем примере алгоритм использования оператора ИНДЕКС для массивов.
Имеем таблицу зарплат. В первом её столбце отображены фамилии работников, во втором – дата выплаты, а в третьем – величина суммы заработка. Нам нужно вывести имя работника в третьей строке.
- Выделяем ячейку, в которой будет выводиться результат обработки. Кликаем по значку «Вставить функцию», который размещен сразу слева от строки формул.
- Происходит процедура активации Мастера функций. В категории «Ссылки и массивы» данного инструмента или «Полный алфавитный перечень» ищем наименование «ИНДЕКС». После того, как нашли этого оператора, выделяем его и щелкаем по кнопке «OK», которая размещается в нижней части окна.
- Открывается небольшое окошко, в котором нужно выбрать один из типов функции: «Массив» или «Ссылка». Нужный нам вариант «Массив». Он расположен первым и по умолчанию выделен. Поэтому нам остается просто нажать на кнопку «OK».
- Открывается окно аргументов функции ИНДЕКС. Как выше говорилось, у неё имеется три аргумента, а соответственно и три поля для заполнения.
В поле «Массив» нужно указать адрес обрабатываемого диапазона данных. Его можно вбить вручную. Но для облегчения задачи мы поступим иначе. Ставим курсор в соответствующее поле, а затем обводим весь диапазон табличных данных на листе. После этого адрес диапазона тут же отобразится в поле.
В поле «Номер строки» ставим цифру «3», так как по условию нам нужно определить третье имя в списке. В поле «Номер столбца» устанавливаем число «1», так как колонка с именами является первой в выделенном диапазоне.
После того, как все указанные настройки совершены, щелкаем по кнопке «OK».
- Результат обработки выводится в ячейку, которая была указана в первом пункте данной инструкции. Именно выведенная фамилия является третьей в списке в выделенном диапазоне данных.
Мы разобрали применение функции ИНДЕКС в многомерном массиве (несколько столбцов и строк). Если бы диапазон был одномерным, то заполнение данных в окне аргументов было бы ещё проще. В поле «Массив» тем же методом, что и выше, мы указываем его адрес. В данном случае диапазон данных состоит только из значений в одной колонке «Имя». В поле «Номер строки» указываем значение «3», так как нужно узнать данные из третьей строки. Поле «Номер столбца» вообще можно оставить пустым, так как у нас одномерный диапазон, в котором используется только один столбец. Жмем на кнопку «OK».
Результат будет точно такой же, что и выше.
Это был простейший пример, чтобы вы увидели, как работает данная функция, но на практике подобный вариант её использования применяется все-таки редко.
Урок: Мастер функций в Экселе
Способ 2: применение в комплексе с оператором ПОИСКПОЗ
На практике функция ИНДЕКС чаще всего применяется вместе с аргументом ПОИСКПОЗ. Связка ИНДЕКС – ПОИСКПОЗ является мощнейшим инструментом при работе в Эксель, который по своему функционалу более гибок, чем его ближайший аналог – оператор ВПР.
Основной задачей функции ПОИСКПОЗ является указание номера по порядку определенного значения в выделенном диапазоне.
Синтаксис оператора ПОИСКПОЗ такой:
=ПОИСКПОЗ(искомое_значение, просматриваемый_массив, [тип_сопоставления])
- Искомое значение – это значение, позицию которого в диапазоне мы ищем;
- Просматриваемый массив – это диапазон, в котором находится это значение;
- Тип сопоставления – это необязательный параметр, который определяет, точно или приблизительно искать значения. Мы будем искать точные значения, поэтому данный аргумент не используется.
С помощью этого инструмента можно автоматизировать введение аргументов «Номер строки» и «Номер столбца» в функцию ИНДЕКС.
Посмотрим, как это можно сделать на конкретном примере. Работаем все с той же таблицей, о которой шла речь выше. Отдельно у нас имеется два дополнительных поля – «Имя» и «Сумма». Нужно сделать так, что при введении имени работника автоматически отображалась сумма заработанных им денег. Посмотрим, как это можно воплотить на практике, применив функции ИНДЕКС и ПОИСКПОЗ.
- Прежде всего, узнаем, какую заработную плату получает работник Парфенов Д. Ф. Вписываем его имя в соответствующее поле.
- Выделяем ячейку в поле «Сумма», в которой будет выводиться итоговый результат. Запускаем окно аргументов функции ИНДЕКС для массивов.
В поле «Массив» вносим координаты столбца, в котором находятся суммы заработных плат работников.
Поле «Номер столбца» оставляем пустым, так как мы используем для примера одномерный диапазон.
А вот в поле «Номер строки» нам как раз нужно будет записать функцию ПОИСКПОЗ. Для её записи придерживаемся того синтаксиса, о котором шла речь выше. Сразу в поле вписываем наименование самого оператора «ПОИСКПОЗ» без кавычек. Затем сразу же открываем скобку и указываем координаты искомого значения. Это координаты той ячейки, в которую мы отдельно записали фамилию работника Парфенова. Ставим точку с запятой и указываем координаты просматриваемого диапазона. В нашем случае это адрес столбца с именами сотрудников. После этого закрываем скобку.
После того, как все значения внесены, жмем на кнопку «OK».
- Результат количества заработка Парфенова Д. Ф. после обработки выводится в поле «Сумма».
- Теперь, если в поле «Имя» мы изменим содержимое с «Парфенов Д.Ф.», на, например, «Попова М. Д.», то автоматически изменится и значение заработной платы в поле «Сумма».
Способ 3: обработка нескольких таблиц
Теперь посмотрим, как с помощью оператора ИНДЕКС можно обработать несколько таблиц. Для этих целей будет применяться дополнительный аргумент «Номер области».
Имеем три таблицы. В каждой таблице отображена заработная плата работников за отдельный месяц. Нашей задачей является узнать заработную плату (третий столбец) второго работника (вторая строка) за третий месяц (третья область).
- Выделяем ячейку, в которой будет производиться вывод результата и обычным способом открываем Мастер функций, но при выборе типа оператора выбираем ссылочный вид. Это нам нужно потому, что именно этот тип поддерживает работу с аргументом «Номер области».
- Открывается окно аргументов. В поле «Ссылка» нам нужно указать адреса всех трех диапазонов. Для этого устанавливаем курсор в поле и выделяем первый диапазон с зажатой левой кнопкой мыши. Затем ставим точку с запятой. Это очень важно, так как если вы сразу перейдете к выделению следующего массива, то его адрес просто заменит координаты предыдущего. Итак, после введения точки с запятой выделяем следующий диапазон. Затем опять ставим точку с запятой и выделяем последний массив. Все выражение, которое находится в поле «Ссылка» берем в скобки.
В поле «Номер строки» указываем цифру «2», так как ищем вторую фамилию в списке.
В поле «Номер столбца» указываем цифру «3», так как колонка с зарплатой является третьей по счету в каждой таблице.
В поле «Номер области» ставим цифру «3», так как нам нужно найти данные в третьей таблице, в которой содержится информация о заработной плате за третий месяц.
После того, как все данные введены, щелкаем по кнопке «OK».
- После этого в предварительно выделенную ячейку выводятся результаты вычисления. Там отображается сумма заработной платы второго по счету работника (Сафронова В. М.) за третий месяц.
Способ 4: вычисление суммы
Ссылочная форма не так часто применяется, как форма массива, но её можно использовать не только при работе с несколькими диапазонами, но и для других нужд. Например, её можно применять для расчета суммы в комбинации с оператором СУММ.
При сложении суммы СУММ имеет следующий синтаксис:
=СУММ(адрес_массива)
В нашем конкретном случае сумму заработка всех работников за месяц можно вычислить при помощи следующей формулы:
=СУММ(C4:C9)
Но можно её немного модифицировать, использовав функцию ИНДЕКС. Тогда она будет иметь следующий вид:
=СУММ(C4:ИНДЕКС(C4:C9;6))
В этом случае в координатах начала массива указывается ячейка, с которой он начинается. А вот в координатах указания окончания массива используется оператор ИНДЕКС. В данном случае первый аргумент оператора ИНДЕКС указывает на диапазон, а второй – на последнюю его ячейку – шестую.
Урок: Полезные функции Excel
Как видим, функцию ИНДЕКС можно использовать в Экселе для решения довольно разноплановых задач. Хотя мы рассмотрели далеко не все возможные варианты её применения, а только самые востребованные. Существует два типа этой функции: ссылочный и для массивов. Наиболее эффективно её можно применять в комбинации с другими операторами. Созданные таким способом формулы смогут решать самые сложные задачи.
Время на прочтение
16 мин
Количество просмотров 18K
Иногда мне бывает скучно и я, вооружившись отладчиком, начинаю копаться в разных программах. В этот раз мой выбор пал на Excel и было желание разобраться как он оперирует высотами рядов, в чём хранит, как считает высоту диапазона ячеек и т.д. Разбирал я Excel 2010 (excel.exe, 32bit, version 14.0.4756.1000, SHA1 a805cf60a5542f21001b0ea5d142d1cd0ee00b28).
Начнём с теории
Если обратиться к документации по VBA для Microsoft Office, то можно увидеть, что высоту ряда так или иначе можно получить через два свойства:
- RowHeight — Returns or sets the height of the first row in the range specified, measured in points. Read/write Double;
- Height — Returns a Double value that represents the height, in points, of the range. Read-only.
Причём если заглянуть ещё и сюда: Excel specifications and limits. То можно обнаружить, что максимальная высота ряда составляет 409 точек. Это к сожалению далеко не единственный случай, когда официальные документы Microsoft немножко лукавят. На самом деле в коде Excel максимальная высота ряда задана как 2047 пикселя, что в точках будет 1535.25. А максимальный размер шрифта 409.55 пунктов. Получить ряд такой огромной высоты простым присваиванием в VBA/Interop не получится, но можно взять ряд, задать его первой ячейке шрифт Cambria Math, а размер шрифта выставить в 409.55 пунктов. Тогда Excel своим хитрым алгоритмом посчитает высоту ряда на основе формата ячейки, получит число превышающее 2047 пикселей (поверьте на слово) и сам выставит у ряда максимально возможную высоту. Если спросить высоту этого ряда через UI, то Excel соврёт что высота 409.5 точек, но если запросить высоту ряда через VBA, то получится честные 1535,25 точек, что равняется 2047 пикселям. Правда после сохранения документа высота всё равно сбросится до 409,5 точек. Эту манипуляцию можно пронаблюдать вот на этом видео: http://recordit.co/ivnFEsELLI
Я не зря упомянул в предыдущем абзаце пиксели. Excel на самом деле хранит и рассчитывает размеры ячеек в целых числах (он вообще максимально всё делает в целых числах). Чаще всего это пиксели, умноженные на некоторый коэффициент. Интересно, что Excel хранит масштаб внешнего вида в виде обыкновенной дроби, например, масштаб 75% будет храниться как два числа 3 и 4. И когда надо будет вывести на экран ряд, Excel возьмёт высоту ряда как целое число пикселей, умножит на 3 и разделит на 4. Но выполнять эту операцию он будет уже в самом конце от этого создаётся эффект, что всё считается в дробных числах. Чтобы в этом убедиться напишите в VBA вот такой код:
w.Rows(1).RowHeight = 75.375
Debug.Print w.Rows(1).Height
VBA выдаст 75, т.к. 75,375 точек будет 100,5 пикселей, а Excel такое себе позволить не может и отбросит дробную часть до 100 пикселей. Когда VBA будет запрашивать высоту ряда в точках, Excel честно переведёт 100 пикселей в точки и вернёт 75.
В принципе мы уже подобрались к тому, чтобы написать класс на C#, который будет описывать информацию о высоте ряда:
class RowHeightInfo {
public ushort Value { get; set; } //высота ряда в целых пикселях, умноженная на 4.
public ushort Flags { get; set; } //дополнительные флаги
}
Вам пока что придётся поверить мне на слово, но в Excel высота ряда хранится именно так. Т.е., если задано, что высота ряда 75 точек, в пикселях это будет 100, то в Value будет хранится 400. Что обозначают все биты в Flags я до конца не выяснил (выяснять значения флагов сложно и долго), но знаю точно, что 0x4000 выставляется для рядов у которых высота задана вручную, а 0x2000 — выставляется у скрытых рядов. В целом у видимых рядов с заданной вручную высотой Flags чаще всего равняется 0x4005, а для рядов у которых высота высчитывается на основе форматирования Flags равняется либо 0xA, либо 0x800E.
Спрашиваем высоту ряда
Теперь в принципе можно взглянуть на метод из excel.exe, который возвращает высоту ряда по его индексу (спасибо HexRays за красивый код):
int __userpurge GetRowHeight@<eax>(signed int rowIndex@<edx>, SheetLayoutInfo *sheetLayoutInfo@<esi>, bool flag)
{
RowHeightInfo *rowHeightInfo; // eax
int result; // ecx
if ( sheetLayoutInfo->dword1A0 )
return sheetLayoutInfo->defaultFullRowHeightMul4 | (~(sheetLayoutInfo->defaultRowDelta2 >> 14 << 15) & 0x8000);
if ( rowIndex < sheetLayoutInfo->MinRowIndexNonDefault )
return sheetLayoutInfo->defaultFullRowHeightMul4 | (~(sheetLayoutInfo->defaultRowDelta2 >> 14 << 15) & 0x8000);
if ( rowIndex >= sheetLayoutInfo->MaxRowIndexNonDefault )
return sheetLayoutInfo->defaultFullRowHeightMul4 | (~(sheetLayoutInfo->defaultRowDelta2 >> 14 << 15) & 0x8000);
rowHeightInfo = GetRowHeightCore(sheetLayoutInfo, rowIndex);
if ( !rowHeightInfo )
return sheetLayoutInfo->defaultFullRowHeightMul4 | (~(sheetLayoutInfo->defaultRowDelta2 >> 14 << 15) & 0x8000);
result = 0;
if ( flag || !(rowHeightInfo->Flags & 0x2000) )
result = rowHeightInfo->Value;
if ( !(rowHeightInfo->Flags & 0x4000) )
result |= 0x8000u;
return result;
}
Что такое dword1A0 я так и не выяснил, т.к. не смог найти место где этот флаг выставляется 
Что такое defaultRowDelta2 для меня тоже до сих пор остаётся загадкой. Когда excel рассчитывает высоту ряда на основе формата, то представляет её как сумму двух чисел. defaultRowDelta2 — это второе число из этой суммы для стандартной высоты ряда. Значение параметра flag тоже загадочно, т.к. везде где я видел вызов этого метода в flag передавался false.
В этом методе также появляется класс SheetLayoutInfo. Я его назвал именно так, потому что в нём хранится много всякой информации о внешнем виде листа. В SheetLayoutInfo есть такие поля как:
- DefaultFullRowHeightMul4 — стандартная высота ряда;
- MinRowIndexNonDefault — индекс первого ряда, у которого высота отличается от стандартной;
- MaxRowIndexNonDefault — индекс ряда, следующего за последним, у которого высота отличается от стандартной;
- DefaultRowDelta2 — та самая часть от суммы стандартной высоты ряда.
- GroupIndexDelta — об этом позже
В принципе логика данного метода вполне понятна:
- Если индекс ряда меньше первого с нестандартной высотой, то возвращаем стандартную;
- Если индекс ряда больше последнего с нестандартной высотой, то возвращаем стандартную;
- В противном случае получаем объект rowHeightInfo для ряда из метода GetRowHeightCore;
- Если rowHeightInfo == null возвращаем стандартную высоту ряда;
- Тут магия с флагами, но в общем виде мы возвращаем то, что находится в rowHeightInfo.Value и выставляем 16-й бит в ответе, если высота ряда не была задана вручную.
Если переписать этот код на C#, то получится примерно следующее:
const ulong HiddenRowMask = 0x2000;
const ulong CustomHeightMask = 0x4000;
const ushort DefaultHeightMask = 0x8000;
public static ushort GetRowHeight(int rowIndex, SheetLayoutInfo sheetLayoutInfo) {
ushort defaultHeight = (ushort) (sheetLayoutInfo.DefaultFullRowHeightMul4 | (~(sheetLayoutInfo.DefaultRowDelta2 >> 14 << 15) & DefaultHeightMask));
if (rowIndex < sheetLayoutInfo.MinRowIndexNonDefault)
return defaultHeight;
if (rowIndex >= sheetLayoutInfo.MaxRowIndexNonDefault)
return defaultHeight;
RowHeightInfo rowHeightInfo = GetRowHeightCore(sheetLayoutInfo, rowIndex);
if (rowHeightInfo == null)
return defaultHeight;
ushort result = 0;
if ((rowHeightInfo.Flags & HiddenRowMask) == 0)
result = rowHeightInfo.Value;
if ((rowHeightInfo.Flags & CustomHeightMask) == 0)
result |= DefaultHeightMask;
return result;
}
Теперь можно взглянуть что происходит внутри GetRowHeightCore:
RowHeightInfo *__fastcall GetRowHeightCore(SheetLayoutInfo *sheetLayoutInfo, signed int rowIndex)
{
RowHeightInfo *result; // eax
RowsGroupInfo *rowsGroupInfo; // ecx
int rowInfoIndex; // edx
result = 0;
if ( rowIndex < sheetLayoutInfo->MinRowIndexNonDefault || rowIndex >= sheetLayoutInfo->MaxRowIndexNonDefault )
return result;
rowsGroupInfo = sheetLayoutInfo->RowsGroups[sheetLayoutInfo-GroupIndexDelta + (rowIndex >> 4)];
result = 0;
if ( !rowsGroupInfo )
return result;
rowInfoIndex = rowsGroupInfo->Indices[rowIndex & 0xF];
if ( rowInfoIndex )
result = (rowsGroupInfo + 8 * (rowInfoIndex + rowsGroupInfo->wordBA + rowsGroupInfo->wordBC - rowsGroupInfo->wordB8));
return result;
}
- Опять в начале Excel проверяет находится ли индекс ряда среди рядов с изменённой высотой и если нет, то возвращает null.
- Находит нужную группу рядов, если такой группы нет, то возвращает null.
- Получает индекс ряда в группе.
- Далее по индексу ряда находит нужный объект класса RowHeightInfo. wordBA, wordBC, wordB8 — какие-то константы. Они изменяются только вместе с историей. В принципе на понимание алгоритма они не влияют.
Тут стоит отклониться от темы и рассказать подробнее про RowsGroupInfo. Excel хранит RowHeightInfo группами по 16 штук, где i-я группа, представленная классом RowsGroupInfo, будет хранить в себе информацию о рядах с i × 16 до i × 16 + 15 включительно.
Но информация о высоте рядов в RowsGroupInfo хранится несколько необычным способом. Скорее всего из-за необходимости поддерживать историю в Excel.
В RowsGroupInfo есть три важных поля: Indices, HeightInfos, и RowsCount, второе в коде выше не видно (оно должно быть в этой строчке: (rowsGroupInfo + 8 × (…)), т.к. rowInfoIndex может принимать очень разные значения, я видел даже больше 1000 и я понятия не имею как в IDA задать такую структуру. Поле RowsCount вообще в коде выше не встречается, но именно там хранится сколько реально нестандартных рядов хранится в группе.
Кроме того, в SheetLayoutInfo есть GroupIndexDelta — разница между реальным индексом группы и индексом первой группы с изменённой высотой ряда.
В поле Indices хранятся смещения RowHeightInfo для каждого индекса ряда внутри группы. Они хранятся там по порядку, а вот в HeightInfos RowHeightInfo уже хранятся в порядке изменения.
Допустим у нас есть новый пустой лист и мы каким-то образом изменили высоту ряда номер 23. Это ряд лежит во второй группе из 16 рядов, тогда:
- Excel определит индекс группы для этого ряда. В текущем случае индекс будет равен 1 и изменит GroupIndexDelta = -1.
- Создаст для группы рядов объект класса RowsGroupInfo и положит его в sheetLayoutInfo->RowsGroups под индексом 0 (sheetLayoutInfo->GroupIndexDelta + 1);
- В RowsGroupInfo Excel выделит память под 16 4-х байтовых Indices, под RowsCount, wordBA, wordBC и wordB8 и т.д..;
- Потом Excel вычисляет индекс ряда в группе через операцию побитового И (это сильно быстрее чем брать остаток от деления): rowIndex & 0xF. Искомый индекс в группе будет равняться: 23 & 0xF = 7;
- После этого Excel получает смещение для индекса 7: offset = Indices[7]. Если offset = 0, то Excel выделяет 8 байт в конце RowsGroupInto, увеличивает RowsCount на единицу и записывает новое смещение в Indices[7]. В любом случае в конце Excel запишет по смещению в RowsGroupInfo информацию о новой высоте ряда и флагах.
Сам класс RowsGroupInfo на C# выглядел бы вот так:
class RowsGroupInfo {
public int[] Indices { get; }
public List<RowHeightInfo> HeightInfos { get; }
public RowsGroupInfo() {
Indices = new int[SheetLayoutInfo.MaxRowsCountInGroup];
HeightInfos = new List<RowHeightInfo>();
for (int i = 0; i < SheetLayoutInfo.MaxRowsCountInGroup; i++) {
Indices[i] = -1;
}
}
}
Метод GetRowHeightCore выглядел бы вот так:
static RowHeightInfo GetRowHeightCore(SheetLayoutInfo sheetLayoutInfo, int rowIndex) {
if (rowIndex < sheetLayoutInfo.MinRowIndexNonDefault || rowIndex >= sheetLayoutInfo.MaxRowIndexNonDefault)
return null;
RowsGroupInfo rowsGroupInfo = sheetLayoutInfo.RowsGroups[sheetLayoutInfo.GroupIndexDelta + (rowIndex >> 4)];
if (rowsGroupInfo == null)
return null;
int rowInfoIndex = rowsGroupInfo.Indices[rowIndex & 0xF];
return rowInfoIndex != -1 ? rowsGroupInfo.HeightInfos[rowInfoIndex] : null;
}
И вот так выглядел бы SetRowHeight (его код из excel.exe я не приводил):
public static void SetRowHeight(int rowIndex, ushort newRowHeight, ushort flags, SheetLayoutInfo sheetLayoutInfo) {
sheetLayoutInfo.MaxRowIndexNonDefault = Math.Max(sheetLayoutInfo.MaxRowIndexNonDefault, rowIndex + 1);
sheetLayoutInfo.MinRowIndexNonDefault = Math.Min(sheetLayoutInfo.MinRowIndexNonDefault, rowIndex);
int realGroupIndex = rowIndex >> 4;
if (sheetLayoutInfo.RowsGroups.Count == 0) {
sheetLayoutInfo.RowsGroups.Add(null);
sheetLayoutInfo.GroupIndexDelta = -realGroupIndex;
}
else if (sheetLayoutInfo.GroupIndexDelta + realGroupIndex < 0) {
int bucketSize = -(sheetLayoutInfo.GroupIndexDelta + realGroupIndex);
sheetLayoutInfo.RowsGroups.InsertRange(0, new RowsGroupInfo[bucketSize]);
sheetLayoutInfo.GroupIndexDelta = -realGroupIndex;
}
else if (sheetLayoutInfo.GroupIndexDelta + realGroupIndex >= sheetLayoutInfo.RowsGroups.Count) {
int bucketSize = sheetLayoutInfo.GroupIndexDelta + realGroupIndex - sheetLayoutInfo.RowsGroups.Count + 1;
sheetLayoutInfo.RowsGroups.AddRange(new RowsGroupInfo[bucketSize]);
}
RowsGroupInfo rowsGroupInfo = sheetLayoutInfo.RowsGroups[sheetLayoutInfo.GroupIndexDelta + realGroupIndex];
if (rowsGroupInfo == null) {
rowsGroupInfo = new RowsGroupInfo();
sheetLayoutInfo.RowsGroups[sheetLayoutInfo.GroupIndexDelta + realGroupIndex] = rowsGroupInfo;
}
int rowInfoIndex = rowsGroupInfo.Indices[rowIndex & 0xF];
RowHeightInfo rowHeightInfo;
if (rowInfoIndex == -1) {
rowHeightInfo = new RowHeightInfo();
rowsGroupInfo.HeightInfos.Add(rowHeightInfo);
rowsGroupInfo.Indices[rowIndex & 0xF] = rowsGroupInfo.HeightInfos.Count - 1;
}
else {
rowHeightInfo = rowsGroupInfo.HeightInfos[rowInfoIndex];
}
rowHeightInfo.Value = newRowHeight;
rowHeightInfo.Flags = flags;
}
Немного практики
После разобранного выше примера с изменением высоты ряда 23 в памяти Excel будет примерно такая картина (я задал ряду 23 высоту 75 точек):
sheetLayoutInfo
- DefaultFullRowHeightMul4 = 80
- DefaultRowDelta2 = 5
- MaxRowIndexNonDefault = 24
- MinRowIndexNonDefault = 23
- GroupIndexDelta = -1
- RowsGroups Count = 1
- [0] RowsGroupInfo
- HeightInfos Count = 1
- [0] RowHeightInfo
- Flags = 0x4005
- Value = 100
- Indices
- [0] = -1
- [1] = -1
- [2] = -1
- [3] = -1
- [4] = -1
- [5] = -1
- [6] = -1
- [7] = 0
- [8] = -1
- [9] = -1
- [10] = -1
- [11] = -1
- [12] = -1
- [13] = -1
- [14] = -1
- [15] = -1
Здесь и в следующем примере я буду выкладывать схематичное представление о том, как выглядят данные в памяти Excel, сделанное в Visual Studio из самописных классов, потому что прямой дамп из памяти не сильно информативен.
Теперь попробуем спрятать ряд 23. Для этого надо выставить бит 0x2000 у Flags. Будем изменять память на живую. Результат можно увидеть на этом видео: http://recordit.co/79vYIbwbzB.
При любом скрытии рядов Excel поступает также.
Теперь зададим высоту ряда не явно, а через формат ячейки. Пускай у ячейки A20 шрифт станет высотой 40 пунктов, тогда высота ячейки в точках станет 45,75 и в памяти Excel будет примерно такое:
sheetLayoutInfo
- DefaultFullRowHeightMul4 = 80
- DefaultRowDelta2 = 5
- MaxRowIndexNonDefault = 24
- MinRowIndexNonDefault = 20
- GroupIndexDelta = -1
- RowsGroups Count = 1
- [0] RowsGroupInfo
- HeightInfos Count = 2
- [0] RowHeightInfo
- Flags = 0x4005
- Value = 100
- [1] RowHeightInfo
- Flags = 0x800E
- Value = 244
- Indices
- [0] = -1
- [1] = -1
- [2] = -1
- [3] = -1
- [4] = 1
- [5] = -1
- [6] = -1
- [7] = 0
- [8] = -1
- [9] = -1
- [10] = -1
- [11] = -1
- [12] = -1
- [13] = -1
- [14] = -1
- [15] = -1
Можно заметить, что Excel всегда хранит высоту ряда, если она не стандартная. Даже если высота не задана явно, а рассчитывается на основе содержимого ячеек или формата, то Excel всё равно посчитает её один раз и занесёт результат в соответствующую группу.
Разбираемся со вставкой/удалением рядов
Интересно было бы разобрать что происходит при вставке/удалении рядов. Соответствующий код в excel.exe найти несложно, но разбирать его не было желания, можете сами взглянуть на часть из него:
sub_305EC930
Флаг a5 определяет какая именно сейчас происходит операция.
int __userpurge sub_305EC930@<eax>(int a1@<eax>, int a2@<edx>, int a3@<ecx>, int a4, int a5, int a6)
{
int v6; // esi
int v7; // ebx
int v8; // edi
int v9; // edx
int v10; // ecx
size_t v11; // eax
_WORD *v12; // ebp
size_t v13; // eax
size_t v14; // eax
int v15; // eax
unsigned __int16 *v16; // ecx
_WORD *v17; // eax
_WORD *v18; // ecx
int v19; // edx
__int16 v20; // bx
int v21; // eax
_WORD *v22; // ecx
int v24; // edx
int v25; // eax
int v26; // esi
int v27; // ebx
size_t v28; // eax
int v29; // ebp
size_t v30; // eax
int v31; // esi
size_t v32; // eax
int v33; // eax
unsigned __int16 *v34; // ecx
int v35; // eax
_WORD *v36; // edx
_WORD *v37; // ecx
int v38; // eax
__int16 v39; // bx
int v40; // eax
_WORD *v41; // ecx
int v42; // [esp+10h] [ebp-48h]
int v43; // [esp+10h] [ebp-48h]
int v44; // [esp+14h] [ebp-44h]
char v45; // [esp+14h] [ebp-44h]
int Dst[16]; // [esp+18h] [ebp-40h]
int v47; // [esp+5Ch] [ebp+4h]
int v48; // [esp+60h] [ebp+8h]
v6 = a1;
v7 = a1 & 0xF;
v8 = a2;
if ( !a5 )
{
v24 = a4 - a1;
v25 = a1 - a3;
v43 = a4 - v6;
if ( v7 >= v25 )
v7 = v25;
v47 = a4 - v7;
v26 = v6 - v7;
v27 = v7 + 1;
v48 = v27;
if ( !v8 )
return v27;
v28 = 4 * v24;
if ( (4 * v24) > 0x40 )
v28 = 64;
v45 = v27 + v26;
v29 = (v27 + v26) & 0xF;
memmove(Dst, (v8 + 4 * v29), v28);
v30 = 4 * v27;
if ( (4 * v27) > 0x40 )
v30 = 64;
v31 = v26 & 0xF;
memmove((v8 + 4 * (v47 & 0xF)), (v8 + 4 * v31), v30);
v32 = 4 * v43;
if ( (4 * v43) > 0x40 )
v32 = 64;
memmove((v8 + 4 * v31), Dst, v32);
if ( !a6 )
return v48;
v33 = v29;
if ( v29 < v29 + v43 )
{
v34 = (v8 + 4 * v29 + 214);
do
{
Dst[v33++] = *v34 >> 15;
v34 += 2;
}
while ( v33 < v29 + v43 );
}
v35 = (v45 - 1) & 0xF;
if ( v35 >= v31 )
{
v36 = (v8 + 4 * ((v27 + v47 - 1) & 0xF) + 214);
v37 = (v8 + 4 * ((v45 - 1) & 0xF) + 214);
v38 = v35 - v31 + 1;
do
{
v39 = *v37 ^ (*v37 ^ *v36) & 0x7FFF;
v37 -= 2;
*v36 = v39;
v36 -= 2;
--v38;
}
while ( v38 );
v27 = v48;
}
v40 = v31;
if ( v31 >= v31 + v43 )
return v27;
v41 = (v8 + 4 * v31 + 214);
do
{
*v41 = *v41 & 0x7FFF | (LOWORD(Dst[v40++]) << 15);
v41 += 2;
}
while ( v40 < v31 + v43 );
return v27;
}
v9 = a1 - a4;
v10 = a3 - a1;
v42 = a1 - a4;
v48 = 16 - v7;
if ( 16 - v7 >= v10 )
v48 = v10;
if ( !v8 )
return v48;
v11 = 4 * v9;
if ( (4 * v9) > 0x40 )
v11 = 64;
v12 = (v8 + 4 * (a4 & 0xF));
v44 = a4 & 0xF;
memmove(Dst, v12, v11);
v13 = 4 * v48;
if ( (4 * v48) > 0x40 )
v13 = 64;
memmove(v12, (v8 + 4 * v7), v13);
v14 = 4 * v42;
if ( (4 * v42) > 0x40 )
v14 = 64;
memmove((v8 + 4 * ((a4 + v48) & 0xF)), Dst, v14);
if ( !a6 )
return v48;
v15 = a4 & 0xF;
if ( v44 < v44 + v42 )
{
v16 = (v8 + 4 * v44 + 214);
do
{
Dst[v15++] = *v16 >> 15;
v16 += 2;
}
while ( v15 < v44 + v42 );
}
if ( v7 < v48 + v7 )
{
v17 = (v8 + 4 * v7 + 214);
v18 = v12 + 107;
v19 = v48;
do
{
v20 = *v17 ^ (*v17 ^ *v18) & 0x7FFF;
v17 += 2;
*v18 = v20;
v18 += 2;
--v19;
}
while ( v19 );
}
v21 = a4 & 0xF;
if ( v44 >= v44 + v42 )
return v48;
v22 = (v8 + 4 * (v44 + v48) + 214);
do
{
*v22 = *v22 & 0x7FFF | (LOWORD(Dst[v21++]) << 15);
v22 += 2;
}
while ( v21 < v44 + v42 );
return v48;
}
К тому же по внешнему виду можно примерно понять что там происходит, а остальное добить по косвенным признакам.
Попытаемся обозначить эти косвенные признаки. Сначала зададим высоту для рядов с 16 по 64 включительно в случайном порядке. Потом перед рядом под индексом 39 вставим новый ряд. Новый ряд будет копировать высоту у ряда 38.
Посмотрим на информацию в группах рядов до и после добавления ряда, я выделил жирным различия:
| До добавления ряда | После добавления ряда |
|---|---|
| Смещения в первой группе: | Смещения в первой группе: |
| 0E, 04, 07, 00, 05, 0A, 09, 0F, 03, 06, 08, 0D, 01, 0B, 0C, 02 | 0E, 04, 07, 00, 05, 0A, 09, 0F, 03, 06, 08, 0D, 01, 0B, 0C, 02 |
| Значения высот рядов в первой группе: | Значения высот рядов в первой группе: |
| 05, 2B, 35, 45, 4B, 50, 5B, 6B, 7B, 8B, A5, AB, B0, B5, E0, 100 | 05, 2B, 35, 45, 4B, 50, 5B, 6B, 7B, 8B, A5, AB, B0, B5, E0, 100 |
| Смещения во второй группе: | Смещения во второй группе: |
| 06, 02, 0E, 09, 01, 07, 0F, 0C, 00, 0A, 04, 0B, 03, 08, 0D, 05 | 06, 02, 0E, 09, 01, 07, 0F, 05, 0C, 00, 0A, 04, 0B, 03, 08, 0D |
| Значения высот рядов во второй группе: | Значения высот рядов во второй группе: |
| 10, 15, 20, 25, 30, 75, 85, 90, 9B, A0, C5, CB, D0, D5, E5, F0 | 10, 15, 20, 25, 30, F0, 85, 90, 9B, A0, C5, CB, D0, D5, E5, F0 |
| Смещения в третьей группе: | Смещения в третьей группе: |
| 0C, 08, 0E, 07, 0A, 01, 06, 0F, 09, 0D, 00, 05, 0B, 02, 04, 03 | 03, 0C, 08, 0E, 07, 0A, 01, 06, 0F, 09, 0D, 00, 05, 0B, 02, 04 |
| Значения высот рядов в третьей группе: | Значения высот рядов в третьей группе: |
| 0B, 1B, 3B, 40, 55, 60, 65, 70, 80, 95, BB, C0, DB, EB, F5, FB | 0B, 1B, 3B, 75, 55, 60, 65, 70, 80, 95, BB, C0, DB, EB, F5, FB |
| Смещения в четвёртой группе: | Смещения в четвёртой группе: |
| _ | 00 |
| Значения высот рядов в четвёртой группе: | Значения высот рядов в четвёртой группе: |
| _ | 40 |
Получается то, что и ожидалось: Excel вставляет во вторую группу новый ряд с индексом 7 (39 & 0xF), у которого смещение равняется 0x05, копирует высоту ряда у индекса 6, при этом последний ряд, который был со смещением 05, выталкивается в следующую группу, а оттуда последний ряд выталкивается в четвёртую и т.д.
Теперь посмотрим, что происходит если удалить 29-й ряд.
| До удаления ряда | После удаления ряда |
|---|---|
| Смещения в первой группе: | Смещения в первой группе: |
| 0E, 04, 07, 00, 05, 0A, 09, 0F, 03, 06, 08, 0D, 01, 0B, 0C, 02 | 0E, 04, 07, 00, 05, 0A, 09, 0F, 03, 06, 08, 0D, 01, 0C, 02, 0B |
| Значения высот рядов в первой группе: | Значения высот рядов в первой группе: |
| 05, 2B, 35, 45, 4B, 50, 5B, 6B, 7B, 8B, A5, AB, B0, B5, E0, 100 | 05, 2B, 35, 45, 4B, 50, 5B, 6B, 7B, 8B, A5, 85, B0, B5, E0, 100 |
| Смещения во второй группе: | Смещения во второй группе: |
| 06, 02, 0E, 09, 01, 07, 0F, 05, 0C, 00, 0A, 04, 0B, 03, 08, 0D | 02, 0E, 09, 01, 07, 0F, 05, 0C, 00, 0A, 04, 0B, 03, 08, 0D, 06 |
| Значения высот рядов во второй группе: | Значения высот рядов во второй группе: |
| 10, 15, 20, 25, 30, F0, 85, 90, 9B, A0, C5, CB, D0, D5, E5, F0 | 10, 15, 20, 25, 30, F0, 75, 90, 9B, A0, C5, CB, D0, D5, E5, F0 |
| Смещения в третьей группе: | Смещения в третьей группе: |
| 03, 0C, 08, 0E, 07, 0A, 01, 06, 0F, 09, 0D, 00, 05, 0B, 02, 04 | 0C, 08, 0E, 07, 0A, 01, 06, 0F, 09, 0D, 00, 05, 0B, 02, 04, 03 |
| Значения высот рядов в третьей группе: | Значения высот рядов в третьей группе: |
| 0B, 1B, 3B, 75, 55, 60, 65, 70, 80, 95, BB, C0, DB, EB, F5, FB | 0B, 1B, 3B, 40, 55, 60, 65, 70, 80, 95, BB, C0, DB, EB, F5, FB |
| Смещения в четвёртой группе: | Смещения в четвёртой группе: |
| 00 | 00 |
| Значения высот рядов в четвёртой группе: | Значения высот рядов в четвёртой группе: |
| 40 | 50 |
В принципе при удалении ряда происходят операции обратные вставке. При этом четвёртая группа продолжает существовать и значение высоты ряда там заполняется стандартной высотой с соответствующим флагом — 0x8005.
Этих данных достаточно для того, чтобы воспроизвести этот алгоритм на C#:
InsertRow
public static void InsertRow(SheetLayoutInfo sheetLayoutInfo, int rowIndex) {
if (rowIndex >= sheetLayoutInfo.MaxRowIndexNonDefault)
return;
RowHeightInfo etalonRowHeightInfo = GetRowHeightCore(sheetLayoutInfo, rowIndex);
RowHeightInfo newRowHeightInfo = etalonRowHeightInfo != null ? etalonRowHeightInfo.Clone() : CreateDefaultRowHeight(sheetLayoutInfo);
int realGroupIndex = (rowIndex + 1) >> 4;
int newRowInGroupIndex = (rowIndex + 1) & 0xF;
int groupIndex;
for (groupIndex = realGroupIndex + sheetLayoutInfo.GroupIndexDelta; groupIndex < sheetLayoutInfo.RowsGroups.Count; groupIndex++, newRowInGroupIndex = 0) {
if (groupIndex < 0)
continue;
if (groupIndex == SheetLayoutInfo.MaxGroupsCount)
break;
RowsGroupInfo rowsGroupInfo = sheetLayoutInfo.RowsGroups[groupIndex];
if (rowsGroupInfo == null) {
if ((newRowHeightInfo.Flags & CustomHeightMask) == 0)
continue;
rowsGroupInfo = new RowsGroupInfo();
sheetLayoutInfo.RowsGroups[groupIndex] = rowsGroupInfo;
}
int rowInfoIndex = rowsGroupInfo.Indices[newRowInGroupIndex];
RowHeightInfo lastRowHeightInGroup;
if (rowInfoIndex == -1 || rowsGroupInfo.HeightInfos.Count < SheetLayoutInfo.MaxRowsCountInGroup) {
lastRowHeightInGroup = GetRowHeightCore(sheetLayoutInfo, ((groupIndex - sheetLayoutInfo.GroupIndexDelta) << 4) + SheetLayoutInfo.MaxRowsCountInGroup - 1);
Array.Copy(rowsGroupInfo.Indices, newRowInGroupIndex, rowsGroupInfo.Indices, newRowInGroupIndex + 1, SheetLayoutInfo.MaxRowsCountInGroup - 1 - newRowInGroupIndex);
rowsGroupInfo.HeightInfos.Add(newRowHeightInfo);
rowsGroupInfo.Indices[newRowInGroupIndex] = rowsGroupInfo.HeightInfos.Count - 1;
}
else {
int lastIndex = rowsGroupInfo.Indices[SheetLayoutInfo.MaxRowsCountInGroup - 1];
lastRowHeightInGroup = rowsGroupInfo.HeightInfos[lastIndex];
Array.Copy(rowsGroupInfo.Indices, newRowInGroupIndex, rowsGroupInfo.Indices, newRowInGroupIndex + 1, SheetLayoutInfo.MaxRowsCountInGroup - 1 - newRowInGroupIndex);
rowsGroupInfo.HeightInfos[lastIndex] = newRowHeightInfo;
rowsGroupInfo.Indices[newRowInGroupIndex] = lastIndex;
}
newRowHeightInfo = lastRowHeightInGroup ?? CreateDefaultRowHeight(sheetLayoutInfo);
}
if ((newRowHeightInfo.Flags & CustomHeightMask) != 0 && groupIndex != SheetLayoutInfo.MaxGroupsCount) {
SetRowHeight(((groupIndex - sheetLayoutInfo.GroupIndexDelta) << 4) + newRowInGroupIndex, newRowHeightInfo.Value, newRowHeightInfo.Flags, sheetLayoutInfo);
}
else {
sheetLayoutInfo.MaxRowIndexNonDefault = Math.Min(sheetLayoutInfo.MaxRowIndexNonDefault + 1, SheetLayoutInfo.MaxRowsCount);
}
}
RemoveRow
public static void RemoveRow(SheetLayoutInfo sheetLayoutInfo, int rowIndex) {
if (rowIndex >= sheetLayoutInfo.MaxRowIndexNonDefault)
return;
int realGroupIndex = rowIndex >> 4;
int newRowInGroupIndex = rowIndex & 0xF;
int groupIndex;
for (groupIndex = realGroupIndex + sheetLayoutInfo.GroupIndexDelta; groupIndex < sheetLayoutInfo.RowsGroups.Count; groupIndex++, newRowInGroupIndex = 0) {
if (groupIndex < -1)
continue;
if (groupIndex == -1) {
sheetLayoutInfo.RowsGroups.Insert(0, null);
sheetLayoutInfo.GroupIndexDelta++;
groupIndex = 0;
}
if (groupIndex == SheetLayoutInfo.MaxGroupsCount)
break;
var newRowHeightInfo = groupIndex == SheetLayoutInfo.MaxGroupsCount - 1 ? null : GetRowHeightCore(sheetLayoutInfo, (groupIndex - sheetLayoutInfo.GroupIndexDelta + 1) << 4);
RowsGroupInfo rowsGroupInfo = sheetLayoutInfo.RowsGroups[groupIndex];
if (rowsGroupInfo == null) {
if (newRowHeightInfo == null || (newRowHeightInfo.Flags & CustomHeightMask) == 0)
continue;
rowsGroupInfo = new RowsGroupInfo();
sheetLayoutInfo.RowsGroups[groupIndex] = rowsGroupInfo;
}
if (newRowHeightInfo == null) {
newRowHeightInfo = CreateDefaultRowHeight(sheetLayoutInfo);
}
int rowInfoIndex = rowsGroupInfo.Indices[newRowInGroupIndex];
if (rowInfoIndex == -1) {
for (int i = newRowInGroupIndex; i < SheetLayoutInfo.MaxRowsCountInGroup - 1; i++) {
rowsGroupInfo.Indices[i] = rowsGroupInfo.Indices[i + 1];
}
rowsGroupInfo.HeightInfos.Add(newRowHeightInfo);
rowsGroupInfo.Indices[SheetLayoutInfo.MaxRowsCountInGroup - 1] = rowsGroupInfo.HeightInfos.Count - 1;
}
else {
for(int i = newRowInGroupIndex; i < rowsGroupInfo.HeightInfos.Count - 1; i++) {
rowsGroupInfo.Indices[i] = rowsGroupInfo.Indices[i + 1];
}
rowsGroupInfo.Indices[rowsGroupInfo.HeightInfos.Count - 1] = rowInfoIndex;
rowsGroupInfo.HeightInfos[rowInfoIndex] = newRowHeightInfo;
}
}
if(rowIndex <= sheetLayoutInfo.MinRowIndexNonDefault) {
sheetLayoutInfo.MinRowIndexNonDefault = Math.Max(sheetLayoutInfo.MinRowIndexNonDefault - 1, 0);
}
}
Весь вышеописанный код вы можете найти на GitHub
Выводы
Код Excel уже не в первый раз удивляет интересными приёмами. В этот раз я узнал как он хранит информацию о высотах рядов. Если сообществу будет интересно, то в следующей статье покажу как Excel считает высоту диапазона ячеек (спойлер: там что-то похожее на SQRT-декомпозицию, но почему-то без кеширования сумм), там же можно будет увидеть как он применяет масштабирование в целых числах.
Табличный процессор имеет обширное количество функций, которые позволяют пользователю проводить различные виды обработки информации. Функция ИНДЕКС помогает реализовывать поиск значений в обозначенной локации заданного диапазона, а затем осуществляет вывод результата в выделенном секторе. В статье будет подробно рассмотрено, как применять функцию ИНДЕКС разнообразными методами.
Содержание
- Описание функции ИНДЕКС
- Что возвращает функция
- Синтаксис
- Аргументы функции
- Дополнительная информация
- Как работает функция ИНДЕКС в Excel?
- Функция ИНДЕКС в Excel пошаговая инструкция
- Функция ИНДЕКС для массивов
- Функция ИНДЕКС для ссылок
- Использование с оператором СУММ
- Сочетание с функцией ПОИСКПОЗ
- Обработка нескольких таблиц
- Примеры использования функции ИНДЕКС в Excel
- Ошибки
- Заключение
Описание функции ИНДЕКС
ИНДЕКС – интегрированная в табличный процессор функция, которая позволяет получить информацию из таблицы при том условии, что пользователь знает номер строчки и столбика, в котором располагается эта информация.
Что возвращает функция
Данная функция осуществляет возвращение значений из определенной строчки и столбика таблицы.
Синтаксис
Существует четыре вариации синтаксиса этой функции. Две русские версии:
- =ИНДЕКС(массив; номер_строки; [номер_столбца]).
- =ИНДЕКС(ссылка; номер_строки; [номер_столбца]; [номер_области]).
Две английские версии:
- =INDEX (array, row_num, [col_num]).
- =INDEX (array, row_num, [col_num], [area_num]).
Аргументы функции
Разберемся более подробно, что означает каждый из приведенных ниже аргументов:
- array – обозначает диапазон секторов или массив данных, по которому будет осуществляться поиск;
- row_num – обозначает номер строчки, где располагаются необходимые значения;
- [col_num] – обозначает номер столбика, где располагаются необходимые значения. Этот параметр является необязательным. В случае, когда в функции ИНДЕКС не описан аргумент номера строчки, этот параметр нужно указывать;
- [area_num] – используется в тех случаях, когда массив имеет некоторое количество диапазонов. Параметр является необязательным и применяется для осуществления выбора абсолютно всех диапазонов.
Дополнительная информация
Рассмотрим некоторые особенности функции, которые необходимо знать при ее использовании:
- Когда номер столбика или строчки равен нулю, функция осуществит возврат данных всего столбика или строчки.
- В случае применения функции ИНДЕКС перед ссылкой на ячейку произойдет возврат ссылки на ячейку вместо значения. Более подробно об этом поговорим в примерах, расположенных ниже.
- Обычно функция ИНДЕКС применяется вместе с функцией ПОИСКПОЗ.
- Функция ИНДЕКС отличается от функции ВПР тем, что она осуществляет возврат данных как слева от нужного показателя, так и справа.
- ИНДЕКС можно применять в 2-х различных видах: «Ссылки на данные» и «Массив данных».
- «Массив» применяется в тех случаях, когда необходимо отыскать показатели, основанные на определенных номерах столбиков и строчек табличной информации.
- «Ссылки на данные» применяются в тех случаях, когда необходимо отыскать показатели в некотором количестве таблиц, чтобы выбрать табличку, а затем помочь функции осуществить поиск по номеру столбца и строки.
Как работает функция ИНДЕКС в Excel?
Рассмотрим процесс работы функции ИНДЕКС с различными типами данных в табличном процессоре.
Функция ИНДЕКС в Excel пошаговая инструкция
Пошаговая инструкция для работы с функцией ИНДЕКС имеет различный вид в зависимости от того, для чего она применяется. Ее можно использовать для работы с массивами, ссылками и другими вспомогательными операторами.
Функция ИНДЕКС для массивов
К примеру, есть табличка с названиями продукции, ее стоимостью, числом и конечной суммой.
Цель: в выделенном секторе показать название пятой в списке позиции. Пошаговая инструкция выглядит так:
- Кликаем на сектор, в который желаем в дальнейшем вывести результат манипуляций. Щелкаем кнопку «Вставить функцию», располагающуюся рядом со строкой для ввода формул.
- На дисплее открылось окошко под названием «Вставка функции». Раскрываем список, находящийся рядом с надписью «Категория:», и жмем «Ссылки и массивы». Далее в окошке с перечнем функций выбираем «ИНДЕКС». После проведения всех действий щелкаем на кнопочку «ОК».
- На экране появилось маленькое окошко, предлагающее выбрать набор аргументов. Выбираем 1-й предложенный вариант и нажимаем «ОК».
- В следующем окошке необходимо указать аргументы. В поле «Массив» вводим диапазон, в рамках которого будет осуществляться работа функции. Координаты можно вписать самостоятельно или же путем выделения необходимой области на рабочем листе при помощи зажатой ЛКМ.
- В поле «Номер_строки» вбиваем число 5, так как этого требует поставленная перед нами задача.
- В поле «Номер_столбца» вбиваем цифру 1, так как названия значений располагаются в 1-м столбике массива.
- После проведения всех настроек жмем «ОК».
- В выбранном секторе появился итоговый результат.
Обратите внимание! Один из аргументов можно не заполнять в случае, если массив является одномерным.
Такие действия выглядят следующим образом:
- В строке «Массив» необходимо выделить только ячейки первого столбика. Вводим номер строки – 5, а номер столбика не заполняем, потому что массив является одномерным.
- Щелкаем на «ОК». В итоге, в выделенном секторе получаем аналогичный результат.
Функция ИНДЕКС для ссылок
Функция ИНДЕКС может осуществлять свою работу сразу с некоторым количеством таблиц. Для реализации этого действия необходим перечень значений для ссылок с полем «Номер_области». К примеру, мы имеем четыре таблички. В них располагаются данные по продажам за различный промежуток времени.
Цель: выявить количество продаж в 4-й позиции за 2-й квартал в штуках. Пошаговое руководство выглядит следующим образом:
- Кликаем на сектор, в который желаем в дальнейшем вывести результат манипуляций. Щелкаем кнопку «Вставить функцию», располагающуюся рядом со строчкой для ввода формул.
- На дисплее открылось окно под названием «Вставка функции». Раскрываем список, находящийся рядом с надписью «Категория:», и жмем «Ссылки и массивы». Далее в окне с перечнем функций выбираем «ИНДЕКС». После проведения всех действий нажимаем «ОК».
- На экране появилось маленькое окошко, предлагающее выбрать набор аргументов. Выбираем второй предложенный вариант и нажимаем «ОК».
- В следующем окошке необходимо указать аргументы. В поле «Ссылка» вводим те же значения, которые вводили в поле «Массив» в предыдущем примере. Главное отличие – указываем не один диапазон, а сразу четыре, разделяя их знаком «;». После описания необходимо поставить «(» в начале и «)» в конце.
- В поле «Номер_строки» вводим значение 4, согласно условию нашей задачи.
- В строчку «Номер_столбца» вводим значение 3, потому что нам необходимо выяснить количество продаж в штуках.
- В строку «Номер области» вводим значение 2, потому как по условию задачи нам необходимо узнать информацию по второму кварталу.
- После проведения всех манипуляций щелкаем на кнопку «ОК». Готово, выбранном секторе появился необходимый нам ответ.
Использование с оператором СУММ
Функцию ИНДЕКС часто применяют совместно с оператором СУММ. Общий вид оператора: =СУММ(Адрес_массива). Применив СУММ, к рассматриваемой нами табличке, мы сможем получить итоговую сумму. Формула для подсчета суммы будет выглядеть следующим образом: =СУММ(D2:D9).
Можно немного отредактировать формулу, встроив в нее функцию ИНДЕКС. Пошаговое руководство выглядит следующим образом:
- Для первого аргумента оператора СУММ выставляем координаты сектора, являющегося точкой начала суммирующего диапазона.
- 2-й аргумент задается при помощи функции ИНДЕКС. Кликаем на строчку для ввода формул и вбиваем следующее значение: =СУММ(D2:ИНДЕКС(D2:D9;8)). Число 8 говорит о том, что мы выставляем ограничение для выбранного диапазона между секторами D2 и D9.
- Жмем на клавишу «Enter», чтобы вывести конечный результат в выделенном изначально секторе.
Сочетание с функцией ПОИСКПОЗ
Переходим к разбору более сложных задач. Ниже будет рассмотрен пример использования функции ИНДЕКС с оператором ПОИСКПОЗ. ПОИСКПОЗ позволяет осуществить возврат указанного показателя в выделенном диапазоне секторов. Общий вид формулы: =ПОИСКПОЗ(Искомое_значение,Просматриваемый_массив,[Тип_сопоставления]). Разберем каждый показатель функции более подробно:
- Искомое значение. Этот аргумент указывает значение, которое нужно отыскать в выделенной области.
- Просматриваемый массив. Область секторов для поиска искомого показателя.
- Тип сопоставления. Аргумент не является обязательным и применяется для более точного поиска.
Для наглядности использования двух функций разберем все на конкретных примерах. Возьмем ту же таблицу, которую мы рассматривали в предыдущих примерах. Около нее располагается маленькая табличка, в которой находится по одному пустому значению для названия и цены. Цель: применяя ПОИСКПОЗ и ИНДЕКС, реализовать добавление в сектор G2 функции, выводящей определенное значение в зависимости от указанного в секторе названия. Пошаговое руководство выглядит так:
- Первоначально заполняем ячейку F1.
- Кликаем на сектор, в который желаем в дальнейшем вывести результат манипуляций. Щелкаем кнопку «Вставить функцию», располагающуюся рядом со строкой для ввода формул.
- На дисплее открылось окно под названием «Вставка функции». Раскрываем список, находящийся рядом с надписью «Категория:», и жмем «Ссылки и массивы». Далее в окошке с перечнем функций выбираем «ИНДЕКС». После проведения всех действий щелкаем на «ОК».
- На экране появилось маленькое окошко, предлагающее выбрать набор аргументов. Выбираем первый предложенный вариант и нажимаем «ОК».
- В строку «Массив» вводим сектор столбика, в котором располагается стоимость позиций.
- В строчку «Номер_строки» добавляем функцию ПОИСКПОЗ. Для реализации данного действия нажимаем на маленькую стрелочку, находящуюся около элемента «Вставить функцию». Раскрылся список, где нужно выбрать «Другие функции». Появилось новое окошко «Мастер функций», в котором нажимаем «Ссылки и массивы», а затем выбираем ПОИСКПОЗ. После проведения всех манипуляций жмем «ОК».
- В поле «Искомое_значение» вводим координаты ячейки, по наполнению которой будет осуществляться поиск в главном массиве. В поле «Просматриваемый_массив» вбиваем диапазон для поиска искомого показателя. Вводим 0 в поле «Тип_сопоставления».
- В строке для ввода формул необходимо кликнуть на «ИНДЕКС».
- На экране в очередной раз отобразился перечень аргументов. Замечаем, что показатели автоматом заполнились необходимыми данными. Ничего не трогаем и кликаем на «ОК». Стоит заметить, что поле «Номер_строки» можно самостоятельно заполнить, используя синтаксис оператора ПОИСКПОЗ.
- В итоге мы получили в выделенном секторе необходимый результат – стоимость позиции. Различные изменения стоимости в главной таблице будут отражаться в этой ячейке. Это же правило работает и с изменением наименования во вспомогательной табличке.
Обработка нескольких таблиц
Рассмотри процесс обработки нескольких таблиц. К примеру, у нас есть 3 таблички. В них отображается зарплата сотрудников по месяцам. Цель: выявить зарплату второго сотрудника за 3-й месяц. Пошаговое руководство выглядит следующим образом:
- Кликаем на ячейку, в которую желаем в дальнейшем вывести результат манипуляций. Щелкаем кнопку «Вставить функцию», располагающуюся рядом со строкой для ввода формул.
- На дисплее открылось окошко под названием «Вставка функции». Раскрываем список, находящийся рядом с надписью «Категория:», и нажимаем «Ссылки и массивы». Далее в окошке с перечнем функций выбираем «ИНДЕКС». После проведения всех действий щелкаем на кнопку «ОК».
- На экране появилось маленькое окошко, предлагающее выбрать набор аргументов. Выбираем 2-й предложенный вариант и нажимаем «ОК».
- В строку «Ссылка» вводим координаты каждого диапазона. В строчку «Номер строки» вбиваем число 2, потому как мы осуществляем поиск 2-й фамилии в перечне. В строчку «Номер столбца» вводим число 3. В строку «Номер области» тоже вбиваем число 3. После проведения всех манипуляций кликаем на «ОК».
- В выбранный заранее сектор вывелись необходимые результаты.
Примеры использования функции ИНДЕКС в Excel
Дополнительно разберем еще один пример использования. Например, у нас есть следующая табличная информация:
Чтобы узнать результат Андрея по дисциплине «Физика», необходимо применить следующую формулу: =ИНДЕКС($B$3:$E$9;3;2). Здесь мы произвели определение показателей нужного диапазона: $B$3:$E$9. Цифра 3 означает номер строчки, где располагается результат Андрея. Цифра 2 означает номер столбца, где располагается дисциплина «Физика».
Ошибки
Функция ИНДЕКС выводит ошибку, если один из аргументов выходит за границы диапазона.
Ошибка возникает, если табличный процессор не понимает, какой сектор необходимо вернуть.
Заключение
Фунция ИНДЕКС – эффективный оператор в табличном процессоре Эксель, позволяющий реализовывать огромный перечень разнообразных действий. Изучив работу с этим оператором, можно значительно ускорить процесс работы с большими объемами информации.
Оцените качество статьи. Нам важно ваше мнение:
Вы когда-нибудь пытались создать порядковый номер строки для каждой группы на листе Excel, как показано ниже? Обычно вы можете создать формулу для решения этой задачи. Но в этой статье я расскажу, как справиться с этой задачей с помощью Power Query в Excel.
Power Query: создайте номер строки для каждой группы в Excel
Чтобы сгенерировать порядковые номера для каждой группы данных, Power Query может оказать вам услугу. Пожалуйста, выполните следующие действия:
1. Выберите диапазон данных, в который вы хотите вставить номер строки. В Excel 2019 и Excel 365 щелкните Данные > Из таблицы/диапазона, см. снимок экрана:
Внимание: в Excel 2016 и Excel 2021 нажмите Данные > Из таблицы, см. снимок экрана:
2. В Создать таблицу диалоговое окно, нажмите OK кнопка для создания таблицы, см. скриншот:
3. А потом в открытом Редактор Power Query выберите столбец, который вы хотите использовать для группировки таблицы, затем щелкните его правой кнопкой мыши. А затем выберите Группа по из контекстного меню см. снимок экрана:
4. В Группа по диалоговое окно:
- Выберите имя столбца, на основе которого вы хотите вставить номер строки, из раскрывающегося списка;
- Выберите Все строки из файла Эксплуатация раскрывающийся список;
- Нажмите OK кнопку.
5. Теперь вернитесь к Редактор Power Query окна, нажмите Добавить столбец > Пользовательский столбец, см. снимок экрана:
6. В Пользовательский столбец диалоговое окно, используя Таблица.AddIndexColumn как показано ниже:
- Введите новое имя столбца в поле Имя нового столбца текстовое окно;
- Затем введите эту формулу: =Таблица.AddIndexColumn([Количество],»Индекс»,1) в Формула пользовательского столбца коробка;
- Наконец, нажмите OK кнопку.
Внимание: В приведенной выше формуле [Считать] — это имя столбца, созданного вами на шаге 4, измените его по своему усмотрению.
7. Теперь вернитесь к Редактор Power Query окно, вы должны удалить все остальные столбцы и оставить только последний созданный вами столбец. Щелкните правой кнопкой мыши имя последнего созданного столбца, выберите Удалить другие столбцы, см. снимок экрана:
8. Затем разверните этот столбец, нажмите кнопку Расширьте значок рядом с заголовком столбца. В развернутом поле отметьте Расширьте , а затем отметьте все имена столбцов из списка и снимите флажок Использовать исходное имя столбца в качестве префикса. И, наконец, нажмите OK кнопка. Смотрите скриншот:
9. И теперь вы можете видеть, что номера индексов строк отображаются, как показано ниже:
10. Затем нажмите Главная > Закрыть и загрузить > Закрыть и загрузить чтобы загрузить данные на новый лист, см. скриншоты:
Лучшие инструменты для работы в офисе
Kutools for Excel Решит большинство ваших проблем и повысит вашу производительность на 80%
- Снова использовать: Быстро вставить сложные формулы, диаграммы и все, что вы использовали раньше; Зашифровать ячейки с паролем; Создать список рассылки и отправлять электронные письма …
- Бар Супер Формулы (легко редактировать несколько строк текста и формул); Макет для чтения (легко читать и редактировать большое количество ячеек); Вставить в отфильтрованный диапазон…
- Объединить ячейки / строки / столбцы без потери данных; Разделить содержимое ячеек; Объединить повторяющиеся строки / столбцы… Предотвращение дублирования ячеек; Сравнить диапазоны…
- Выберите Дубликат или Уникальный Ряды; Выбрать пустые строки (все ячейки пустые); Супер находка и нечеткая находка во многих рабочих тетрадях; Случайный выбор …
- Точная копия Несколько ячеек без изменения ссылки на формулу; Автоматическое создание ссылок на несколько листов; Вставить пули, Флажки и многое другое …
- Извлечь текст, Добавить текст, Удалить по позиции, Удалить пробел; Создание и печать промежуточных итогов по страницам; Преобразование содержимого ячеек в комментарии…
- Суперфильтр (сохранять и применять схемы фильтров к другим листам); Расширенная сортировка по месяцам / неделям / дням, периодичности и др .; Специальный фильтр жирным, курсивом …
- Комбинируйте книги и рабочие листы; Объединить таблицы на основе ключевых столбцов; Разделить данные на несколько листов; Пакетное преобразование xls, xlsx и PDF…
- Более 300 мощных функций. Поддерживает Office/Excel 2007-2021 и 365. Поддерживает все языки. Простое развертывание на вашем предприятии или в организации. Полнофункциональная 30-дневная бесплатная пробная версия. 60-дневная гарантия возврата денег.
Вкладка Office: интерфейс с вкладками в Office и упрощение работы
- Включение редактирования и чтения с вкладками в Word, Excel, PowerPoint, Издатель, доступ, Visio и проект.
- Открывайте и создавайте несколько документов на новых вкладках одного окна, а не в новых окнах.
- Повышает вашу продуктивность на 50% и сокращает количество щелчков мышью на сотни каждый день!
Комментарии (0)
Оценок пока нет. Оцените первым!
Функция ИНДЕКС помогает извлекать значение из массива данных. Массив может различаться своей структурой, количеством столбцов и строк и даже количество самих массивов может быть больше одного.
Пример работы функции ИНДЕКС в Excel от простого к сложному
Сначала рассмотрим самый простой пример применения. У нас есть несколько городов. Пусть нашей первой задачей будет извлечь пятый по счету город из нашей одномерной базы данных. Синтаксис нашей формулы будет следующий: ИНДЕКС(массив; номер_строки). Начинаем писать формулу (яч. B9). Первый аргумент – это все города B3:C7, а второй – необходимый нам номер ряда, в котором хранится информация, которую мы хотим получить – пятый город:
Функция возвратила значение с второго ряда нашей таблицы. Теперь дополним нашу таблицу информацией о туристах, посетивших город в 2017 году:
Для дальнейшего ознакомления работы функции расширим задачу до двухмерного массива исходных данных.
Функция ИНДЕКС двумерный и многомерный массив
Теперь наш массив двухмерный. Пусть теперешним заданием будет узнать количество туристов в Ливерпуле. В ячейке B19 пишем формулу. Синтаксис тоже видоизменится: ИНДЕКС(массив; номер_строки; номер_столбца), у нас добавится третий аргумент – номер столбца, в котором хранится нужные нам данные:
Аналогично функция работает с трёхмерными массивами, четырёхмерными и так далее. Теперь давайте рассмотрим, как решать задачи, когда таблиц несколько. Пусть у нас будут города трёх стран с количеством посетителей:
На этот раз у нас три двумерные таблицы – три страны с различными городами и их посетителями. Нам необходимо найти количество туристов в городе Ницца страны Франции или, если перефразировать под наш синтаксис, количество посетителей третьего ряда второй колонки второй таблицы. Первым делом, как и раньше, нам нужно выбрать диапазон. НО теперь их у нас три, а значит, все три мы и выбираем, предварительно взяв в скобки эту часть синтаксиса. После чего добавляем уже знакомые нам координаты искомой информации – строку и столбец, а также номер таблицы, которая содержит искомый нами диапазон:
И получаем готовую формулу с решением поставленной задачи:
Пример формулы комбинации функций ИНДЕКС и СУММ
Функцию ИНДЕКC так же можно комбинировать и с другими функциями. Например, наша база данных содержит дополнительно количество туристов Великобритании за 2018-2019 года, мы хотим узнать сумму туристов:
- за 2018 год.
- по городу Манчестер за весь период.
В этом нам поможет известная любому пользователю несложная функция СУММ. Она охватит результат поиска, сделанным ИНДЕКC и выполнит операцию сложения найденных значений. Чтобы выполнить первую задачу, для начала нам нужно выбрать диапазон с одними числами(без столбца с городами, поскольку будем суммировать численные значения C43:E47). Затем на месте, где мы прописывали номер строки, пишем 0. Благодаря этому ИНДЕКC не будет «искать» данные по строкам, а просто перейдет к следующей операции. А следующая операция – прописываем столбец 2 и получаем ответ на первый пункт:
Сумма туристов за 2018 год по пяти городам Великобритании составляет 40 987 людей.
Аналогично этой схеме мы ищем ответ на второй пункт. Только теперь нам нужно считать данные с ряда, поэтому ноль ставим на месте номера столбца:
И получаем ответ на второй пункт – всего посетителей за три года в Манчестере было 2 474 человека.
Для примера зачастую используются самые простые задачи и однотипные решения через функцию. Но в работе объем данных всегда больше и сложнее, поэтому для решения таких заданий используют несколько функций или их сочетание. Несколько таких примеров будем рассматривать дальше.
Формулировку функции можно видоизменять в зависимости от постановки задачи. Пусть нам нужно определить и показать сколько туристов вместе было в 2017-м году в первых трёх городах по списку – Кембридже, Манчестере и Лондоне. Тогда мы снова используем функцию СУММ, но в месте, где указывается конец диапазона значений, по которым мы проводим поиск, вставляем нашу ИНДЕКС. Проще говоря, диапазон для суммирования выглядит так: (начало:конец). Началом будет первая ячейка массива, как обычно, а конец мы заменим. Укажем количество городов, по которым будем считать людей (действие 1). Затем, когда будем составлять функцию ИНДЕКC, укажем, что первый аргумент – числовой диапазон всех пяти городов за 2017-й год, а второй – наше кол-во городов (ячейка D64):
Точно так же можно выполнить следующее задание: найти сумму посетителей Оксфорде за 2017-2018 года. В этом случае делаем всё точно так же, только выбираем горизонтальный диапазон C61:E61 :
В конце необязательно ссылаться на ячейку с написанным количеством искомых значений, можно сразу писать цифру 3 в первом примере и цифру 2 во втором примере, всё будет работать точно так же:
и
идентичны.
Комбинирование нескольких функций могут делать то же, что и одна отдельная функция, но при этом быть менее требовательными к расположению данных, к их размерам или количеству.
Формула ИНДЕКС и ПОИСКПОЗ лучшая замена функции ВПР
Существуют весьма весомые аргументы преимущества использования формулы ИНДЕКС и ПОИСКПОЗ в Excel лучше, чем функция ВПР. Если вы уже знакомы с функцией ВПР, то наверняка знаете, что для её корректной работы искомые данные всегда должны располагаться по правую сторону от критериев:
Получается, что для работы сначала нужно упорядочить столбцы в соответствии с требованиями, а только потом совершать действия. Но иногда сама структура отчета или сводки, с которой нам нужно иметь дело, не позволяет совершать перестановки. Тогда нам очень кстати пригодится ИНДЕКС в сочетании с функцией ПОИСКПОЗ. Синтаксис ИНДЕКСА: (массив; номер_строки; номер_столбца). На первой позиции у нас будет диапазон значений (туристы, 2017), вместо следующих двух пишем ПОИСКПОЗ (искомый критерий;диапазон критериев; 0 (для точного результата)):
Рассмотрим более наглядный и реальный пример, где можно заменить ВПР. У нас есть два отчета: один — о количестве продаж определенного товара, а второй – о цене на упаковку одного товара. И как раз вторая таблица имеет такое расположение столбцов, которое не позволяет использовать нам ВПР – первыми занимают место значения, а вторыми – критерии:
Для того чтобы выполнить заполнение первой таблицы, делаем точно также, как в предыдущем примере – в ячейке D88 пишем ИНДЕКС, первым делом указываем столбец, где находятся искомые значения (цена за упаковку). Затем нужно указать, где нам искать соответствующие критерию значения — подстраиваем ПОИСКПОЗ под наше решение: выбираем искомый критерий (Хепилор), затем массив искомых критериев со второй таблицы:
Теперь просто копируем формулу до конца столбца, но не забываем закрепить ссылки, иначе массив будет спускаться дальше и мы получим некорректные значения. Наша таблица готова:
Если у нас нет данных во второй таблице о цене и препаратах, у нас будет в ячейке ошибка #Н/Д. Теперь к нашим ранее использованным функциям добавим ЕСЛИОШИБКА, которая нам поможет изменить внешний вид отчета, сделать его более понятным для читателя. Опять же, поскольку у нас вторая таблица не соответствует требованиям ВПР, на помощь приходит ИНДЕКС+ПОИСКПОЗ. Усложняем уже имеющуюся формулу, добавляя ЕСЛИОШИБКА, указывая, что при отсутствии данных, мы хотим видеть прочерк:

Таким образом формула из комбинации функций ИНДЕКС и ПОИСПОЗ работают лучше популярной функции ВПР и не имеют никаких ограничений для выборки данных из таблицы даже по нескольким условиям.
Функция
ИНДЕКС(
)
, английский вариант INDEX(),
возвращает значение из диапазона ячеек по номеру строки и столбца. Например, формула
=ИНДЕКС(A9:A12;2)
вернет значение из ячейки
А10
, т.е. из ячейки расположенной во второй строке диапазона.
Синтаксис функции
ИНДЕКС
(массив; номер_строки; номер_столбца)
Массив
— ссылка на диапазон ячеек.
Номер_строки
— номер строки в массиве, из которой требуется возвратить значение. Если аргумент «номер_строки» опущен, аргумент «номер_столбца» является обязательным.
Номер_столбца
— номер столбца в массиве, из которого требуется возвратить значение. Если аргумент «номер_столбца» опущен, аргумент «номер_строки» является обязательным.
Если используются оба аргумента — и «номер_строки», и «номер_столбца», — то функция
ИНДЕКС()
возвращает значение, находящееся в ячейке на пересечении указанных строки и столбца.
Значения аргументов «номер_строки» и «номер_столбца» должны указывать на ячейку внутри заданного массива; в противном случае функция
ИНДЕКС()
возвращает значение ошибки #ССЫЛКА! Например, формула
=ИНДЕКС(A2:A13;22)
вернет ошибку, т.к. в диапазоне
А2:А13
только 12 строк.
Значение из заданной строки диапазона
Пусть имеется одностолбцовый диапазон
А6:А9.
Выведем значение из 2-й строки диапазона, т.е. значение
Груши
. Это можно сделать с помощью формулы
=ИНДЕКС(A6:A9;2)
Если диапазон горизонтальный (расположен в одной строке, например,
А6:D6
), то формула для вывода значения из 2-го столбца будет выглядеть так
=ИНДЕКС(A6:D6;;2)
Значение из заданной строки и столбца таблицы
Пусть имеется таблица в диапазоне
А6:B9.
Выведем значение, расположенное в 3-й строке и 2-м столбце таблицы, т.е. значение
200
. Это можно сделать с помощью формулы
=ИНДЕКС(A6:B9;3;2)
Использование функции в формулах массива
Если задать для аргумента «номер_строки» или «номер_столбца» значение 0, функция
ИНДЕКС()
возвратит массив значений для целого столбца или, соответственно, целой строки (не всего столбца/строки листа, а только столбца/строки входящего в массив). Чтобы использовать массив значений, введите функцию
ИНДЕКС()
как
формулу массива
.
Пусть имеется одностолбцовый диапазон
А6:А9.
Выведем 3 первых значения из этого диапазона, т.е. на
А6
,
А7
,
А8
. Для этого выделите 3 ячейки (
А21
,
А22
,
А23
), в
Строку формул
введите формулу
=ИНДЕКС(A6:A9;0)
, затем нажмите
CTRL+SHIFT+ENTER
.
Зачем это нужно? Теперь удалить по отдельности значения из ячеек
А21
,
А22
,
А23
не удастся, мы получим предупреждение «нельзя изменять часть массива».
Хотя можно просто ввести в этих 3-х ячейках ссылки на диапазон
А6:А8.
Выделите 3 ячейки и введите формулу
=A6:A8.
Затем нажмите
CTRL+SHIFT+ENTER
и получим тот же результат.
Использование массива констант
Вместо ссылки на диапазон можно использовать
массив констант
:
Формула
=ИНДЕКС({«первый»:»второй»:»третий»:»четвертый»};4)
вернет текстовое значение
четвертый
.
ПОИСКПОЗ() + ИНДЕКС()
Функция
ИНДЕКС()
часто используется в связке с функцией
ПОИСКПОЗ()
, которая возвращает позицию (строку) содержащую искомое значение. Это позволяет создать формулу, аналогичную функции
ВПР()
.
Формула
=ВПР(«яблоки»;A35:B38;2;0)
аналогична формуле
=ИНДЕКС(B35:B38;ПОИСКПОЗ(«яблоки»;A35:A38;0))
которая извлекает цену товара
Яблоки
из таблицы, размещенную в диапазоне
A35:B38
Связка
ПОИСКПОЗ()
+
ИНДЕКС()
даже гибче, чем функция
ВПР()
, т.к. с помощью ее можно, например, определить товар с заданной ценой (обратная задача, так называемый «левый ВПР()»). Формула
=ИНДЕКС(A35:A38;ПОИСКПОЗ(200;B35:B38;0))
определяет товар с ценой 200. Если товаров с такой ценой несколько, то будет выведен первый сверху.
Ссылочная форма
Функция
ИНДЕКС()
позволяет использовать так называемую ссылочную форму. Поясним на примере.
Пусть имеется диапазон с числами (
А2:А10
) Необходимо найти сумму первых 2-х, 3-х, …9 значений. Конечно, можно написать несколько формул
=СУММ(А2:А3)
,
=СУММ(А2:А4)
и т.д. Но, записав формулу ввиде:
=СУММ(A2:ИНДЕКС(A2:A10;4))
получим универсальное решение, в котором требуется изменять только последний аргумент (если в формуле выше вместо 4 ввести 5, то будет подсчитана сумма первых 5-и значений).
Использование функции
ИНДЕКС()
в этом примере принципиально отличается от примеров рассмотренных выше, т.к. функция возвращает не само значение, а ссылку (адрес ячейки) на значение. Вышеуказанная формула
=СУММ(A2:ИНДЕКС(A2:A10;4))
эквивалентна формуле
=СУММ(A2:A5)
Аналогичный результат можно получить используя функцию
СМЕЩ()
=СУММ(СМЕЩ(A2;;;4))
Теперь более сложный пример, с областями.
Пусть имеется таблица продаж нескольких товаров по полугодиям.
Задав
Товар
,
год
и
полугодие
, можно вывести соответствующий объем продаж с помощью формулы
=ИНДЕКС((B9:C12;D9:E12;F9:G12);B15;A19;B17)
Вся таблица как бы разбита на 3 подтаблицы (области), соответствующие отдельным годам:
B9:C12
;
D9:E12
;
F9:G12
. Задавая номер строки, столбца (в подтаблице) и номер области, можно вывести соответствующий объем продаж. В
файле примера
, выбранные строка и столбец выделены цветом с помощью
Условного форматирования
.































































































