Разработка и Конфигурация · 9 мин
1С: как узнать индекс элемента массива
Как узнать индекс элемента массива в 1С: метод Найти(), перебор циклом, поиск по части значения, проверка результата Неопределено и типичные ошибки разработчиков.
Массив в 1С — упорядоченная коллекция значений, где каждый элемент доступен по числовому индексу, начиная с нуля. Чтобы узнать индекс элемента, чаще всего применяют встроенный метод Найти(): он возвращает позицию первого найденного значения или Неопределено, если такого элемента в массиве нет. Этого достаточно для большинства задач — поиска настройки, проверки наличия ссылки, выбора строки по условию.
Важно понимать ограничение метода: Найти() сравнивает значения на строгое равенство. Если нужно найти элемент по части строки, по условию или по нескольким критериям, придётся перебирать массив циклом и запоминать индекс вручную. Ниже разобраны оба подхода, проверка результата и ошибки, которые чаще всего приводят к неверной логике.
Метод Найти(): базовый способ получить индекс
Метод Найти() принимает один параметр — искомое значение — и возвращает его индекс в массиве. Индексация начинается с нуля: первый элемент имеет индекс 0, второй — 1 и так далее. Если значение встречается несколько раз, возвращается позиция первого вхождения.
МассивТоваров = Новый Массив;
МассивТоваров.Добавить("Гвозди");
МассивТоваров.Добавить("Молоток");
МассивТоваров.Добавить("Шурупы");
Индекс = МассивТоваров.Найти("Молоток");
// Индекс = 1
Сравнение выполняется по значению с учётом типа. Строка "10" и число 10 — разные значения, поиск одного по другому вернёт Неопределено. Для строк регистр букв также имеет значение: "Молоток" и "молоток" не совпадут.
Индекс = Массив.Найти(ИскомоеЗначение);
Если Индекс = Неопределено Тогда
Сообщить("Элемент не найден");
Иначе
Сообщить("Позиция: " + Индекс);
КонецЕсли;Как правильно проверить результат поиска
Главная особенность — метод возвращает Неопределено, а не -1 и не 0, когда элемент отсутствует. Проверку нужно делать именно на Неопределено, иначе логика сломается: сравнение Индекс = -1 никогда не сработает, а обращение Массив[Неопределено] вызовет ошибку исполнения.
Типичный безопасный шаблон выглядит так:
Индекс = Массив.Найти(ИскомоеЗначение);
Если Индекс <> Неопределено Тогда
Элемент = Массив[Индекс];
// работа с найденным элементом
Иначе
// обработка ситуации "не найдено"
КонецЕсли;
Отдельная ловушка — индекс 0. Конструкция Если Индекс Тогда сработает как ложь для первого элемента массива, потому что 0 приводится к Ложь. Всегда сравнивайте с Неопределено явно.
Поиск индекса перебором циклом
Когда условие сложнее простого равенства — например, найти строку, содержащую подстроку, или элемент с максимальным значением свойства, — используют цикл Для с явным индексом. Переменная цикла и будет искомой позицией.
ИндексНайденного = Неопределено;
Для Инд = 0 По Массив.ВГраница() Цикл
Если СтрНайти(Массив[Инд], "гвоздь") > 0 Тогда
ИндексНайденного = Инд;
Прервать;
КонецЕсли;
КонецЦикла;
Метод ВГраница() возвращает индекс последнего элемента — это удобнее и надёжнее, чем вычислять Количество() - 1. Оператор Прервать останавливает цикл после первого совпадения, экономя время на больших массивах.
Если нужно найти не первый, а последний подходящий элемент, уберите Прервать — переменная перезапишется на каждом совпадении и в итоге будет хранить последний индекс. Для сбора всех позиций добавляйте каждый найденный индекс в отдельный массив.
Особые случаи: ссылки, структуры и регистр строк
Поиск ссылки в массиве
Ссылки на объекты базы данных сравниваются корректно: если в массиве лежит ссылка на тот же элемент справочника, Найти() вернёт её индекс. Но ссылка и результат ПолучитьСсылку() от разных вызовов совпадут, а вот ссылка и строка с её представлением — нет.
Поиск без учёта регистра
Для регистронезависимого сравнения приведите обе строки к одному регистру функцией НРег() или ВРег():
Для Инд = 0 По Массив.ВГраница() Цикл
Если НРег(Массив[Инд]) = НРег(ИскомоеЗначение) Тогда
ИндексНайденного = Инд;
Прервать;
КонецЕсли;
КонецЦикла;
Массивы структур
Метод Найти() для структур практически бесполезен: две структуры с одинаковым составом не считаются равными. Здесь всегда нужен цикл со сравнением конкретного ключа, например Массив[Инд].Код = ИскомыйКод.
Альтернативы: соответствие и список значений
Если поиск по массиву выполняется часто и в цикле, стоит пересмотреть структуру данных. Многократный вызов Найти() на большом массиве — это линейный перебор на каждый запрос, что заметно тормозит код.
Сравнение вариантов
Подходит для разового поиска и небольших коллекций. Ограничение — линейный перебор при каждом вызове
Мгновенный поиск по ключу. Подходит, когда значения уникальны и поиск частый; индекса как такового нет
Есть метод НайтиПоЗначению(), возвращающий элемент, по которому доступен индекс через Индекс(). Удобен для связки значение+представление
Метод Найти() ищет по значению колонки, НайтиСтроки() — по нескольким условиям. Подходит для составных данных
Для СписокЗначений последовательность такая: Элемент = Список.НайтиПоЗначению(Значение), затем Индекс = Список.Индекс(Элемент). Двухшаговая схема компенсируется тем, что список хранит представления и пометки — удобно для интерфейсных задач.
Как выбрать способ
Проверка результата и отладка
Быстрый способ убедиться, что поиск работает, — вывести результат через Сообщить() или посмотреть переменную в отладчике (табло). Полезно выводить не только индекс, но и само найденное значение: это сразу показывает, тот ли элемент найден.
Индекс = Массив.Найти(ИскомоеЗначение);
Сообщить("Индекс: " + ?(Индекс = Неопределено, "не найден", Индекс));
В отладчике удобно поставить точку останова сразу после строки поиска и посмотреть содержимое массива целиком — часто оказывается, что искомое значение отличается пробелом в конце или другим типом данных. Функция СокрЛП() перед сравнением убирает такие расхождения для строк.
Как проверить результат
Число от 0 до ВГраница() включительно
Неопределено при уверенности, что элемент есть
Массив[Индекс] равен искомому значению
Значение отличается — найден дубликат раньше нужного
ТипЗнч() совпадает у элемента и искомого
Строка сравнивается с числом или ссылкой
Частые вопросы
Что возвращает Найти(), если элемента нет в массиве?
Значение Неопределено. Не -1 и не 0 — поэтому проверку всегда делайте через сравнение с Неопределено, иначе условие сработает неверно.
Как найти индекс последнего вхождения значения?
Метод Найти() возвращает только первое совпадение. Для последнего переберите массив циклом без Прервать и сохраняйте индекс при каждом совпадении — в конце останется последняя позиция. Альтернатива — обратный цикл от ВГраница() до 0 с шагом -1 и остановкой на первом совпадении.
Почему Найти() не находит значение, которое точно есть в массиве?
Чаще всего причины три: разные типы данных (число против строки), разный регистр букв, лишние пробелы в строке. Приведите значения к одному типу, используйте НРег() и СокрЛП() перед сравнением.
Можно ли найти индекс элемента в соответствии?
Нет, у соответствия нет индексов — доступ идёт по ключу. Если нужна позиция, используйте массив или список значений. Соответствие выбирают ради скорости поиска по ключу, а не ради порядка.
Как узнать индекс элемента в списке значений?
Сначала найдите элемент: Элемент = Список.НайтиПоЗначению(Значение). Если он не Неопределено, получите позицию: Индекс = Список.Индекс(Элемент). Нумерация также начинается с нуля.
Что быстрее — Найти() или перебор циклом?
Для простого равенства Найти() быстрее и короче, так как реализован на уровне платформы. Цикл оправдан только когда условие сложнее равенства. При частом поиске в большом массиве оба варианта проигрывают соответствию.
Что важно запомнить
Индекс элемента массива в 1С получают методом Найти(Значение): результат — число от нуля или Неопределено, если элемента нет. Проверяйте результат только через сравнение с Неопределено, следите за типами и регистром строк, а для сложных условий и частого поиска используйте цикл или соответствие.