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

Программист 1С v8.3 (Управляемые формы) Управленческий учет IT и автоматизация бизнеса
← На главную

При разработке отчетов или обработок в 1С часто возникает задача посчитать количество документов, сгруппировав их по определенному признаку, например, по статусу («Новая», «В работе», «Просрочено»). Новички часто сталкиваются с проблемой: запрос возвращает «ноль» или неверные данные из-за неправильной работы с результатом запроса или неверной структуры самого запроса. Давайте разберем, как решить эту задачу профессионально и избежать ошибок.

Вариант 1: Использование итогов в запросе

Этот способ идеален, когда вам нужно получить «сводные» показатели по всем статусам за один проход. Мы используем конструкцию ИТОГИ, которая позволяет системе 1С самостоятельно рассчитать сумму по заданным условиям.

Для реализации этого метода, построим запрос, который вычисляет «единички» для каждого статуса, а затем суммирует их по общим итогам:


Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
|	ВЫБОР
|		КОГДА Журнал.Статус = ЗНАЧЕНИЕ(Перечисление.Статусы.Новая) ТОГДА 1
|		ИНАЧЕ 0
|	КОНЕЦ КАК Новая,
|	ВЫБОР
|		КОГДА Журнал.Статус = ЗНАЧЕНИЕ(Перечисление.Статусы.ВРаботе) ТОГДА 1
|		ИНАЧЕ 0
|	КОНЕЦ КАК ВРаботе,
|	ВЫБОР
|		КОГДА Журнал.Статус = ЗНАЧЕНИЕ(Перечисление.Статусы.Просрочено) ТОГДА 1
|		ИНАЧЕ 0
|	КОНЕЦ КАК Просрочено
|ИЗ
|	Документ.Журнал КАК Журнал
|ИТОГИ
|	СУММА(Новая),
|	СУММА(ВРаботе),
|	СУММА(Просрочено)
|ПО
|	ОБЩИЕ";

Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

Если Выборка.Следующий() Тогда
    // Обращаемся к итогам напрямую из первой строки выборки
    КоличествоНовых = Выборка.Новая;
    КоличествоВРаботе = Выборка.ВРаботе;
    КоличествоПросроченных = Выборка.Просрочено;
КонецЕсли;

Важные моменты:

Вариант 2: Использование группировки (СГРУППИРОВАТЬ ПО)

Если вам удобнее работать с плоским списком, где каждая строка представляет отдельный статус и его количество, используйте СГРУППИРОВАТЬ ПО. Это более универсальный подход, который легко масштабируется при добавлении новых статусов.


Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
|	Журнал.Статус КАК Статус,
|	КОЛИЧЕСТВО(1) КАК Количество
|ИЗ
|	Документ.Журнал КАК Журнал
|СГРУППИРОВАТЬ ПО
|	Журнал.Статус";

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

Пока Выборка.Следующий() Цикл
    Если Выборка.Статус = Перечисления.Статусы.Новая Тогда
        Новые = Выборка.Количество;
    ИначеЕсли Выборка.Статус = Перечисления.Статусы.ВРаботе Тогда
        ВРаботе = Выборка.Количество;
    ИначеЕсли Выборка.Статус = Перечисления.Статусы.Просрочено Тогда
        Просрочено = Выборка.Количество;
    КонецЕсли;
КонецЦикла;

Почему этот способ надежен:

  1. Запрос возвращает ровно столько строк, сколько активных статусов используется в документах.
  2. Мы обходим результат циклом Пока Выборка.Следующий(), что исключает потерю данных.
  3. Внутри цикла мы анализируем каждое поле Статус и распределяем полученное Количество по нужным нам переменным.

Типичные ошибки при разработке

Разберем, почему у вас могли возникать «нули» или ошибки:

Совет по отладке

Если вы сомневаетесь в структуре данных, которые возвращает ваш запрос, используйте отладчик. Выгрузите результат в таблицу значений с помощью Таблица = Запрос.Выполнить().Выгрузить();. Поставив точку останова на следующей строке, вы сможете открыть переменную Таблица и наглядно увидеть, какие данные вернул запрос: есть ли там нужные строки, статусы и количественные показатели. Это лучший способ перестать «гадать» и начать программировать осознанно.

← На главную