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