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