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

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

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

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

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

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

Ниже разобраны рабочие способы с примерами кода: от простого перебора выборки до группировки с подсчётом по категориям. Отдельно рассмотрены типичные ошибки, которые приводят к неверным числам или лишней нагрузке на базу.

Какие способы подсчёта записей существуют в 1С

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

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

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

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

Самый быстрый вариант, когда нужно только число. Не возвращает сами записи.

Перебор выборки со счётчиком

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

Выгрузка в таблицу значений

Удобна для повторного доступа к данным, но расходует память на больших выборках.

Итоги запроса

Дают и детали, и количество, но усложняют структуру обхода результата.

Подсчёт через агрегатную функцию Количество

Наиболее производительный способ — попросить СУБД посчитать записи. Для этого в тексте запроса используется функция Количество. Вариант Количество(*) считает все строки результата, а Количество(Поле) — только строки, где указанное поле не равно NULL.

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

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

"ВЫБРАТЬ

| Количество(*) КАК КоличествоЗаписей

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| НЕ Номенклатура.ПометкаУдаления";

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

Выборка = Результат.Выбрать();

Если Выборка.Следующий() Тогда

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

КонецЕсли;

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

Подсчёт уникальных значений через Различные

Если нужно узнать количество уникальных значений (например, сколько разных контрагентов встречается в документах), используется конструкция Количество(РАЗЛИЧНЫЕ Поле). Это стандартный приём для оценки количества дублей и аналитики.

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

"ВЫБРАТЬ

| Количество(РАЗЛИЧНЫЕ Продажи.Контрагент) КАК КоличествоКонтрагентов

|ИЗ

| РегистрНакопления.Продажи КАК Продажи";

Подсчёт через перебор выборки

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

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

КоличествоЗаписей = 0;

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

КоличествоЗаписей = КоличествоЗаписей + 1;

// обработка текущей записи

КонецЦикла;

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

Подсчёт через таблицу значений

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

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

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

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

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

Частая задача — узнать количество записей не вообще, а по каждой группе: сколько документов у каждого контрагента, сколько строк в каждом заказе. Здесь используется секция СГРУППИРОВАТЬ ПО вместе с агрегатной функцией.

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

"ВЫБРАТЬ

| РеализацияТоваров.Контрагент КАК Контрагент,

| Количество(РАЗЛИЧНЫЕ РеализацияТоваров.Ссылка) КАК КоличествоДокументов

|ИЗ

| Документ.РеализацияТоваровУслуг КАК РеализацияТоваров

|СГРУППИРОВАТЬ ПО

| РеализацияТоваров.Контрагент";

Для фильтрации групп по количеству (например, найти контрагентов с более чем десятью документами) применяется секция ИМЕЮЩИЕ, а не ГДЕ. Условие ГДЕ отбирает строки до группировки и не может ссылаться на результат агрегата.

Порядок действий для группового подсчёта
  1. 1
    Сформулируйте, по какому полю нужна группировка
  2. 2
    Добавьте в выборку поле группировки и Количество с нужным аргументом
  3. 3
    Напишите секцию СГРУППИРОВАТЬ ПО с полем группировки
  4. 4
    Если нужен отбор групп по числу — добавьте ИМЕЮЩИЕ с условием на агрегат
  5. 5
    Выполните запрос и проверьте результат на тестовых данных с известным количеством

Проверка количества записей в консоли запросов

На этапе разработки и отладки удобно смотреть количество записей в консоли запросов — внешней обработке, которая есть в составе многих инструментов разработчика. Консоль обычно показывает число строк результата после выполнения, что позволяет быстро проверить отборы и соединения без написания кода.

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

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

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

Запрос с Количество(*) возвращает строку
Норма

Одна строка с числом, включая ноль

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

Пустой результат — вероятно, ошибка в тексте запроса

Число соответствует ожиданиям
Норма

Совпадает с ручным подсчётом в списке справочника или документа

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

Расхождение — проверьте условия ГДЕ и соединения таблиц

Производительность
Норма

Запрос с агрегатом выполняется быстро даже на больших таблицах

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

Выгрузка в таблицу значений большой выборки вызывает паузы и рост памяти

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

Самая распространённая ошибка — использование Количество(Поле) там, где нужно Количество(*). Если в поле встречаются значения NULL (например, после левого соединения), такие строки не попадут в подсчёт, и число окажется заниженным без каких-либо предупреждений.

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

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

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

Часто задаваемые вопросы

Почему Количество(Поле) и Количество() дают разные числа?

Функция Количество(Поле) не учитывает строки, где указанное поле равно NULL, а Количество() считает все строки результата. Разница между значениями показывает, сколько записей содержит пустое значение в этом поле. Чаще всего NULL появляется при левых соединениях, когда в присоединяемой таблице нет соответствующей записи.

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

У объекта выборки нет свойства с числом строк. Чтобы получить количество заранее, выполните отдельный запрос с Количество(*) по тем же условиям либо выгрузите результат в таблицу значений и прочитайте её метод Количество(). Первый вариант быстрее, второй удобнее, если данные нужны повторно.

Можно ли посчитать записи в динамическом списке формы?

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

Что быстрее: запрос с Количество или перебор выборки со счётчиком?

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

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

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

Почему запрос с Количество(*) не возвращает пустой результат при отсутствии записей?

Агрегатный запрос без группировки всегда возвращает одну строку: если записей нет, значение агрегата равно нулю. Поэтому проверять нужно не Результат.Пустой(), а само значение поля после обхода выборки. Это стандартное поведение SQL-подобных агрегатов.

Итог

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

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