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