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