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

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

Как узнать количество строк в таблице значений 1С

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

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

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

В материале разобраны основной и альтернативные способы подсчёта, отличия для обычных и управляемых форм, типичные ошибки и способы проверить результат. Примеры приведены на встроенном языке 1С и подходят для платформы 8.3.

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

У объекта «ТаблицаЗначений» есть встроенный метод Количество(), который возвращает число строк в коллекции. Это самый быстрый и правильный способ: метод не обходит строки, а обращается к служебному счётчику, поэтому его скорость не зависит от размера таблицы.

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

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

// ... заполнение таблицы ...

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

Сообщить("В таблице строк: " + ЧислоСтрок);

Если таблица только что создана и в неё ничего не добавляли, метод вернёт 0. Это нормальное состояние, а не ошибка: пустая таблица значений — валидный объект, с которым можно работать дальше. Проверка Если ТЗ.Количество() = 0 Тогда — стандартный способ убедиться, что данные загрузились.

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

Как посчитать строки, удовлетворяющие условию

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

ПараметрыОтбора = Новый Структура;

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

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

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

В структуру отбора можно добавить несколько полей — тогда условия объединяются по «И». Учтите, что сравнение идёт на точное равенство: отбор «больше нуля» или «содержит подстроку» через НайтиСтроки() задать нельзя. Для таких условий придётся перебирать таблицу в цикле со счётчиком.

Счётчик = 0;

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

Если СтрокаТЗ.Количество > 0 Тогда

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

КонецЕсли;

КонецЦикла;

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

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

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

Все строки таблицы. Мгновенно, ограничений нет.

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

Точное равенство по одному или нескольким полям. Быстро, но условия только на равенство.

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

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

Запрос с СУММА/КОЛИЧЕСТВО

Сложные условия и группировки на больших объёмах. Требует поместить ТЗ во временную таблицу.

Подсчёт через запрос и свёртку

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

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

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

"ВЫБРАТЬ

| КОЛИЧЕСТВО(*) КАК ВсегоСтрок

|ИЗ

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

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

Если Результат.Следующий() Тогда

ЧислоСтрок = Результат.ВсегоСтрок;

КонецЕсли;

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

Также таблицу значений можно поместить во временную таблицу запроса через параметр — это позволяет применять к ней любые агрегатные функции и соединения с данными базы без выгрузки в цикл.

Количество строк таблицы на форме

Если таблица значений размещена на управляемой форме как реквизит, в коде формы она доступна как объект типа «ДанныеФормыКоллекция». У неё тоже есть метод Количество(), и синтаксис почти не отличается:

&НаКлиенте

Процедура ПоказатьЧислоСтрок(Команда)

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

Сообщить("Строк в табличной части: " + ЧислоСтрок);

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

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

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

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

Дерево значений и вложенные строки

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

Чтобы посчитать все строки дерева, включая вложенные, нужен рекурсивный обход:

Функция ПосчитатьСтрокиДерева(Строки)

Всего = 0;

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

Всего = Всего + 1 + ПосчитатьСтрокиДерева(СтрокаДерева.Строки);

КонецЦикла;

Возврат Всего;

КонецФункции

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

Типичные ошибки при подсчёте строк

Самая частая ошибка — путать таблицу значений с результатом запроса. У результата запроса нет метода Количество(): сначала нужно вызвать Выгрузить() и получить таблицу значений, либо использовать выборку с подсчётом в цикле. Попытка вызвать РезультатЗапроса.Количество() приведёт к ошибке исполнения.

Вторая распространённая проблема — подсчёт строк в цикле с параллельным удалением. Если внутри Для Каждого удалять строки, коллекция изменяется во время обхода, и часть строк пропускается. Правильный приём — обход в обратном порядке через индекс: от ТЗ.Количество() - 1 до 0 с шагом -1.

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

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

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

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

Для таблиц, полученных из запроса, сверьте число строк с результатом того же запроса в консоли запросов: количество строк выборки должно совпадать со значением Количество() у выгруженной таблицы. Расхождение обычно означает, что после выгрузки таблица была изменена — добавлены или удалены строки.

Если считаете строки по условию через НайтиСтроки(), проверочный вариант — цикл со счётчиком по тому же условию. Совпадение двух независимых подсчётов подтверждает корректность отбора. Расхождение чаще всего говорит о несовпадении типов: например, в отборе строка, а в колонке — число.

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

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

Значение Количество() для новой пустой таблицы
Норма

Возвращает 0

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

Ошибка вызова — переменная не является таблицей значений

Совпадение с числом строк выборки запроса
Норма

Значения равны

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

Таблица изменялась после выгрузки

Подсчёт по условию двумя способами
Норма

НайтиСтроки() и цикл дают одно число

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

Расхождение — проверьте типы значений в отборе

Таблица на форме
Норма

Число совпадает с видимыми строками без отбора

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

На элемент формы наложен ОтборСтрок — видимых строк меньше

Частые вопросы

Чем Количество() отличается от Выгрузить().Количество() для запроса?

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

Можно ли узнать количество строк без перебора, если нужен отбор по условию «больше»?

НайтиСтроки() поддерживает только равенство, поэтому для условий вида «больше нуля» либо используйте цикл со счётчиком, либо поместите таблицу во временную таблицу запроса и примените условие ГДЕ с агрегатом КОЛИЧЕСТВО(*). На больших таблицах второй вариант заметно быстрее.

Почему Количество() показывает больше строк, чем видно на форме?

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

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

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

Влияет ли Свернуть() на результат Количество()?

Да. После свёртки строки группируются по указанным колонкам, и Количество() вернёт число сгруппированных строк, то есть число уникальных комбинаций значений колонок группировки. Исходное количество строк после свёртки восстановить нельзя.

Итог

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

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