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

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

С какого значения начинается индексация элементов коллекций в 1С

Разбираемся, с какого значения начинается индексация массивов, таблиц значений и других коллекций в 1С, как обращаться к элементам и избегать типичных ошибок.

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

Это правило часто становится источником ошибок у разработчиков, которые приходят в 1С из языков с индексацией с единицы, или у начинающих, которые интуитивно обращаются к первому элементу по индексу 1. Результат — ошибка «Индекс находится за границами массива» или обращение не к тому элементу, который ожидался.

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

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

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

Например, если табличная часть документа содержит три строки, то программно они доступны по индексам 0, 1 и 2. Попытка обратиться к элементу с индексом 3 вызовет исключение, потому что такого элемента не существует.

МассивИндекс с 0

Первый элемент — Массив[0]

Таблица значенийИндекс с 0

Первая строка — Таблица[0]

Список значенийИндекс с 0

Первый элемент — Список[0]

Табличная частьИндекс с 0

Номер строки на форме при этом начинается с 1

Как правильно обращаться к первому и последнему элементу

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

Типовой приём выглядит так: ПоследнийЭлемент = Массив[Массив.Количество() - 1];. Если коллекция пустая, такое обращение приведёт к ошибке, поэтому перед доступом к последнему элементу стоит проверять, что количество элементов больше нуля.

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

1c
Массив = Новый Массив;
Массив.Добавить("Первый");
Массив.Добавить("Второй");

Первый = Массив[0]; // "Первый"
Последний = Массив[Массив.Количество() - 1]; // "Второй"

Обход коллекции в цикле: с нуля или без индексов

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

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

Безопасный обход коллекции по индексам
  1. 1
    Получите количество элементов: Всего = Коллекция.Количество()
  2. 2
    Организуйте цикл: Для Индекс = 0 По Всего - 1 Цикл
  3. 3
    Обращайтесь к элементу внутри цикла: Элемент = Коллекция[Индекс]
  4. 4
    При удалении элементов итерируйтесь в обратном порядке: от Всего - 1 до 0
  5. 5
    Проверьте результат на тестовых данных с пустой и заполненной коллекцией

Удаление элементов при обходе

Частая ошибка — удалять элементы коллекции в прямом цикле от начала к концу. После удаления элемента все последующие сдвигаются на одну позицию, индексы «съезжают», и часть элементов пропускается. Правильный приём — обход с конца: Для Индекс = -Массив.ВГраница() По 0 Цикл либо вычитание единицы из индекса после удаления.

Где в 1С нумерация начинается с единицы

Несмотря на нулевую индексацию коллекций, в платформе есть контексты, где пользователь видит нумерацию с единицы. Самый заметный пример — колонка «НомерСтроки» в табличных частях: первая строка на форме имеет номер 1, хотя её программный индекс равен 0. Свойство НомерСтроки строки табличной части также возвращает значение, начиная с 1.

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

Методы, помогающие избежать ручной работы с индексами

Платформа предоставляет методы, которые снижают необходимость вычислять индексы вручную. У массива есть метод ВГраница(), возвращающий индекс последнего элемента (или -1 для пустого массива) — это надёжнее, чем Количество() - 1, и сразу сигнализирует о пустой коллекции.

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

Методы Вставить() и Сдвинуть() позволяют управлять позицией элементов, но требуют корректного индекса. Перед вызовом Вставить(Индекс, Значение) убедитесь, что индекс не превышает количество элементов, иначе получите исключение.

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

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

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

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

Как проверить корректность кода с индексами

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

Полезно временно выводить в отладку индекс и значение элемента на каждой итерации цикла. Если первый выводимый индекс не равен нулю или последний не равен количеству минус один, границы цикла заданы неверно.

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

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

Первый обработанный элемент
Норма

Соответствует элементу с индексом 0

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

Первый элемент пропущен или обработан дважды

Последний элемент
Норма

Обработан, исключений нет

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

Ошибка «Индекс за границами» или последний элемент пропущен

Пустая коллекция
Норма

Код завершается без ошибок

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

Исключение при обращении к элементу

Удаление элементов
Норма

Удалены все нужные элементы

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

Часть элементов пропущена

Часто задаваемые вопросы

С какого индекса начинается массив в 1С?

С нуля. Первый элемент массива доступен как Массив[0], а индекс последнего элемента равен Массив.Количество() - 1 или Массив.ВГраница().

Почему номер строки табличной части начинается с 1, а индекс с 0?

Номер строки — это отображаемое для пользователя свойство, привычное по таблицам интерфейса. Индекс — внутреннее программное обращение к коллекции. Чтобы получить индекс из номера строки, вычтите единицу.

Что вернёт обращение к несуществующему индексу?

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

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

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

Можно ли обойти коллекцию вообще без индексов?

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

Индексируются ли с нуля строки результата запроса?

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

Итог

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

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