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

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

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

Как найти значение в массиве 1С: перебор циклом, методы ВГраница и Количество, поиск через соответствие, таблицу значений и список значений. Примеры кода и типичные ошибки.

Массив в 1С — это упорядоченная коллекция значений, доступ к которым выполняется по числовому индексу. У типа «Массив» нет встроенного метода «Найти», поэтому разработчики часто ищут обходные пути: перебор циклом, вспомогательные структуры или другие коллекции. Выбор способа зависит от размера массива, частоты поиска и того, что именно нужно получить — сам элемент, его индекс или факт наличия.

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

Как устроен массив и почему в нём нет метода «Найти»

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

Платформа 1С не предоставляет для массива методов Найти или Содержит — такие методы есть у списка значений, таблицы значений и соответствия. Это осознанное ограничение: массив задуман как простая структура для последовательного доступа, а не для поиска. Поэтому задача «найти в массиве» всегда решается либо перебором, либо сменой структуры данных.

Поиск значения перебором в цикле

Базовый способ — пройти по массиву циклом и сравнить каждый элемент с искомым значением. Как только совпадение найдено, цикл прерывается, чтобы не тратить время на оставшиеся элементы.

Функция НайтиИндексВМассиве(Массив, ИскомоеЗначение)

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

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

Возврат Индекс;

КонецЕсли;

КонецЦикла;

Возврат -1; // не найдено

КонецФункции

Возврат -1 при отсутствии результата — общепринятое соглашение: так вызывающий код легко отличает «не найдено» от «найден первый элемент с индексом 0». Проверка результата обязательна — иначе обращение Массив[-1] вызовет ошибку исполнения.

Если нужен не индекс, а сам элемент или факт наличия, удобнее цикл Для Каждого:

Найдено = Ложь;

Для Каждого Элемент Из Массив Цикл

Если Элемент = ИскомоеЗначение Тогда

Найдено = Истина;

Прервать;

КонецЕсли;

КонецЦикла;

Порядок действий
  1. 1
    Создайте или получите массив, в котором нужно искать
  2. 2
    Напишите цикл от 0 до Массив.ВГраница() с сравнением элементов
  3. 3
    При совпадении сохраните индекс или элемент и выполните Прервать
  4. 4
    После цикла проверьте результат: -1 или Неопределено означает отсутствие значения
  5. 5
    Убедитесь, что вызывающий код корректно обрабатывает случай, когда элемент не найден

Поиск по части строки и сложным условиям

Простое сравнение работает для точного совпадения, но часто нужно найти элемент по подстроке, по свойству объекта или по нескольким условиям. Для поиска подстроки используется функция СтрНайти, которая возвращает позицию вхождения или 0, если вхождения нет.

Для Каждого Элемент Из Массив Цикл

Если СтрНайти(Элемент, "Накладная") > 0 Тогда

// элемент содержит нужную подстроку

КонецЕсли;

КонецЦикла;

Если массив содержит структуры или ссылки, сравнение идёт по конкретному свойству: Элемент.Артикул = ИскомыйАртикул или Элемент.Ссылка = НужныйДокумент. Ссылки сравниваются оператором равенства корректно — платформа сравнивает их по уникальному идентификатору, а не по представлению.

Ускорение поиска через соответствие

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

Индексы = Новый Соответствие;

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

Индексы.Вставить(Массив[Индекс], Индекс);

КонецЦикла;

// далее поиск в любом месте кода:

НайденныйИндекс = Индексы[ИскомоеЗначение];

Если НайденныйИндекс <> Неопределено Тогда

// элемент найден

КонецЕсли;

Обращение к соответствию по ключу, которого нет, возвращает Неопределено — это безопасно и не вызывает исключения. Такой приём оправдан, когда проверок больше, чем элементов в массиве, или когда массив содержит тысячи значений. Для разового поиска по небольшому массиву строить соответствие нет смысла — накладные расходы превысят выигрыш.

Альтернативы: список значений и таблица значений

Если структуру данных ещё можно выбрать, стоит рассмотреть коллекции со встроенным поиском. Список значений имеет метод НайтиПоЗначению, который возвращает элемент списка или Неопределено:

Список = Новый СписокЗначений;

Список.Добавить("Первый");

Список.Добавить("Второй");

Элемент = Список.НайтиПоЗначению("Второй");

Если Элемент <> Неопределено Тогда

Индекс = Список.Индекс(Элемент);

КонецЕсли;

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

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

Перебор массива циклом

Подходит для разового поиска и небольших массивов. Не требует дополнительной памяти, но при многократном поиске работает медленно.

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

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

Список значений

Удобен, когда нужен встроенный метод НайтиПоЗначению и работа с представлениями. Медленнее соответствия при частом поиске.

Таблица значений

Лучший выбор при поиске по нескольким полям и получении всех совпадений. Избыточна для простого списка однотипных значений.

Типичные ошибки при поиске в массиве

Самая частая ошибка — обращение к элементу по индексу без проверки, что поиск вообще дал результат. Если функция вернула -1 или Неопределено, а код продолжает работать с этим значением как с индексом, возникает ошибка «Индекс находится за границами массива».

Вторая группа ошибок связана со сравнением: попытка сравнить ссылку со строкой-наименованием, поиск подстроки с учётом регистра там, где пользователь вводит текст произвольно, или сравнение чисел, один из которых получен из строки без явного преобразования. Все эти случаи не вызывают исключения — они просто молча возвращают «не найдено», и найти причину бывает непросто.

Третья ошибка — удаление элементов из массива внутри цикла прямого перебора. После удаления индексы сдвигаются, и часть элементов пропускается. Если нужно фильтровать массив, либо идите циклом с конца (ВГраница() до нуля с шагом -1), либо собирайте результат в новый массив.

Типичные ошибки
01
Использование результата поиска без проверки на -1 или Неопределено — приводит к ошибке обращения за границы массива
02
Удаление элементов в прямом цикле — индексы смещаются, часть элементов пропускается
03
Сравнение ссылки со строковым представлением — поиск молча ничего не находит
04
Построение соответствия ради одного поиска — лишние затраты памяти и времени без выигрыша
05
Отсутствие Прервать после нахождения элемента — цикл продолжает работу впустую

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

После реализации поиска проверьте три сценария: элемент есть в массиве (в том числе первым и последним), элемента нет, массив пуст. Для пустого массива ВГраница() возвращает -1, и корректно написанный цикл просто не выполнится — но код, который обращается к Массив[0] до проверки, упадёт с ошибкой.

При выборе способа ориентируйтесь на частоту поиска и объём данных. Разовая проверка — обычный цикл. Сотни проверок по одному набору данных — соответствие. Поиск по нескольким полям с получением всех совпадений — таблица значений. Не оптимизируйте заранее: на массивах в десятки элементов разница между способами незаметна.

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

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

Поиск существующего элемента
Норма

Возвращается корректный индекс или элемент

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

Возвращается -1 или Неопределено при заведомо существующем значении — проверьте типы и регистр

Поиск отсутствующего значения
Норма

Возвращается -1 или Неопределено, ошибок нет

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

Возникает исключение или возвращается 0, что маскируется под первый элемент

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

Цикл не выполняется, возвращается признак «не найдено»

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

Ошибка обращения по индексу

Итог

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

Встроенного метода поиска у массива в 1С нет: разовый поиск делайте циклом с Прервать, многократный — через соответствие, поиск по полям — через таблицу значений. Всегда проверяйте результат на -1 или Неопределено и не удаляйте элементы в прямом цикле перебора.

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

Есть ли в 1С аналог метода Найти для массива?

Нет, у типа «Массив» такого метода нет. Ближайшие альтернативы со встроенным поиском — список значений (НайтиПоЗначению), таблица значений (Найти, НайтиСтроки) и соответствие (обращение по ключу). Для самого массива поиск реализуется циклом.

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

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

Как проверить, есть ли значение в массиве, без получения индекса?

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

Почему поиск не находит значение, которое точно есть в массиве?

Чаще всего причина в несовпадении типов (строка вместо числа, строка вместо ссылки) или в регистре символов при поиске через СтрНайти. Также проверьте наличие неразрывных пробелов и лишних символов — их помогает убрать функция СокрЛП.

Что быстрее: перебор массива или соответствие?

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

Можно ли искать в массиве структур по значению поля?

Да, внутри цикла обращайтесь к свойству структуры: Элемент.ИмяПоля = ИскомоеЗначение. Если таких поисков много, удобнее перенести данные в таблицу значений — тогда поиск по полю выполнит метод Найти с указанием имени колонки.