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