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