Разработка и Конфигурация · 9 мин
Как узнать количество строк в динамическом списке 1С
Как программно получить количество строк динамического списка в 1С: через СКД, временную таблицу и пакетный запрос. Примеры кода, ограничения и типичные ошибки.
Динамический список в управляемой форме 1С не хранит данные целиком: он подгружает их порциями по мере прокрутки. Поэтому привычного свойства «КоличествоСтрок» у него нет, а попытка обойти строки программно приводит к чтению только загруженного фрагмента. Это главная причина, почему вопрос подсчёта строк возникает у разработчиков регулярно.
Тем не менее задача решаема. Количество записей, которые вернёт динамический список с текущими отбором и параметрами, можно вычислить, повторив его запрос через схему компоновки данных и добавив агрегатную функцию либо подсчитав строки результата. Ниже разобраны рабочие способы, их ограничения и типичные ошибки.
Почему у динамического списка нет готового счётчика строк
Динамический список построен на механизме динамического считывания данных: платформа запрашивает у базы только те записи, которые видны в таблице формы, плюс небольшой буфер. Полная выборка никогда не материализуется на клиенте, поэтому объект списка физически не знает общее число строк без дополнительного обращения к базе.
Отсюда следует важное ограничение: любой способ подсчёта — это дополнительный запрос к базе данных. На больших таблицах (сотни тысяч записей) такой запрос может выполняться заметное время, особенно если в списке сложные соединения или отборы по неиндексированным полям. Подсчёт стоит выполнять по требованию пользователя или в фоновом задании, а не при каждом обновлении формы.
Способ 1: выполнить запрос динамического списка через СКД
Самый корректный подход — получить схему компоновки данных и настройки динамического списка и выполнить их программно на сервере. Тогда учитываются произвольный запрос, отборы, параметры и отборы пользователя без ручного дублирования логики.
Для этого используется метод формы ПолучитьИсполняемуюСхемуКомпоновкиДанных() и ПолучитьИсполняемыеНастройкиКомпоновкиДанных(), доступные у расширения формы динамического списка. Результат СКД выводится в таблицу значений, у которой уже есть метод Количество().
&НаСервере
Функция КоличествоСтрокСписка()
Схема = Элементы.Список.ПолучитьИсполняемуюСхемуКомпоновкиДанных();
Настройки = Элементы.Список.ПолучитьИсполняемыеНастройкиКомпоновкиДанных();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Макет = КомпоновщикМакета.Выполнить(Схема, Настройки, , ,
Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(Макет);
Результат = Новый ТаблицаЗначений;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(Результат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Возврат Результат.Количество();
КонецФункции
Методы получения исполняемой схемы и настроек доступны только на сервере и только в управляемой форме с реквизитом типа «ДинамическийСписок». В обычных формах и на толстом клиенте придётся работать с запросом напрямую.
Способ 2: отдельный запрос с теми же отборами
Если запрос списка простой и отборы формируются программно, часто проще написать отдельный запрос с агрегатной функцией. Он выполняется быстрее, чем выгрузка всех строк в таблицу значений, потому что СУБД возвращает одно число вместо полного набора данных.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Товары.Ссылка) КАК КоличествоСтрок
|ИЗ
| Справочник.Товары КАК Товары
|ГДЕ
| Товары.Родитель = &Группа";
Запрос.УстановитьПараметр("Группа", ТекущаяГруппа);
Выборка = Запрос.Выполнить().Выбрать();
Выборка.Следующий();
КоличествоСтрок = Выборка.КоличествоСтрок;
Главная сложность этого способа — синхронизация условий. Если пользователь меняет отбор в списке через настройки, ваш отдельный запрос об этом не узнает, и число будет отличаться от того, что видит пользователь. Поэтому способ подходит, когда отборы фиксированы или полностью контролируются вашим кодом.
Способ 3: подсчёт через динамическое считывание порциями
Если нужно не просто число, а обход всех данных списка с сохранением его настроек, можно использовать динамическое считывание: выполнить СКД и читать результат порциями, суммируя количество записей. По сути это вариация первого способа, но без выгрузки всей таблицы в память.
Этот вариант оправдан, когда записей очень много и выгрузка полной таблицы значений рискует занять слишком много оперативной памяти на сервере. Для простого отображения счётчика пользователю такой подход избыточен — используйте агрегатный запрос.
Сравнение вариантов
Точно повторяет список со всеми отборами и параметрами, но выгружает весь результат в память — тяжело на больших выборках.
Быстрый и лёгкий, возвращает одно число, но отборы нужно дублировать вручную и держать в синхронизации со списком.
Экономит память при обходе миллионов записей, но код сложнее и не нужен для простого счётчика.
Как вывести количество строк пользователю
Типичный сценарий — показать число записей в надписи на форме или в заголовке. Рекомендуемый порядок: добавить на форму декорацию или элемент надписи, создать команду «Обновить количество» и в её серверном обработчике вызывать функцию подсчёта.
- 1Добавьте на форму элемент надписи для вывода числа и команду с кнопкой
- 2В серверной функции получите исполняемую схему и настройки списка
- 3Выполните компоновку в таблицу значений и возьмите её Количество()
- 4Присвойте результат тексту надписи
- 5Проверьте: измените отбор в списке и повторно нажмите кнопку — число должно измениться
Если счётчик нужен «вживую» при каждом изменении отбора, подключите обработчик ожидания с задержкой в одну-две секунды после изменения настроек: это отсечёт лавину запросов при быстром вводе условий пользователем. Для больших баз подсчёт лучше вынести в фоновое задание с индикацией выполнения.
Особенности и ограничения
Несколько моментов, которые влияют на результат. Во-первых, если в динамическом списке включена группировка, выгруженная таблица будет содержать и строки групп — их нужно исключать или считать только детальные записи. Во-вторых, основная таблица списка с установленным признаком «Произвольный запрос» и сложными соединениями может возвращать дубли ссылок — тогда считать следует КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Ссылка), а не общее число строк.
В-третьих, стандартные отборы, наложенные пользователем через «Ещё — Настроить список», попадут в исполняемые настройки автоматически при использовании первого способа, но не попадут в ваш отдельный запрос. Это самая частая причина расхождения «счётчик показывает одно, в списке видно другое».
Проверка результата
Убедиться в корректности подсчёта можно простым способом: временно отключить все отборы и сравнить полученное число с количеством записей в самой таблице (например, через консоль запросов тем же агрегатом). Затем по одному включать отборы и сверять изменение счётчика.
Как проверить результат
Совпадает с КОЛИЧЕСТВО по таблице в консоли запросов
Число меньше — проверьте произвольный запрос и соединения
Меняется при изменении настроек списка
Не реагирует на отбор — используется отдельный запрос без синхронизации
Подсчёт занимает доли секунды на типовом объёме
Форма подвисает — перенесите подсчёт в фоновое задание
Что важно запомнить
Готового счётчика у динамического списка нет. Точное число с учётом всех отборов даёт выполнение исполняемой СКД в таблицу значений; быстрый вариант — отдельный запрос с КОЛИЧЕСТВО, но отборы придётся синхронизировать вручную. Подсчёт выполняйте на сервере, по требованию, а на больших таблицах — в фоне.
Частые вопросы
Можно ли узнать количество строк без выполнения запроса к базе?
Нет. Динамический список подгружает данные порциями и не знает полный объём выборки. Любой способ подсчёта — это дополнительное обращение к СУБД: либо выполнение СКД списка, либо отдельный агрегатный запрос.
Почему мой счётчик не совпадает с тем, что видно в списке?
Чаще всего причина в том, что отдельный запрос не учитывает отборы, которые пользователь наложил через настройки списка. Используйте исполняемые настройки компоновки — они включают и пользовательские отборы. Также проверьте дубли ссылок при соединениях.
Работает ли подсчёт, если в списке есть группировки?
Работает, но выгруженная таблица будет содержать строки группировок вместе с детальными записями. Либо фильтруйте их при подсчёте, либо выполняйте отдельный агрегатный запрос по детальным записям.
Как посчитать строки в обычной форме (не управляемой)?
В обычных формах методов получения исполняемой СКД нет. Используйте отдельный запрос с теми же условиями, что установлены в свойстве «Запрос» списка, и функцией КОЛИЧЕСТВО. Параметры и отборы придётся передавать вручную.
Насколько подсчёт нагружает базу при миллионах записей?
Запрос вида КОЛИЧЕСТВО по индексированным полям обычно выполняется приемлемо, но со сложными соединениями и отборами по неиндексированным полям может занять секунды. В таких случаях выносите подсчёт в фоновое задание и не вызывайте его автоматически при каждом изменении формы.