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

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

Как определить индекс элемента массива в 1С

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

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

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

Как устроена индексация массива в 1С

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

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

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

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

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

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

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

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

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

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

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

Иначе

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

КонецЕсли;

Типичный сценарий — удаление найденного элемента. Здесь проверка на Неопределено критична: метод Удалить(Неопределено) приведёт к ошибке исполнения и прервёт выполнение кода.

Порядок действий при поиске индекса
  1. 1
    Сформируйте массив и убедитесь, что тип искомого значения совпадает с типом элементов
  2. 2
    Вызовите Индекс = Массив.Найти(ИскомоеЗначение)
  3. 3
    Проверьте результат: Если Индекс = Неопределено — элемента нет
  4. 4
    Используйте индекс для чтения, замены или удаления элемента только после успешной проверки

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

Когда условие поиска сложнее простого равенства — например, найти строку по подстроке, число в диапазоне или элемент по нескольким критериям — используется перебор с явным индексом. Цикл Для Индекс = 0 По Массив.ВГраница() даёт доступ и к индексу, и к элементу одновременно.

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

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

Если СтрНайти(Массив[Индекс], "груш") > 0 Тогда

ИскомыйИндекс = Индекс;

Прервать;

КонецЕсли;

КонецЦикла;

Оператор Прервать останавливает цикл после первого совпадения — это экономит время на больших массивах. Если нужны индексы всех совпадений, уберите Прервать и собирайте индексы в отдельный массив. Для массивов структур перебор — единственный корректный вариант поиска, поскольку условие можно построить по любому полю: Если Массив[Индекс].Артикул = ИскомыйАртикул Тогда.

Особенности сравнения значений разных типов

Метод Найти() сравнивает значения строго: Найти("5") не найдёт число 5, потому что строка и число — разные типы. Это самая частая причина «непонятного» поведения, когда элемент визуально есть в массиве, но поиск возвращает Неопределено. Перед поиском приводите искомое значение к типу элементов массива явно: Число(), Строка(), XMLСтрока() для ссылок.

При поиске ссылок сравнение идёт по уникальному идентификатору объекта: две переменные, указывающие на один и тот же элемент справочника, будут найдены корректно. А вот сравнение по представлению или наименованию не сработает — Найти("Контрагент ООО Ромашка") не найдёт ссылку, даже если представление совпадает. Для дат учитывайте, что сравнивается значение с точностью до секунды, поэтому дата со временем не будет равна дате без времени.

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

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

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

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

Что использовать для поиска

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

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

Перебор в цикле

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

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

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

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

Поиск по нескольким колонкам через НайтиСтроки(). Ограничение: тяжелее по памяти и коду для простых списков

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

Убедиться, что индекс найден верно, помогает простая проверка: вывести Массив[Индекс] и сравнить с искомым значением. В конфигураторе удобно использовать точку останова и табло (окно «Выражения»): добавьте туда Индекс, Массив.Количество() и сам элемент. Так видно и значение индекса, и реальное содержимое массива на момент поиска.

Полезный приём при подозрении на несовпадение типов — вывести ТипЗнч(Массив[0]) и ТипЗнч(ИскомоеЗначение). Если типы различаются, причина неудачного поиска найдена. Также проверяйте пробелы и регистр в строках: Найти() чувствителен к регистру, поэтому для строк без учёта регистра надёжнее использовать перебор со ВРег() или НРег().

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

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

Значение переменной Индекс после Найти()
Норма

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

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

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

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

Значения совпадают

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

Найден другой элемент — проверьте дубли и условие поиска

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

ТипЗнч() возвращает одинаковые типы

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

Разные типы — нужно явное приведение перед поиском

FAQ

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

Значение Неопределено. Всегда проверяйте результат через «Если Индекс <> Неопределено», прежде чем использовать его для удаления или чтения элемента, иначе получите ошибку исполнения.

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

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

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

Нет, структуры не сравниваются по значению. Используйте перебор с условием по конкретному полю, например: Если Массив[Индекс].Код = ИскомыйКод Тогда.

Почему Найти() не находит строку, которая точно есть в массиве?

Чаще всего причины — регистр символов, лишние пробелы или неразличимые символы (например, неразрывный пробел). Примените СокрЛП() и ВРег() к обеим сторонам сравнения в цикле перебора.

Как удалить элемент по найденному индексу безопасно?

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

Чем отличается ВГраница() от Количество()?

Количество() — число элементов, ВГраница() — индекс последнего элемента, то есть Количество() минус 1. Для перебора по индексам используйте ВГраница(), иначе выйдете за пределы массива.

Итог

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

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