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

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

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

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

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

Индексация массивов в 1С начинается с нуля: первый элемент имеет индекс 0, второй — 1 и так далее. Максимальный индекс всегда на единицу меньше значения Количество(). Это отличается от нумерации строк табличных частей в пользовательском интерфейсе и часто становится источником ошибок у начинающих разработчиков.

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

Метод Найти(): базовый синтаксис

Метод вызывается у переменной массива и принимает один параметр — искомое значение. Сравнение выполняется на строгое равенство с учётом типа данных: число 5 не будет найдено, если в массиве лежит строка "5".

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

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

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

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

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

// Индекс = 1

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

Проверка результата: обработка Неопределено

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

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

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

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

Иначе

Сообщить("Индекс: " + Индекс);

КонецЕсли;

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

Типичные ошибки
01
Проверка 'Если Индекс Тогда' — индекс 0 трактуется как Ложь, найденный первый элемент считается отсутствующим
02
Использование результата Найти() без проверки на Неопределено — ошибка выполнения при отсутствии элемента
03
Поиск строки без учёта регистра — 'Груша' не находится, если в массиве 'груша'

Поиск всех вхождений и поиск по условию через цикл

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

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

Для Инд = 0 По Массив.Количество() - 1 Цикл

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

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

КонецЕсли;

КонецЦикла;

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

Поиск индекса по условию в цикле
  1. 1
    Объявите переменную Результат = Неопределено
  2. 2
    Пройдите массив циклом от 0 до Количество()-1
  3. 3
    Внутри цикла проверьте условие для текущего элемента
  4. 4
    При совпадении запишите индекс в Результат и выполните Прервать
  5. 5
    После цикла проверьте Результат на Неопределено

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

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

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

Для Инд = 0 По МассивСтруктур.Количество() - 1 Цикл

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

Индекс = Инд;

Прервать;

КонецЕсли;

КонецЦикла;

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

Способы поиска в разных коллекциях

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

Простые значения (числа, строки, ссылки). Быстро, но только строгое равенство и первое вхождение

Цикл по массиву

Поиск по условию, части строки или полю структуры. Гибко, но требует ручной обработки индекса

Таблица.Найти() + Индекс()

Для таблиц значений: поиск строки по колонке, затем получение её индекса

Производительность и ограничения

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

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

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

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

После нахождения индекса полезно убедиться, что по нему действительно лежит нужное значение: Массив[Индекс] = ИскомоеЗначение. Это простая самопроверка, которая отлавливает ошибки смещения индексов при сложной логике.

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

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

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

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

Число от 0 до Количество()-1

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

Неопределено — элемент отсутствует или не совпал тип/регистр

Значение по индексу
Норма

Массив[Индекс] равно искомому значению

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

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

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

Строка найдена при совпадении регистра

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

Не находится — проверьте ВРег()/НРег() и лишние пробелы

Итог и частые вопросы

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

Итог

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

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

Почему Найти() возвращает Неопределено, хотя элемент точно есть в массиве?

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

Как найти индекс последнего вхождения элемента?

Штатного метода нет. Переберите массив в цикле от конца к началу (от Количество()-1 до 0 с шагом -1) и прервите его при первом совпадении — это и будет последнее вхождение.

Можно ли найти индекс элемента в массиве структур методом Найти()?

Нет. Структуры сравниваются по ссылке, а не по содержимому, поэтому Найти() почти всегда вернёт Неопределено. Перебирайте массив в цикле и сравнивайте нужное поле каждой структуры.

Чем отличается поиск индекса в массиве от поиска в таблице значений?

У таблицы значений Найти() возвращает строку, а не индекс. Чтобы получить индекс, передайте найденную строку в метод Индекс(). Для отбора по нескольким колонкам используйте НайтиСтроки() со структурой отбора.

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

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