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