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

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

Количество строк в таблице значений 1С: методы и примеры

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

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

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

Материал ориентирован на платформу 1С:Предприятие 8.3 и актуален как для обычных, так и для управляемых форм: синтаксис методов таблицы значений в этой части одинаков.

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

Метод Количество() вызывается у объекта типа «ТаблицаЗначений» и возвращает целое число — число строк, физически присутствующих в таблице. Метод не принимает параметров и не изменяет саму таблицу.

ТЗ = Новый ТаблицаЗначений;

ТЗ.Колонки.Добавить("Номенклатура");

ТЗ.Колонки.Добавить("Количество");

НоваяСтрока = ТЗ.Добавить();

НоваяСтрока.Номенклатура = "Товар 1";

Сообщить("Строк в таблице: " + ТЗ.Количество()); // выведет 1

1c
ЧислоСтрок = ТЗ.Количество();
Если ЧислоСтрок > 0 Тогда
    Сообщить("Таблица содержит " + ЧислоСтрок + " строк");
Иначе
    Сообщить("Таблица пуста");
КонецЕсли;

Если таблица только что создана и строки в неё не добавлялись, метод вернёт 0. Это корректное значение, а не признак ошибки — обращение к методу у пустой, но созданной таблицы безопасно.

Ошибка возникает в другом случае: если переменная не инициализирована (равна Неопределено) или содержит значение другого типа, попытка вызвать Количество() приведёт к исключению времени выполнения. Поэтому в общих процедурах, куда таблица передаётся параметром, полезно сначала проверить тип.

Проверка таблицы на пустоту

Самое частое применение метода — проверка, есть ли в таблице хотя бы одна строка, перед началом обработки. Типовая конструкция выглядит так:

Если ТЗ.Количество() = 0 Тогда

Возврат; // нечего обрабатывать

КонецЕсли;

Такая проверка защищает от лишней работы: не запускается цикл, не выполняются запросы, не открываются транзакции. В обработках, которые вызываются часто, это заметно упрощает логику и снижает нагрузку.

Порядок действий
  1. 1
    Убедитесь, что переменная содержит объект типа ТаблицаЗначений (при необходимости проверьте через ТипЗнч)
  2. 2
    Вызовите ТЗ.Количество() и сохраните результат в переменную или используйте прямо в условии
  3. 3
    Сравните результат с нулём, если нужна проверка на пустоту
  4. 4
    При необходимости выведите значение пользователю через Сообщить() или элемент формы

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

Если ТипЗнч(ТЗ) = Тип("ТаблицаЗначений") И ТЗ.Количество() > 0 Тогда

// обработка строк

КонецЕсли;

Подсчёт строк по условию

У таблицы значений нет метода вида «посчитать строки с фильтром». Чтобы узнать, сколько строк удовлетворяет условию, применяют два подхода: метод НайтиСтроки() с последующим подсчётом элементов массива либо явный перебор в цикле со счётчиком.

Подсчёт через НайтиСтроки()

Метод НайтиСтроки(Отбор) возвращает массив строк, соответствующих структуре отбора. Количество найденных строк — это количество элементов массива:

Отбор = Новый Структура("Склад", СкладОсновной);

НайденныеСтроки = ТЗ.НайтиСтроки(Отбор);

ЧислоПодходящих = НайденныеСтроки.Количество();

Отбор в структуре работает только на равенство. Если нужно условие «больше», «не равно» или сравнение нескольких полей по сложной логике, НайтиСтроки() не подходит — используйте цикл.

Подсчёт в цикле

Счетчик = 0;

Для Каждого СтрокаТЗ Из ТЗ Цикл

Если СтрокаТЗ.Количество > 100 И СтрокаТЗ.Отгружено Тогда

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

КонецЕсли;

КонецЦикла;

Цикл универсален, но при очень больших таблицах (сотни тысяч строк) и частых вызовах стоит подумать о переносе подсчёта в запрос: агрегатная функция КОЛИЧЕСТВО в запросе к исходным данным обычно эффективнее, чем выгрузка таблицы и перебор на клиенте или сервере.

Сравнение способов подсчёта

ТЗ.Количество()

Общее число строк без условий. Самый быстрый вариант, фильтрация невозможна.

НайтиСтроки() + Количество()

Подсчёт по отбору на равенство одного или нескольких полей. Не поддерживает сравнения и сложную логику.

Цикл со счётчиком

Любые условия, включая вычисляемые. Медленнее на больших таблицах, требует больше кода.

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

Подсчёт на стороне СУБД ещё до выгрузки данных. Оптимален для больших объёмов, но требует источника данных в базе.

Особенности работы в формах и с динамическими списками

Реквизит формы типа «ТаблицаЗначений» в управляемой форме — это объект ДанныеФормыКоллекция, а не классическая таблица значений. Метод Количество() у него тоже есть и работает аналогично, поэтому на форме достаточно написать:

ЧислоСтрок = Объект.Товары.Количество(); // табличная часть документа

ЧислоСтрокФормы = ТоварыНаФорме.Количество(); // реквизит формы

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

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

Типичные ошибки и ограничения

Первая распространённая ошибка — вызов Количество() у переменной со значением Неопределено. Такое случается, когда функция, возвращающая таблицу, в какой-то ветке логики не вернула значение. Результат — исключение «Метод объекта не обнаружен» или «Значение не является значением объектного типа».

Вторая ошибка — путаница между Количество() и КоличествоСтрок(). Метода КоличествоСтрок() у таблицы значений нет; подобное имя существует у текстового документа (КоличествоСтрок() объекта ТекстовыйДокумент). Разработчики, переключаясь между объектами, иногда подставляют не то имя.

Третья ошибка — ожидание, что Количество() учитывает отбор, установленный в элементе формы. Отбор строк в таблице на форме влияет только на отображение; метод по-прежнему вернёт полное число строк коллекции. Для подсчёта видимых строк нужен НайтиСтроки() с теми же параметрами отбора.

Типичные ошибки
01
Вызов Количество() у Неопределено — исключение времени выполнения; проверяйте инициализацию переменной
02
Использование несуществующего метода КоличествоСтрок() у таблицы значений — правильное имя Количество()
03
Ожидание, что Количество() учитывает отбор строк на форме — метод возвращает полное число строк
04
Попытка передать условие в Количество() — метод не принимает параметров, для фильтрации нужен НайтиСтроки()
05
Перебор миллионов строк в цикле ради подсчёта — на больших объёмах используйте запрос с КОЛИЧЕСТВО

Производительность и выбор подхода

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

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

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

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

"ВЫБРАТЬ

| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Движения.Номенклатура) КАК ЧислоПозиций

|ИЗ

| РегистрНакопления.ТоварыНаСкладах.Остатки(, Склад = &Склад) КАК Движения";

Запрос.УстановитьПараметр("Склад", СкладОсновной);

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда

ЧислоПозиций = Выборка.ЧислоПозиций;

КонецЕсли;

Такой подход снижает объём передаваемых между сервером и СУБД данных и уменьшает потребление памяти, что особенно заметно на крупных базах.

Маршрут решения

Как выбрать действие

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

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

После внедрения кода убедитесь, что подсчёт работает корректно на граничных случаях: пустая таблица, одна строка, таблица с большим числом строк. Для отладки удобно выводить значение через Сообщить() или смотреть его в табло отладчика.

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

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

Вызов метода у пустой таблицы
Норма

Возвращает 0, исключений нет

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

Исключение «Метод объекта не обнаружен» — переменная не является таблицей значений

Подсчёт через НайтиСтроки
Норма

Число совпадает с ручным подсчётом строк по тому же отбору

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

Ноль при заведомо существующих строках — проверьте имена полей и типы значений в структуре отбора

Работа в цикле
Норма

Счётчик равен ожидаемому числу, цикл завершается

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

Счётчик больше ожидаемого — условие внутри цикла слишком широкое

Часто задаваемые вопросы

Можно ли передать условие прямо в метод Количество()?

Нет, метод не принимает параметров и всегда возвращает полное число строк. Для подсчёта с условием используйте НайтиСтроки() со структурой отбора и возьмите количество элементов полученного массива, либо организуйте цикл со счётчиком.

Чем отличается Количество() у таблицы значений и у табличной части документа?

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

Почему НайтиСтроки() возвращает пустой массив, хотя подходящие строки есть?

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

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

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

Что быстрее: Количество() по выгруженной таблице или запрос с КОЛИЧЕСТВО?

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

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

Да, через цикл с проверкой ЗначениеЗаполнено(СтрокаТЗ.ИмяКолонки) или через НайтиСтроки() с отбором по пустому значению соответствующего типа. Цикл надёжнее, так как пустое значение может быть представлено по-разному в зависимости от типа колонки.

Итог

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

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