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

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

Как получить количество строк в табличной части документа 1С

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

Получение количества строк табличной части — одна из базовых операций при разработке и доработке конфигураций 1С. Она нужна для проверки заполненности документа перед проведением, для расчёта итогов, для контроля ограничений и для построения циклов обработки данных.

Основной способ — метод Количество() коллекции строк табличной части. Однако синтаксис обращения к табличной части зависит от контекста: работаете ли вы с объектом документа в модуле, со ссылкой на документ, с данными формы в управляемом приложении или с запросом. Разные контексты требуют разного кода, и путаница между ними — самая частая причина ошибок у начинающих разработчиков.

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

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

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

Если вы работаете в модуле объекта документа (например, в обработчике ПередЗаписью или ОбработкаПроведения), обращение к табличной части выполняется напрямую по её имени:

bsl
КоличествоСтрок = Товары.Количество();

Если КоличествоСтрок = 0 Тогда
    Сообщить("Документ не содержит строк в табличной части Товары");
КонецЕсли;

Здесь Товары — имя табличной части, заданное в конфигураторе. Метод возвращает значение типа Число. Если табличная часть пуста, результат будет равен нулю — это валидное значение, а не ошибка.

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

Получение количества строк через ссылку на документ

Часто в коде есть только ссылка на документ, а не объект. В этом случае обращение к табличной части через точку работает: платформа автоматически прочитает данные из базы. Синтаксис выглядит так:

bsl
КоличествоСтрок = ДокументСсылка.Товары.Количество();

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

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

Получение количества строк запросом

Когда нужно узнать количество строк без загрузки документа или по многим документам сразу, оптимален запрос с агрегатной функцией КОЛИЧЕСТВО. Табличная часть доступна в запросе как отдельная таблица с именем вида Документ.РеализацияТоваровУслуг.Товары.

bsl
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|    КОЛИЧЕСТВО(*) КАК КоличествоСтрок
|ИЗ
|    Документ.РеализацияТоваровУслуг.Товары КАК Товары
|ГДЕ
|    Товары.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", ДокументСсылка);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
    КоличествоСтрок = Выборка.КоличествоСтрок;
КонецЕсли;

Для массовой проверки запрос с группировкой вернёт количество строк сразу по всем документам выборки одним обращением к базе:

Запрос.Текст =

"ВЫБРАТЬ

| Товары.Ссылка КАК Документ,

| КОЛИЧЕСТВО(*) КАК КоличествоСтрок

|ИЗ

| Документ.РеализацияТоваровУслуг.Товары КАК Товары

|ГДЕ

| Товары.Ссылка В (&СписокДокументов)

|СГРУППИРОВАТЬ ПО

| Товары.Ссылка";

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

Количество строк в управляемой форме

В модуле управляемой формы документ представлен как данные формы, а табличная часть доступна через реквизит Объект. Обращение выглядит так:

bsl
&НаКлиенте
Процедура ТоварыПриИзменении(Элемент)
    КоличествоСтрок = Объект.Товары.Количество();
    Элементы.ГруппаИтоги.Заголовок = "Строк: " + КоличествоСтрок;
КонецПроцедуры

Обращение к Объект.Товары на клиенте работает без вызова сервера, потому что данные табличной части уже находятся в форме. Это безопасный и быстрый способ для динамического обновления заголовков, надписей и признаков доступности кнопок.

Если табличная часть выведена на форму как элемент «Таблица формы», не путайте количество строк данных с видимыми строками элемента формы. Элемент управления может применять отбор, и тогда отображаемых строк будет меньше, чем в данных. Метод Количество() всегда считает именно данные.

Подсчёт строк по условию и связанные задачи

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

Отбор = Новый Структура("Цена", 0);

СтрокиБезЦены = Объект.Товары.НайтиСтроки(Отбор);

КоличествоПроблемных = СтрокиБезЦены.Количество();

Для сложных условий, которые не выразить равенством значений, подходит обычный цикл со счётчиком:

Счётчик = 0;

Для Каждого СтрокаТовары Из Объект.Товары Цикл

Если СтрокаТовары.Количество * СтрокаТовары.Цена > 100000 Тогда

Счётчик = Счётчик + 1;

КонецЕсли;

КонецЦикла;

Для построчной нумерации или вывода номера строки используйте свойство НомерСтроки строки табличной части — оно заполняется платформой автоматически и начинается с единицы.

Сравнение вариантов

Объект.Товары.Количество()

Модуль объекта, форма, незаписанный документ. Быстро, но требует загруженного объекта.

Ссылка.Товары.Количество()

Разовая проверка по ссылке. Просто, но читает всю табличную часть из базы.

Запрос с КОЛИЧЕСТВО(*)

Массовые проверки и отчёты. Оптимально по производительности, но не видит незаписанные данные.

Типичные ошибки и как их избежать

Первая распространённая ошибка — обращение к табличной части по неправильному имени. Имя в коде должно точно совпадать с именем, заданным в конфигураторе, с учётом регистра букв не имеет значения, а вот опечатка приведёт к ошибке «Поле объекта не обнаружено».

Вторая ошибка — попытка получить количество строк у запроса для ещё не записанного документа. Запрос работает только с данными в базе, поэтому для нового документа результат всегда будет нулевым, что легко принять за пустую табличную часть.

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

Типичные ошибки
01
Опечатка в имени табличной части — ошибка «Поле объекта не обнаружено» при выполнении
02
Запрос к незаписанному документу — результат 0 при фактически заполненных строках
03
Обращение Ссылка.Товары.Количество() внутри цикла — многократные чтения базы и торможение
04
Путаница между строками данных и отфильтрованными строками элемента формы — неверные выводы о заполненности

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

Чтобы убедиться, что код работает правильно, откройте документ в режиме предприятия, посчитайте строки визуально (или по номеру последней строки) и сравните с выводом вашего кода через Сообщить() или отладчик.

В отладчике удобно поставить точку останова и вычислить выражение Объект.Товары.Количество() в окне «Вычислить выражение» — вы сразу увидите и значение, и тип данных.

Дополнительная проверка: добавьте строку в табличную часть и убедитесь, что результат увеличился на единицу, затем удалите строку и проверьте уменьшение. Так вы подтвердите, что код читает актуальные данные, а не кэшированное состояние.

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

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

Значение Количество() для документа с известным числом строк
Норма

Совпадает с номером последней строки в форме документа

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

Расходится — проверьте имя табличной части и контекст обращения

Поведение для нового незаписанного документа
Норма

Обращение к объекту возвращает реальное число строк

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

Запрос возвращает 0 — это ожидаемо, используйте объект

Скорость обработки списка документов
Норма

Один запрос с группировкой выполняется быстро

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

Цикл с обращением через ссылку работает заметно медленно

Частые вопросы

Возвращает ли Количество() ноль для пустой табличной части или возникает ошибка?

Возвращает число 0, ошибки не происходит. Проверку вида «Если Товары.Количество() = 0» можно использовать как штатный способ контроля заполненности документа.

Можно ли получить количество строк всех табличных частей документа сразу?

Штатного единого метода нет. Нужно обратиться к каждой табличной части по имени. Перечень табличных частей документа можно получить через метаданные: ДокументСсылка.Метаданные().ТабличныеЧасти, и пройти по ним циклом с обращением Ссылка[ИмяТЧ].Количество().

Чем отличается Количество() от Выгрузить().Количество()?

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

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

Используйте агрегатную функцию КОЛИЧЕСТВО(*) с группировкой по полю Ссылка по таблице вида Документ.ИмяДокумента.ИмяТабличнойЧасти. Один такой запрос вернёт количество строк по каждому документу выборки.

Работает ли Количество() на клиенте в управляемой форме?

Да, обращение Объект.Товары.Количество() выполняется на клиенте без вызова сервера, так как данные табличной части уже находятся в форме. Это подходит для динамического обновления надписей и доступности элементов.

Итог

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

Используйте метод Количество() табличной части: через объект — в модулях и формах, через ссылку — для разовых проверок, через запрос с КОЛИЧЕСТВО(*) — для массовых обработок. Помните, что запрос не видит незаписанные данные, а обращение через ссылку в цикле вредит производительности.