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

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

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

Базовый вариант: подсчет по реквизиту шапки документа

Рассмотрим стандартный сценарий, когда поле группировки находится непосредственно в реквизитах документа (например, Организация или ИсточникПривлечения). Для получения корректного результата используем агрегатные функции СУММА и КОЛИЧЕСТВО с модификатором РАЗЛИЧНЫЕ.

Посмотрим на пример запроса для документа Заказ покупателя:


ВЫБРАТЬ
    ЗаказПокупателя.Организация КАК Организация,
    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ЗаказПокупателя.Ссылка) КАК КоличествоДокументов,
    СУММА(ЗаказПокупателя.СуммаДокумента) КАК СуммаДокументов
ИЗ
    Документ.ЗаказПокупателя КАК ЗаказПокупателя
ГДЕ
    ЗаказПокупателя.Проведен = ИСТИНА
    И ЗаказПокупателя.Дата МЕЖДУ &НачДата И &КонДата
СГРУППИРОВАТЬ ПО
    ЗаказПокупателя.Организация

Разберем важные особенности этой конструкции:

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

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

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

Проанализируем основные причины этой ошибки и некорректных итогов:

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

Способ 1: Явное соединение шапки документа и табличной части

Рассмотрим правильный вариант запроса, где мы соединяем документ и его табличную часть по ссылке и группируем результат по значению дополнительного свойства:


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

Способ 2: Прямая выборка из таблицы дополнительных реквизитов

Поскольку поле Ссылка в табличной части само по себе содержит ссылку на документ-владелец, мы можем обратиться к реквизитам шапки через точку от поля Ссылка. Это позволяет упростить текст запроса и избежать явной конструкции соединения:


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

Способ 3: Учет документов с незаполненным реквизитом (Левое соединение)

Если в отчет требуется включить также и те документы, у которых дополнительный реквизит не заполнен вовсе, строим запрос от таблицы документов с помощью ЛЕВОЕ СОЕДИНЕНИЕ:


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

Обратите внимание: условие по свойству ДопРеквизиты.Свойство = &Свойство в случае левого соединения обязательно помещается в секцию ПО, а не в ГДЕ. Если указать его в ГДЕ, левое соединение превратится во внутреннее, и документы без заполненного свойства отсекутся.

← На главную