К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как найти индекс элемента в массиве 1С

Как найти индекс элемента в массиве 1С: метод Найти(), поиск в цикле, работа с объектами, типичные ошибки и проверка результата с примерами кода.

Встроенный язык 1С:Предприятие предоставляет прямой способ определить позицию значения в массиве — метод Найти(). Он возвращает индекс первого вхождения искомого элемента либо Неопределено, если значения в массиве нет. Этого достаточно для большинства задач, но есть нюансы: нумерация массивов в 1С начинается с нуля, сравнение ссылок идёт по значению ссылки, а для сложных структур метод может не подойти.

Разобраться с поиском индекса важно, потому что от него зависят дальнейшие операции: удаление элемента через Удалить(), вставка через Вставить() или замена значения по позиции. Ошибка в определении индекса приводит к удалению не того элемента или к обращению за границы массива, что вызывает исключение и останавливает выполнение кода.

Ниже рассмотрены базовый синтаксис метода Найти(), поиск в цикле для сложных условий, особенности работы со ссылками и структурами, а также типичные ошибки и способы проверить результат перед использованием.

Базовый поиск индекса методом Найти()

Метод Найти() вызывается у объекта типа «Массив» и принимает один параметр — искомое значение. Синтаксис предельно прост:

Массив = Новый Массив;

Массив.Добавить("Яблоко");

Массив.Добавить("Груша");

Массив.Добавить("Слива");

Индекс = Массив.Найти("Груша");

// Индекс = 1, так как нумерация начинается с нуля

ИндексОтсутствующего = Массив.Найти("Апельсин");

// ИндексОтсутствующего = Неопределено

Метод выполняет последовательное сравнение элементов с искомым значением и останавливается на первом совпадении. Если в массиве несколько одинаковых значений, будет возвращён индекс только первого из них. Для поиска всех вхождений потребуется цикл, который рассмотрен ниже.

Сравнение выполняется по стандартным правилам встроенного языка: строки сравниваются с учётом регистра, числа — по значению, даты — по моменту времени. Это значит, что Найти("груша") не найдёт элемент "Груша" — при необходимости приводите регистр через НРег() или ВРег() перед поиском.

1c
Индекс = Массив.Найти(ИскомоеЗначение);
Если Индекс <> Неопределено Тогда
    Массив.Удалить(Индекс);
КонецЕсли;

Как правильно проверить результат поиска

Главное правило безопасной работы с Найти() — никогда не использовать возвращённое значение без проверки на Неопределено. Если передать Неопределено в методы Удалить(), Вставить() или использовать его как индекс обращения, платформа выдаст ошибку, и выполнение процедуры прервётся.

Типовая безопасная конструкция выглядит так:

Индекс = Массив.Найти(ИскомоеЗначение);

Если Индекс = Неопределено Тогда

// Элемент не найден: логируем, добавляем или пропускаем

Массив.Добавить(ИскомоеЗначение);

Иначе

// Элемент найден — работаем с позицией

Массив[Индекс] = НовоеЗначение;

КонецЕсли;

Обратите внимание: проверка Если Индекс Тогда без сравнения с Неопределено опасна. Индекс 0 (первый элемент массива) в булевом контексте ведёт себя как ложь, поэтому такая проверка пропустит корректно найденный первый элемент. Всегда сравнивайте результат явно: Индекс <> Неопределено.

Поиск индекса в цикле для сложных условий

Метод Найти() сравнивает элементы целиком, поэтому он не подходит, когда массив содержит структуры, строки таблиц значений или нужно искать по части значения. В таких случаях используется явный перебор с запоминанием индекса.

Поиск по условию в массиве структур

ИндексНайденного = Неопределено;

Для Индекс = 0 По Массив.ВГраница() Цикл

Если Массив[Индекс].Код = ИскомыйКод Тогда

ИндексНайденного = Индекс;

Прервать;

КонецЕсли;

КонецЦикла;

Метод ВГраница() возвращает индекс последнего элемента, что удобно для цикла от нуля до конца массива. Оператор Прервать останавливает перебор сразу после нахождения — это важно для производительности на больших массивах.

Поиск всех вхождений значения

Если нужны индексы всех совпадений, собирайте их в отдельный массив:

НайденныеИндексы = Новый Массив;

Для Индекс = 0 По Массив.ВГраница() Цикл

Если Массив[Индекс] = ИскомоеЗначение Тогда

НайденныеИндексы.Добавить(Индекс);

КонецЕсли;

КонецЦикла;

При последующем удалении найденных элементов удаляйте их от большего индекса к меньшему. Если удалять в прямом порядке, позиции оставшихся элементов сместятся, и часть элементов будет пропущена либо удалена ошибочно.

Типичные ошибки
01
Удаление элементов по найденным индексам в прямом порядке — позиции смещаются, часть элементов пропускается; удаляйте от конца к началу
02
Поиск строки без учёта регистра: Найти("груша") не находит "Груша" — приводите регистр через НРег()
03
Сравнение структур через Найти() — структуры сравниваются не по содержимому, используйте цикл с проверкой полей
04
Проверка «Если Индекс Тогда» вместо сравнения с Неопределено — индекс 0 трактуется как ложь, первый элемент теряется

Особенности поиска ссылок и объектов

Для ссылок на объекты базы данных (справочники, документы) метод Найти() работает корректно: ссылки сравниваются по значению, то есть две переменные, указывающие на один и тот же элемент справочника, считаются равными. Это делает Найти() удобным для проверки наличия документа или товара в массиве.

Иная ситуация со структурами и другими составными объектами. Структуры сравниваются не по содержимому полей, поэтому Найти() для массива структур практически бесполезен — совпадение будет найдено только при ссылке на тот же самый объект. Для таких данных применяйте цикл с проверкой конкретных полей, как показано выше.

Если массив содержит значения разных типов, помните, что сравнение строгое: число 5 не равно строке "5". При смешанных данных перед поиском приведите типы к единому виду через Строка(), Число() или форматируйте значения единообразно при заполнении массива.

Альтернативы массиву для частого поиска

Метод Найти() и ручной перебор выполняют линейный поиск: чем больше массив, тем дольше поиск. Если операция «найти позицию значения» выполняется многократно в цикле по большой коллекции, стоит рассмотреть другие структуры данных.

Соответствие обеспечивает быстрый поиск по ключу: вместо поиска индекса значения вы храните пары «значение — индекс» и получаете позицию одним обращением Соответствие.Получить(Ключ). Это оправдано, когда массив заполняется один раз, а поиск выполняется сотни и тысячи раз.

Таблица значений с индексом по колонке — ещё один вариант: метод Найти() таблицы значений ищет строку по значению колонки, а добавленный через Индексы.Добавить() индекс ускоряет повторные поиски. Подходит, когда помимо позиции нужны связанные данные.

Сравнение вариантов

Массив.Найти()

Простые значения, разовый поиск. Ограничение: линейный перебор, только точное совпадение элемента целиком

Цикл с ВГраница()

Сложные условия, массивы структур, поиск всех вхождений. Ограничение: больше кода, нужно вручную следить за прерыванием

Соответствие

Многократный поиск по ключу на больших данных. Ограничение: ключи уникальны, порядок элементов не сохраняется

Таблица значений с индексом

Поиск по полю с дополнительными данными в строке. Ограничение: тяжелее массива, требует создания индекса

Проверка результата и отладка

При отладке поиска полезно выводить промежуточные значения через Сообщить() или смотреть их в табло конфигуратора. Проверьте три вещи: что искомое значение имеет ожидаемый тип и регистр, что массив действительно заполнен (вызовите Массив.Количество()), и что возвращаемый индекс попадает в диапазон от 0 до ВГраница().

Если Найти() возвращает Неопределено, хотя значение «точно есть», почти всегда причина в несовпадении типов или регистра строк. Сравните значения в отладчике визуально и проверьте тип через ТипЗнч() — это быстрее, чем перечитывать код заполнения массива.

Контрольные точки

Как проверить результат

Возвращаемое значение Найти()
Норма

Число от 0 до Массив.ВГраница()

Тревожный признак

Неопределено при заведомо существующем значении — проверяйте тип и регистр

Тип искомого значения
Норма

Тип совпадает с типом элементов массива

Тревожный признак

Строка вместо числа, разный регистр символов

Индекс перед Удалить()/Вставить()
Норма

Индекс проверен на Неопределено и не выходит за границы

Тревожный признак

Передаётся без проверки — риск исключения

Частые вопросы

Что возвращает метод Найти(), если элемент не найден?

Метод возвращает значение Неопределено. Это не число и не -1, поэтому результат нельзя использовать в арифметике или как индекс без предварительной проверки сравнением с Неопределено.

С какого числа начинается нумерация массива в 1С?

С нуля. Первый элемент имеет индекс 0, а индекс последнего возвращает метод ВГраница(). Это отличается от нумерации строк в некоторых других коллекциях 1С, поэтому при переносе логики легко ошибиться на единицу.

Как найти индекс элемента в массиве структур?

Метод Найти() для этого не подходит — структуры не сравниваются по содержимому полей. Перебирайте массив в цикле от 0 до ВГраница() и сравнивайте нужное поле каждой структуры с искомым значением, запоминая индекс при совпадении.

Как найти все вхождения значения, а не только первое?

Пройдите массив циклом и собирайте индексы всех совпадений в отдельный массив. Метод Найти() всегда возвращает только первое вхождение и не имеет параметра для продолжения поиска с позиции.

Учитывается ли регистр при поиске строк?

Да, строки сравниваются с учётом регистра: «Груша» и «груша» — разные значения. Для регистронезависимого поиска применяйте НРег() или ВРег() к искомому значению и к элементам массива при сравнении в цикле.

Что быстрее для многократного поиска — массив или соответствие?

Соответствие значительно быстрее при большом числе поисков, так как обращение по ключу не требует перебора элементов. Массив с методом Найти() оправдан для разовых поисков в небольших коллекциях, где простота кода важнее скорости.

Итог

Что важно запомнить

Индекс элемента в массиве 1С находится методом Найти(), который возвращает позицию с нуля или Неопределено. Результат всегда проверяйте явным сравнением с Неопределено, для структур и сложных условий используйте цикл с ВГраница(), а при частом поиске на больших данных переходите на соответствие или таблицу значений с индексом.