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

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

1С: как найти значение в массиве

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

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

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

Метод Найти(): поиск точного значения

Штатный способ поиска в массиве — метод Найти(). Он принимает один параметр — искомое значение — и возвращает индекс первого найденного элемента. Если совпадений нет, метод возвращает Неопределено. Именно это значение нужно проверять, а не ноль или пустую строку.

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

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

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

Массив.Добавить("Апельсин");

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

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

Сообщить("Значение не найдено");

Иначе

Сообщить("Найдено на позиции: " + Индекс); // вернёт 1

КонецЕсли;

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

Метод сравнивает значения строго: тип и содержимое должны совпадать. Строка "123" не будет равна числу 123, а поиск строки зависит от регистра — "Груша" и "груша" считаются разными значениями. Для ссылок сравнение идёт по самой ссылке, что обычно удобно при работе со списками документов или элементов справочников.

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

Проверка самого факта наличия значения

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

Если МассивИсключений.Найти(ТекущийКонтрагент) <> Неопределено Тогда

// Контрагент в списке исключений — пропускаем обработку

Продолжить;

КонецЕсли;

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

Поиск по условию: перебор в цикле

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

ИскомаяПодстрока = "груша";

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

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

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

Сообщить("Найдено: " + Элемент);

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

Прервать;

КонецЕсли;

КонецЕсли;

Обратите внимание на два приёма в примере. Функция НРег() приводит обе строки к нижнему регистру, делая поиск регистронезависимым. Оператор Прервать останавливает цикл сразу после первого совпадения — без него перебор продолжится до конца массива, что бессмысленно, если нужен только первый результат.

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

Поиск в массиве структур и строк таблицы значений

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

Решение — цикл с обращением к свойству структуры:

Для Каждого Запись Из МассивСтруктур Цикл

Если Запись.Артикул = ИскомыйАртикул Тогда

НайденнаяЗапись = Запись;

Прервать;

КонецЕсли;

КонецЦикла;

Если данные изначально лежат в таблице значений, массив вообще не нужен: у таблицы есть собственные методы Найти(Значение, Колонка) и НайтиСтроки(Отбор). Второй метод принимает структуру отбора и возвращает массив всех подходящих строк — это самый удобный инструмент поиска по нескольким полям одновременно.

Сравнение способов поиска

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

Точное совпадение простого значения. Быстро и коротко, но без условий и без учёта регистра.

Цикл Для Каждого

Любые условия: подстрока, регистр, диапазоны, поиск в структурах. Требует больше кода.

Таблица значений + НайтиСтроки

Поиск по нескольким полям сразу. Подходит, когда данные табличные; для простого списка избыточно.

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

Мгновенная проверка наличия ключа. Идеально для больших списков, но хранит только ключ-значение.

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

Первая и самая распространённая ошибка — проверка результата Найти() на ноль вместо Неопределено. Значение с индексом 0 — это первый элемент массива, и условие Если Индекс = 0 примет его за «не найдено», что приведёт к логическим сбоям в обработке.

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

Третья ошибка — обращение к элементу по индексу без проверки. Если Найти() вернул Неопределено, а код сразу выполняет Массив[Индекс], программа завершится с ошибкой. Проверка результата должна идти перед любым использованием индекса.

Типичные ошибки
01
Проверка результата Найти() на 0 вместо Неопределено — первый элемент принимается за отсутствие результата
02
Игнорирование регистра и пробелов при поиске строк — совпадение не находится
03
Использование Массив[Индекс] без проверки — падение с ошибкой, когда значение не найдено
04
Поиск структуры методом Найти() — сравнение идёт не по содержимому, результат непредсказуем
05
Отсутствие Прервать в цикле — лишний перебор всего массива после нахождения результата

Производительность: когда массив стоит заменить

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

Если задача — многократно проверять наличие значений, переведите список в соответствие один раз, а затем используйте его для проверок:

СоответствиеПоиска = Новый Соответствие;

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

СоответствиеПоиска.Вставить(Элемент, Истина);

КонецЦикла;

// Дальше быстрые проверки:

Если СоответствиеПоиска[ПроверяемоеЗначение] <> Неопределено Тогда

// Значение есть в списке

КонецЕсли;

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

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

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

Результат Найти()
Норма

Возвращён числовой индекс, элемент доступен по Массив[Индекс]

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

Возвращено Неопределено, но код продолжает работать с индексом

Поиск строк
Норма

Регистр и пробелы нормализованы с обеих сторон

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

Значение визуально есть в массиве, но не находится

Скорость обработки
Норма

Поиск выполняется быстро даже на больших данных

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

Вложенные циклы с Найти() занимают основное время выполнения

Краткий итог и частые вопросы

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

Итог

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

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

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

Метод возвращает значение Неопределено — не ноль и не минус один. Проверять результат нужно именно сравнением с Неопределено: Если Индекс = Неопределено Тогда.

Как найти значение в массиве без учёта регистра?

Штатный Найти() регистрозависим, поэтому используйте цикл: приведите обе строки к одному регистру функцией НРег() или ВРег() и сравнивайте их. Для поиска подстроки дополнительно примените СтрНайти().

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

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

Чем искать, если в массиве лежат структуры?

Метод Найти() для структур не подходит — перебирайте массив циклом и сравнивайте нужное свойство: Если Элемент.ИмяСвойства = ИскомоеЗначение Тогда. Если данных много, лучше хранить их в таблице значений и использовать НайтиСтроки().

Что быстрее: Найти() в массиве или поиск в соответствии?

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

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

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