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