Работа с табличными частями в 1С:Предприятие — одна из самых частых задач как для разработчиков, так и для опытных пользователей. Нередко требуется узнать количество строк в таблице документа, справочника или регистра сведений — будь то для отчетности, проверки корректности ввода данных или автоматизации бизнес-процессов. Однако методы получения этого значения сильно зависят от контекста: используете вы встроенный язык, работаете через интерфейс пользователя или нужна оптимизированная выборка для больших объемов данных.
В этой статье мы разберем 5 рабочих способов получения количества строк — от простейших для новичков до продвинутых техник для программистов. Вы узнаете, как избежать типичных ошибок при работе с Количество(), почему иногда Выгрузить() работает быстрее, чем прямая выборка, и как корректно обрабатывать пустые табличные части. Все примеры приведены для актуальных версий платформы 1С 8.3 и протестированы на конфигурациях УТ 11, БП 3.0 и ЗУП 3.1.
1. Базовый метод: функция Количество() для табличной части
Самый очевидный и часто используемый способ — встроенная функция Количество(). Она работает для любых табличных частей документов, справочников и регистров, но имеет нюансы, о которых многие забывают.
Пример кода для документа "РеализацияТоваровУслуг":
КоличествоСтрок = ДокументОбъект.Товары.Количество();
- ✅ Плюсы: простой синтаксис, работает во всех конфигурациях, не требует дополнительных прав.
- ⚠️ Минусы: если табличная часть не заполнена (например, в новом документе), вернет
0, что может сбивать логику проверок. - 🔄 Альтернатива: для регистров сведений лучше использовать
Выбрать().Количество()— об этом ниже.
Важный момент: функция Количество() возвращает количество физических строк, включая пустые (если они сохранены в базе). Чтобы исключить пустые строки, добавьте проверку:
КоличествоНепустыхСтрок = 0;
Для Каждого Строка Из ДокументОбъект.Товары Цикл
Если НЕ Строка.Пустая() Тогда
КоличествоНепустыхСтрок = КоличествоНепустыхСтрок + 1;
КонецЕсли;
КонецЦикла;
Если вам нужно часто проверять табличные части на пустоту, создайте общую функцию ПолучитьКоличествоНепустыхСтрок(ТабличнаяЧасть) и вызывайте её по мере необходимости.
2. Работа через запрос: когда Количество() не подходит
В некоторых случаях прямой вызов Количество() может быть неэффективен — например, при работе с большими табличными частями (10 000+ строк) или когда нужна дополнительная фильтрация. Здесь на помощь приходят запросы 1С.
Пример запроса для подсчета строк в табличной части документа "ПоступлениеТоваров" с фильтром по номенклатуре:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| COUNT(*) КАК Количество
|ИЗ
| Документ.ПоступлениеТоваров.Товары КАК Товары
|ГДЕ
| Товары.Ссылка = &СсылкаНаДокумент
| И Товары.Номенклатура = &Номенклатура";
Запрос.УстановитьПараметр("СсылкаНаДокумент", ДокументОбъект.Ссылка);
Запрос.УстановитьПараметр("Номенклатура", Номенклатура);
Результат = Запрос.Выполнить();
КоличествоСтрок = Результат.Выбрать().Количество();
| Сценарий | Метод | Производительность | Примечания |
|---|---|---|---|
| Малая табличная часть (<100 строк) | Количество() | ⚡ Мгновенно | Оптимальный выбор |
| Большая табличная часть (>10 000 строк) | Запрос с COUNT(*) | 🐢 Медленнее, но точнее | Добавляйте индексы по фильтруемым полям |
| Фильтрация по нескольким условиям | Запрос с ГДЕ | ⏳ Зависит от индексов | Используйте параметры, а не конкатенацию строк |
| Работа с виртуальными таблицами | Запрос к регистру | ⚠️ Может блокировать данные | Избегайте в транзакциях |
Критическая ошибка новичков: использование Выбрать().Количество() для результата запроса вместо COUNT(*) в самом запросе. Первый вариант загружает все строки в память, что приводит к тормозам при больших объемах данных.
3. Альтернативные способы: Выгрузить(), Массив и КоллекцияЗначений
Если вам нужно не только количество, но и дальнейшая обработка данных, удобно использовать методы Выгрузить() или преобразование в Массив/КоллекцияЗначений. Эти методы полезны, когда требуется:
- 📊 Анализировать данные в отрыве от 1С (например, для интеграции)
- 🔄 Обрабатывать строки параллельно в нескольких потоках
- 📋 Сохранять промежуточные результаты для отчетов
Пример с Выгрузить():
ТаблицаЗначений = ДокументОбъект.Товары.Выгрузить();
КоличествоСтрок = ТаблицаЗначений.Количество();
Пример с преобразованием в Массив:
МассивСтрок = Новый Массив;
Для Каждого Строка Из ДокументОбъект.Товары Цикл
МассивСтрок.Добавить(Строка);
КонецЦикла;
КоличествоСтрок = МассивСтрок.Количество();
⚠️ Внимание: метод Выгрузить() создает копию данных в памяти. При работе с таблицами более 50 000 строк это может привести к переполнению памяти и падению сеанса. В таких случаях используйте постраничную выборку.
Что делать если Выгрузить() вызывает ошибку "Недостаточно памяти"
Разбейте выгрузку на части с помощью параметра НачальнаяСтрока и КоличествоСтрок:
ТаблицаЧасть1 = ДокументОбъект.Товары.Выгрузить(0, 10000);
ТаблицаЧасть2 = ДокументОбъект.Товары.Выгрузить(10000, 10000);
Или используйте запрос с ограничением ПЕРВЫЕ 10000.
4. Работа с регистрами сведений и накопления
Табличные части регистров требуют особого подхода. Здесь нельзя просто вызвать Количество() — нужно использовать виртуальные таблицы или прямые запросы к регистру.
Пример для регистра сведений "ЦеныНоменклатуры":
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| COUNT(*) КАК Количество
|ИЗ
| РегистрСведений.ЦеныНоменклатуры КАК Цены
|ГДЕ
| Цены.Номенклатура = &Номенклатура
| И Цены.Период МЕЖДУ &ДатаНачала И &ДатаОкончания";
Запрос.УстановитьПараметр("Номенклатура", Номенклатура);
Запрос.УстановитьПараметр("ДатаНачала", НачалоДня(ТекущаяДата()));
Запрос.УстановитьПараметр("ДатаОкончания", КонецДня(ТекущаяДата()));
Результат = Запрос.Выполнить().Выбрать();
КоличествоЗаписей = Результат.Количество();
Для регистров накопления (например, "ТоварыНаСкладах") добавьте группировку по измерениям:
Запрос.Текст =
"ВЫБРАТЬ
| COUNT(*) КАК Количество
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
|ГДЕ
| Остатки.Склад = &Склад
| И Остатки.Номенклатура = &Номенклатура";
⚠️ Внимание: при работе с регистрами накопления не забывайте указывать виртуальную таблицу (.Остатки,.Обороты). Попытка выбрать данные напрямую из регистра без указания виртуальной таблицы приведет к ошибке.
5. Подсчет строк в форме: для пользователей без доступа к конфигуратору
Если вы не программист, но нужно быстро узнать количество строк в табличной части открытого документа, воспользуйтесь встроенными возможностями формы:
- Откройте документ (например, "Реализация товаров").
- Перейдите на вкладку с табличной частью (например,
Товары). - Нажмите
Ctrl + Fдля вызова поиска. - В поле поиска введите любой символ, который гарантированно есть в каждой строке (например,
.или пробел). - Внизу формы появится надпись
"Найдено N вхождений"— это и есть количество строк.
Для справочников (например, "Номенклатура" с табличной частью Цены"):
- 🔍 Откройте справочник в режиме списка.
- 📋 Выделите нужный элемент и нажмите
Enterдля перехода в форму. - 🖱️ Кликните правой кнопкой по заголовку табличной части и выберите
"Итоги"— в некоторых конфигурациях там отображается количество строк.
Ограничение: этот метод работает только для визуально отображаемых строк. Если в таблице есть скрытые фильтром строки, они не будут учтены.
Выделить все строки (Ctrl+A)|Посмотреть статусную строку внизу формы|Использовать поиск (Ctrl+F)|Проверить итоги по таблице (правый клик)
-->
6. Оптимизация производительности: что делать с большими таблицами
При работе с табличными частями объемом более 50 000 строк стандартные методы могут приводить к зависаниям. Вот 3 техники оптимизации:
- Постраничная обработка: разбивайте данные на блоки по 5 000–10 000 строк.
Для НомСтр = 0 По ДокументОбъект.Товары.Количество() - 1 Цикл| Если НомСтр % 5000 = 0 Тогда
| Сообщить("Обработано " + НомСтр + " строк");
| КонецЕсли;
КонецЦикла;
- Использование временных таблиц: для сложных отчетов сначала выгружайте данные во временную таблицу базы.
Запрос = Новый Запрос;Запрос.Текст = "ВЫБРАТЬ ... В #ВременнаяТаблица";
- Отключение контроля прав: если работаете в привилегированном режиме, временно отключите проверку прав для ускорения.
Попытка| УстановитьПривилегированныйРежим(Истина);
| // Ваш код здесь
Исключение
| УстановитьПривилегированныйРежим(Ложь);
КонецПопытки;
Для регистров сведений с большим количеством записей используйте периодические выборки:
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| Период КАК Период
|ИЗ
| РегистрСведений.ЦеныНоменклатуры
|ГДЕ
| Период МЕЖДУ &ДатаНачала И &ДатаОкончания
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| МАКСИМУМ(Период) КАК Период
|ИЗ
| РегистрСведений.ЦеныНоменклатуры";
⚠️ Внимание: при работе с большими регистрами накопления (например, "ПартииТоваровНаСкладах") избегайте запросов без ограничения по периоду. Это может заблокировать базу на часы. Всегда добавляйте условие Период МЕЖДУ ... И ....
Для таблиц более 100 000 строк всегда используйте запросы с ограничением по дате или другим индексированным полям. Прямой обход строк через Для Каждого в таких случаях недопустим.
FAQ: Частые вопросы по работе с табличными частями
Можно ли получить количество строк в табличной части без открытия документа?
Да, но только через запрос. Пример для документа "ЗаказПокупателя":
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| COUNT(Товары.Ссылка) КАК КоличествоСтрок
|ИЗ
| Документ.ЗаказПокупателя.Товары КАК Товары
|ГДЕ
| Товары.Ссылка = &СсылкаНаДокумент";
Запрос.УстановитьПараметр("СсылкаНаДокумент", СсылкаНаДокумент);
Результат = Запрос.Выполнить().Выбрать().Количество();
Обратите внимание: этот метод вернет количество только если табличная часть физически сохранена в базе. Для нового (незаписанного) документа так сделать нельзя.
Почему Количество() возвращает 0, хотя в таблице есть строки?
Это типичная ситуация, когда:
- Документ еще не проведен (строки не сохранены в базе).
- Табличная часть программно очищена методом
Очистить(). - Вы работаете с динамическим списком, а не с самим объектом.
Проверьте статус документа (ДокументОбъект.Проведен()) и убедитесь, что вы обращаетесь к правильному объекту.
Как посчитать строки с определенным значением в колонке?
Используйте цикл с условием или запрос. Пример для фильтрации по колонке "Номенклатура":
КоличествоФильтрованных = 0;
Для Каждого Строка Из ДокументОбъект.Товары Цикл
Если Строка.Номенклатура = ИскомаяНоменклатура Тогда
КоличествоФильтрованных = КоличествоФильтрованных + 1;
КонецЕсли;
КонецЦикла;
Для больших таблиц лучше использовать запрос с ГДЕ.
Можно ли получить количество строк в табличной части через COM-соединение?
Да, но синтаксис будет отличаться. Пример на VBScript:
Set Doc = V8New("ДокументОбъект.ЗаказПокупателя")
Doc.FindByNumber(123)
RowCount = Doc.Товары.Count()
Внимательно следите за регистром имен полей — в COM они могут отличаться от внутренних имен 1С.
Как узнать количество строк в табличной части мобильного приложения 1С?
В мобильной платформе 1С:Предприятие методы те же, но:
- Избегайте тяжелых запросов — они блокируют UI.
- Используйте
ФоновоеЗаданиедля длительных операций. - Для отображения количества в интерфейсе используйте поле
ПодвалТаблицы.
Пример кода для мобильного клиента:
Процедура ПриОткрытии()
КоличествоСтрок = Товары.Количество();
ЭлементыФормы.ПодвалТаблицы.Заголовок = "Всего товаров: " + КоличествоСтрок;
КонецПроцедуры