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