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

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

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

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

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

Главное различие между способами — нагрузка на базу и точность результата. Запрос с группировкой выполняется на стороне СУБД и возвращает одно число, а программный перебор вычитывает записи по одной и на больших таблицах работает долго. Ниже разобраны рабочие варианты кода для управляемых и обычных форм, особенности периодических регистров и типичные ошибки.

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

Способ 1. Запрос с функцией КОЛИЧЕСТВО — основной вариант

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

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

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

"ВЫБРАТЬ

| КОЛИЧЕСТВО(*) КАК КоличествоЗаписей

|ИЗ

| РегистрСведений.КурсыВалют КАК КурсыВалют";

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

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

Количество = Результат.КоличествоЗаписей;

КонецЕсли;

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

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

bsl
ВЫБРАТЬ КОЛИЧЕСТВО(*) КАК КоличествоЗаписей ИЗ РегистрСведений.КурсыВалют КАК КурсыВалют

Способ 2. Подсчёт с отбором по условиям

На практике редко нужно общее число строк — чаще требуется количество записей, удовлетворяющих условию: по конкретному измерению, за период, по ресурсу. Условие добавляется в секцию ГДЕ, а параметры передаются через УстановитьПараметр.

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

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

"ВЫБРАТЬ

| КОЛИЧЕСТВО(*) КАК КоличествоЗаписей

|ИЗ

| РегистрСведений.ЦеныНоменклатуры КАК Цены

|ГДЕ

| Цены.ВидЦены = &ВидЦены";

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

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

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

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

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

Способ 3. Программный перебор через менеджер регистра

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

НаборЗаписей = РегистрыСведений.КурсыВалют.Выбрать();

Количество = 0;

Пока НаборЗаписей.Следующий() Цикл

Количество = Количество + 1;

КонецЦикла;

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

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

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

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

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

Перебор через Выбрать()

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

Динамический список

Показывает количество строк в интерфейсе, но не предназначен для программного получения точного числа.

Подсчёт в пользовательском режиме без программирования

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

В форме списка доступна настройка отбора и сортировки, а в некоторых конфигурациях в строке состояния или через команду «Вывести список» видно итоговое число строк. Выведенный в табличный документ список показывает фактическое количество выведенных записей.

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

Как посчитать записи через консоль запросов
  1. 1
    Откройте консоль запросов в режиме 1С:Предприятие
  2. 2
    Вставьте текст: ВЫБРАТЬ КОЛИЧЕСТВО(*) ИЗ РегистрСведений.ИмяРегистра
  3. 3
    При необходимости добавьте секцию ГДЕ с отбором и заполните параметры
  4. 4
    Нажмите «Выполнить» и проверьте значение в колонке результата

Особенности для периодических и подчинённых регистров

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

Регистр, подчинённый регистратору, заполняется движениями документов. Удаление документа удаляет его записи, поэтому количество строк меняется при перепроведении и пометке на удаление. Подсчёт здесь тоже выполняется запросом, но при анализе имеет смысл группировать по регистратору.

// Количество уникальных комбинаций измерений (актуальных значений)

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

"ВЫБРАТЬ

| КОЛИЧЕСТВО(*) КАК КоличествоЗаписей

|ИЗ

| РегистрСведений.КурсыВалют.СрезПоследних(&Период, ) КАК Срез";

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

Производительность и типичные ошибки

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

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

Ещё одна ошибка — забыть про разделители в сервисе (SaaS). В разделённой базе запрос без учёта разделителя может вернуть данные только текущей области, что иногда и требуется, но при административном анализе даёт неверную картину.

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

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

Скорость выполнения
Норма

Запрос с КОЛИЧЕСТВО выполняется быстро даже на большом регистре

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

Подсчёт занимает минуты — вероятно, используется перебор или выгрузка таблицы

Значение результата
Норма

Целое число, для пустого регистра — 0

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

NULL, Неопределено или ошибка исполнения запроса

Соответствие ожиданиям
Норма

Число совпадает с количеством строк в форме списка при том же отборе

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

Расхождение — проверьте, не используется ли срез последних вместо основной таблицы

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

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

Откройте форму списка регистра и выведите список в табличный документ — количество строк будет видно в результате. Для точного числа с отбором удобнее консоль запросов с текстом ВЫБРАТЬ КОЛИЧЕСТВО(*).

Что вернёт КОЛИЧЕСТВО(*) для пустого регистра?

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

Чем отличается количество записей в срезе последних от основной таблицы?

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

Можно ли посчитать записи по группам, а не общее число?

Да. Добавьте измерение в список выборки и секцию СГРУППИРОВАТЬ ПО — запрос вернёт количество записей по каждому значению измерения, например число цен по каждому виду цен.

Почему перебор через Выбрать() работает медленно?

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

Как посчитать записи регистра, подчинённого регистратору, по конкретному документу?

Добавьте в запрос условие ГДЕ Регистратор = &Документ и передайте ссылку на документ параметром. КОЛИЧЕСТВО(*) вернёт число строк движений именно этого документа.

Итог

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

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