Работа с табличными частями в 1С:Предприятие — одна из самых частых задач как для разработчиков, так и для опытных пользователей. Нередко требуется узнать количество строк в таблице документа, справочника или регистра сведений — будь то для отчетности, проверки корректности ввода данных или автоматизации бизнес-процессов. Однако методы получения этого значения сильно зависят от контекста: используете вы встроенный язык, работаете через интерфейс пользователя или нужна оптимизированная выборка для больших объемов данных.

В этой статье мы разберем 5 рабочих способов получения количества строк — от простейших для новичков до продвинутых техник для программистов. Вы узнаете, как избежать типичных ошибок при работе с Количество(), почему иногда Выгрузить() работает быстрее, чем прямая выборка, и как корректно обрабатывать пустые табличные части. Все примеры приведены для актуальных версий платформы 1С 8.3 и протестированы на конфигурациях УТ 11, БП 3.0 и ЗУП 3.1.

1. Базовый метод: функция Количество() для табличной части

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

Пример кода для документа "РеализацияТоваровУслуг":

КоличествоСтрок = ДокументОбъект.Товары.Количество();
  • Плюсы: простой синтаксис, работает во всех конфигурациях, не требует дополнительных прав.
  • ⚠️ Минусы: если табличная часть не заполнена (например, в новом документе), вернет 0, что может сбивать логику проверок.
  • 🔄 Альтернатива: для регистров сведений лучше использовать Выбрать().Количество() — об этом ниже.

Важный момент: функция Количество() возвращает количество физических строк, включая пустые (если они сохранены в базе). Чтобы исключить пустые строки, добавьте проверку:

КоличествоНепустыхСтрок = 0;

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

Если НЕ Строка.Пустая() Тогда

КоличествоНепустыхСтрок = КоличествоНепустыхСтрок + 1;

КонецЕсли;

КонецЦикла;

💡

Если вам нужно часто проверять табличные части на пустоту, создайте общую функцию ПолучитьКоличествоНепустыхСтрок(ТабличнаяЧасть) и вызывайте её по мере необходимости.

2. Работа через запрос: когда Количество() не подходит

В некоторых случаях прямой вызов Количество() может быть неэффективен — например, при работе с большими табличными частями (10 000+ строк) или когда нужна дополнительная фильтрация. Здесь на помощь приходят запросы 1С.

Пример запроса для подсчета строк в табличной части документа "ПоступлениеТоваров" с фильтром по номенклатуре:

Запрос = Новый Запрос;

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

"ВЫБРАТЬ

| COUNT(*) КАК Количество

|ИЗ

| Документ.ПоступлениеТоваров.Товары КАК Товары

|ГДЕ

| Товары.Ссылка = &СсылкаНаДокумент

| И Товары.Номенклатура = &Номенклатура";

Запрос.УстановитьПараметр("СсылкаНаДокумент", ДокументОбъект.Ссылка);

Запрос.УстановитьПараметр("Номенклатура", Номенклатура);

Результат = Запрос.Выполнить();

КоличествоСтрок = Результат.Выбрать().Количество();

СценарийМетодПроизводительностьПримечания
Малая табличная часть (<100 строк)Количество()⚡ МгновенноОптимальный выбор
Большая табличная часть (>10 000 строк)Запрос с COUNT(*)🐢 Медленнее, но точнееДобавляйте индексы по фильтруемым полям
Фильтрация по нескольким условиямЗапрос с ГДЕ⏳ Зависит от индексовИспользуйте параметры, а не конкатенацию строк
Работа с виртуальными таблицамиЗапрос к регистру⚠️ Может блокировать данныеИзбегайте в транзакциях

Критическая ошибка новичков: использование Выбрать().Количество() для результата запроса вместо COUNT(*) в самом запросе. Первый вариант загружает все строки в память, что приводит к тормозам при больших объемах данных.

📊 Какой метод вы используете чаще для подсчета строк?
Функция Количество()
Запросы 1С
Цикл по строкам
Виртуальные таблицы
Не знаю

3. Альтернативные способы: Выгрузить(), Массив и КоллекцияЗначений

Если вам нужно не только количество, но и дальнейшая обработка данных, удобно использовать методы Выгрузить() или преобразование в Массив/КоллекцияЗначений. Эти методы полезны, когда требуется:

  • 📊 Анализировать данные в отрыве от 1С (например, для интеграции)
  • 🔄 Обрабатывать строки параллельно в нескольких потоках
  • 📋 Сохранять промежуточные результаты для отчетов

Пример с Выгрузить():

ТаблицаЗначений = ДокументОбъект.Товары.Выгрузить();

КоличествоСтрок = ТаблицаЗначений.Количество();

Пример с преобразованием в Массив:

МассивСтрок = Новый Массив;

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

МассивСтрок.Добавить(Строка);

КонецЦикла;

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

⚠️ Внимание: метод Выгрузить() создает копию данных в памяти. При работе с таблицами более 50 000 строк это может привести к переполнению памяти и падению сеанса. В таких случаях используйте постраничную выборку.
Что делать если Выгрузить() вызывает ошибку "Недостаточно памяти"

Разбейте выгрузку на части с помощью параметра НачальнаяСтрока и КоличествоСтрок:

ТаблицаЧасть1 = ДокументОбъект.Товары.Выгрузить(0, 10000);

ТаблицаЧасть2 = ДокументОбъект.Товары.Выгрузить(10000, 10000);

Или используйте запрос с ограничением ПЕРВЫЕ 10000.

4. Работа с регистрами сведений и накопления

Табличные части регистров требуют особого подхода. Здесь нельзя просто вызвать Количество() — нужно использовать виртуальные таблицы или прямые запросы к регистру.

Пример для регистра сведений "ЦеныНоменклатуры":

Запрос = Новый Запрос;

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

"ВЫБРАТЬ

| COUNT(*) КАК Количество

|ИЗ

| РегистрСведений.ЦеныНоменклатуры КАК Цены

|ГДЕ

| Цены.Номенклатура = &Номенклатура

| И Цены.Период МЕЖДУ &ДатаНачала И &ДатаОкончания";

Запрос.УстановитьПараметр("Номенклатура", Номенклатура);

Запрос.УстановитьПараметр("ДатаНачала", НачалоДня(ТекущаяДата()));

Запрос.УстановитьПараметр("ДатаОкончания", КонецДня(ТекущаяДата()));

Результат = Запрос.Выполнить().Выбрать();

КоличествоЗаписей = Результат.Количество();

Для регистров накопления (например, "ТоварыНаСкладах") добавьте группировку по измерениям:

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

"ВЫБРАТЬ

| COUNT(*) КАК Количество

|ИЗ

| РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки

|ГДЕ

| Остатки.Склад = &Склад

| И Остатки.Номенклатура = &Номенклатура";

⚠️ Внимание: при работе с регистрами накопления не забывайте указывать виртуальную таблицу (.Остатки, .Обороты). Попытка выбрать данные напрямую из регистра без указания виртуальной таблицы приведет к ошибке.

5. Подсчет строк в форме: для пользователей без доступа к конфигуратору

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

  1. Откройте документ (например, "Реализация товаров").
  2. Перейдите на вкладку с табличной частью (например, Товары).
  3. Нажмите Ctrl + F для вызова поиска.
  4. В поле поиска введите любой символ, который гарантированно есть в каждой строке (например, . или пробел).
  5. Внизу формы появится надпись "Найдено N вхождений" — это и есть количество строк.

Для справочников (например, "Номенклатура" с табличной частью Цены"):

  • 🔍 Откройте справочник в режиме списка.
  • 📋 Выделите нужный элемент и нажмите Enter для перехода в форму.
  • 🖱️ Кликните правой кнопкой по заголовку табличной части и выберите "Итоги" — в некоторых конфигурациях там отображается количество строк.

Ограничение: этот метод работает только для визуально отображаемых строк. Если в таблице есть скрытые фильтром строки, они не будут учтены.

Выделить все строки (Ctrl+A)|Посмотреть статусную строку внизу формы|Использовать поиск (Ctrl+F)|Проверить итоги по таблице (правый клик)

-->

6. Оптимизация производительности: что делать с большими таблицами

При работе с табличными частями объемом более 50 000 строк стандартные методы могут приводить к зависаниям. Вот 3 техники оптимизации:

  1. Постраничная обработка: разбивайте данные на блоки по 5 000–10 000 строк.
    Для НомСтр = 0 По ДокументОбъект.Товары.Количество() - 1 Цикл
    

    | Если НомСтр % 5000 = 0 Тогда

    | Сообщить("Обработано " + НомСтр + " строк");

    | КонецЕсли;

    КонецЦикла;

  2. Использование временных таблиц: для сложных отчетов сначала выгружайте данные во временную таблицу базы.
    Запрос = Новый Запрос;
    

    Запрос.Текст = "ВЫБРАТЬ ... В #ВременнаяТаблица";

  3. Отключение контроля прав: если работаете в привилегированном режиме, временно отключите проверку прав для ускорения.
    Попытка
    

    | УстановитьПривилегированныйРежим(Истина);

    | // Ваш код здесь

    Исключение

    | УстановитьПривилегированныйРежим(Ложь);

    КонецПопытки;

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

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

"ВЫБРАТЬ РАЗЛИЧНЫЕ

| Период КАК Период

|ИЗ

| РегистрСведений.ЦеныНоменклатуры

|ГДЕ

| Период МЕЖДУ &ДатаНачала И &ДатаОкончания

|

|ОБЪЕДИНИТЬ ВСЕ

|

|ВЫБРАТЬ

| МАКСИМУМ(Период) КАК Период

|ИЗ

| РегистрСведений.ЦеныНоменклатуры";

⚠️ Внимание: при работе с большими регистрами накопления (например, "ПартииТоваровНаСкладах") избегайте запросов без ограничения по периоду. Это может заблокировать базу на часы. Всегда добавляйте условие Период МЕЖДУ ... И ....
💡

Для таблиц более 100 000 строк всегда используйте запросы с ограничением по дате или другим индексированным полям. Прямой обход строк через Для Каждого в таких случаях недопустим.

FAQ: Частые вопросы по работе с табличными частями

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

Да, но только через запрос. Пример для документа "ЗаказПокупателя":

Запрос = Новый Запрос;

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

"ВЫБРАТЬ

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

|ИЗ

| Документ.ЗаказПокупателя.Товары КАК Товары

|ГДЕ

| Товары.Ссылка = &СсылкаНаДокумент";

Запрос.УстановитьПараметр("СсылкаНаДокумент", СсылкаНаДокумент);

Результат = Запрос.Выполнить().Выбрать().Количество();

Обратите внимание: этот метод вернет количество только если табличная часть физически сохранена в базе. Для нового (незаписанного) документа так сделать нельзя.

Почему Количество() возвращает 0, хотя в таблице есть строки?

Это типичная ситуация, когда:

  • Документ еще не проведен (строки не сохранены в базе).
  • Табличная часть программно очищена методом Очистить().
  • Вы работаете с динамическим списком, а не с самим объектом.

Проверьте статус документа (ДокументОбъект.Проведен()) и убедитесь, что вы обращаетесь к правильному объекту.

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

Используйте цикл с условием или запрос. Пример для фильтрации по колонке "Номенклатура":

КоличествоФильтрованных = 0;

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

Если Строка.Номенклатура = ИскомаяНоменклатура Тогда

КоличествоФильтрованных = КоличествоФильтрованных + 1;

КонецЕсли;

КонецЦикла;

Для больших таблиц лучше использовать запрос с ГДЕ.

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

Да, но синтаксис будет отличаться. Пример на VBScript:

Set Doc = V8New("ДокументОбъект.ЗаказПокупателя")

Doc.FindByNumber(123)

RowCount = Doc.Товары.Count()

Внимательно следите за регистром имен полей — в COM они могут отличаться от внутренних имен 1С.

Как узнать количество строк в табличной части мобильного приложения 1С?

В мобильной платформе 1С:Предприятие методы те же, но:

  • Избегайте тяжелых запросов — они блокируют UI.
  • Используйте ФоновоеЗадание для длительных операций.
  • Для отображения количества в интерфейсе используйте поле ПодвалТаблицы.

Пример кода для мобильного клиента:

Процедура ПриОткрытии()

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

ЭлементыФормы.ПодвалТаблицы.Заголовок = "Всего товаров: " + КоличествоСтрок;

КонецПроцедуры