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

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

Как узнать количество строк в динамическом списке 1С

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

Динамический список в управляемой форме 1С не хранит данные целиком: он подгружает их порциями по мере прокрутки. Поэтому привычного свойства «КоличествоСтрок» у него нет, а попытка обойти строки программно приводит к чтению только загруженного фрагмента. Это главная причина, почему вопрос подсчёта строк возникает у разработчиков регулярно.

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

Почему у динамического списка нет готового счётчика строк

Динамический список построен на механизме динамического считывания данных: платформа запрашивает у базы только те записи, которые видны в таблице формы, плюс небольшой буфер. Полная выборка никогда не материализуется на клиенте, поэтому объект списка физически не знает общее число строк без дополнительного обращения к базе.

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

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

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

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

&НаСервере

Функция КоличествоСтрокСписка()

Схема = Элементы.Список.ПолучитьИсполняемуюСхемуКомпоновкиДанных();

Настройки = Элементы.Список.ПолучитьИсполняемыеНастройкиКомпоновкиДанных();

КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;

Макет = КомпоновщикМакета.Выполнить(Схема, Настройки, , ,

Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));

ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;

ПроцессорКомпоновки.Инициализировать(Макет);

Результат = Новый ТаблицаЗначений;

ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;

ПроцессорВывода.УстановитьОбъект(Результат);

ПроцессорВывода.Вывести(ПроцессорКомпоновки);

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

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

Методы получения исполняемой схемы и настроек доступны только на сервере и только в управляемой форме с реквизитом типа «ДинамическийСписок». В обычных формах и на толстом клиенте придётся работать с запросом напрямую.

Способ 2: отдельный запрос с теми же отборами

Если запрос списка простой и отборы формируются программно, часто проще написать отдельный запрос с агрегатной функцией. Он выполняется быстрее, чем выгрузка всех строк в таблицу значений, потому что СУБД возвращает одно число вместо полного набора данных.

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

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

"ВЫБРАТЬ

| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Товары.Ссылка) КАК КоличествоСтрок

|ИЗ

| Справочник.Товары КАК Товары

|ГДЕ

| Товары.Родитель = &Группа";

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

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

Выборка.Следующий();

КоличествоСтрок = Выборка.КоличествоСтрок;

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

Способ 3: подсчёт через динамическое считывание порциями

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

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

Сравнение вариантов

СКД + таблица значений

Точно повторяет список со всеми отборами и параметрами, но выгружает весь результат в память — тяжело на больших выборках.

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

Быстрый и лёгкий, возвращает одно число, но отборы нужно дублировать вручную и держать в синхронизации со списком.

Порционное чтение

Экономит память при обходе миллионов записей, но код сложнее и не нужен для простого счётчика.

Как вывести количество строк пользователю

Типичный сценарий — показать число записей в надписи на форме или в заголовке. Рекомендуемый порядок: добавить на форму декорацию или элемент надписи, создать команду «Обновить количество» и в её серверном обработчике вызывать функцию подсчёта.

Порядок действий
  1. 1
    Добавьте на форму элемент надписи для вывода числа и команду с кнопкой
  2. 2
    В серверной функции получите исполняемую схему и настройки списка
  3. 3
    Выполните компоновку в таблицу значений и возьмите её Количество()
  4. 4
    Присвойте результат тексту надписи
  5. 5
    Проверьте: измените отбор в списке и повторно нажмите кнопку — число должно измениться

Если счётчик нужен «вживую» при каждом изменении отбора, подключите обработчик ожидания с задержкой в одну-две секунды после изменения настроек: это отсечёт лавину запросов при быстром вводе условий пользователем. Для больших баз подсчёт лучше вынести в фоновое задание с индикацией выполнения.

Особенности и ограничения

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

В-третьих, стандартные отборы, наложенные пользователем через «Ещё — Настроить список», попадут в исполняемые настройки автоматически при использовании первого способа, но не попадут в ваш отдельный запрос. Это самая частая причина расхождения «счётчик показывает одно, в списке видно другое».

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

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

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

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

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

Счётчик без отборов
Норма

Совпадает с КОЛИЧЕСТВО по таблице в консоли запросов

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

Число меньше — проверьте произвольный запрос и соединения

Счётчик с отбором пользователя
Норма

Меняется при изменении настроек списка

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

Не реагирует на отбор — используется отдельный запрос без синхронизации

Время выполнения
Норма

Подсчёт занимает доли секунды на типовом объёме

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

Форма подвисает — перенесите подсчёт в фоновое задание

Итог

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

Готового счётчика у динамического списка нет. Точное число с учётом всех отборов даёт выполнение исполняемой СКД в таблицу значений; быстрый вариант — отдельный запрос с КОЛИЧЕСТВО, но отборы придётся синхронизировать вручную. Подсчёт выполняйте на сервере, по требованию, а на больших таблицах — в фоне.

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

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

Нет. Динамический список подгружает данные порциями и не знает полный объём выборки. Любой способ подсчёта — это дополнительное обращение к СУБД: либо выполнение СКД списка, либо отдельный агрегатный запрос.

Почему мой счётчик не совпадает с тем, что видно в списке?

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

Работает ли подсчёт, если в списке есть группировки?

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

Как посчитать строки в обычной форме (не управляемой)?

В обычных формах методов получения исполняемой СКД нет. Используйте отдельный запрос с теми же условиями, что установлены в свойстве «Запрос» списка, и функцией КОЛИЧЕСТВО. Параметры и отборы придётся передавать вручную.

Насколько подсчёт нагружает базу при миллионах записей?

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