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

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

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

Попытка решить такую задачу в одном запросе с простой группировкой приводит к ошибке: агрегатная функция СУММА либо суммирует все строки документа, задваивая количество, либо при расчете МАКСИМУМ платформа берет максимальное значение по всей выборке, а не сумму максимумов. Рассмотрим подробнее, как правильно реализовать подобный расчет и решить сопутствующую проблему объединения разнородных выборок.

Способ 1. Многоуровневый расчет через временные таблицы в пакетном запросе

Проанализируем механику работы языка запросов 1С. В секции ИТОГИ или при группировке функция СУММА всегда рассчитывается по детальным записям источника данных. Чтобы получить сумму максимумов, необходимо разделить расчет на два последовательных шага с использованием временной таблицы.

Разберем по шагам создание пакетного запроса:

  1. Первый этап (сворачивание на уровне документа): во временную таблицу выбираются данные с группировкой по номенклатуре и ссылке на документ. Для поля суммы применяется агрегатная функция СУММА, а для поля количества — МАКСИМУМ. Таким образом, по каждому отдельному документу мы получаем его суммарную стоимость и его максимальный объем обработки.
  2. Второй этап (итоговая агрегация по номенклатуре): во втором запросе пакета данные считываются из временной таблицы и группируются уже только по номенклатуре, где к обоим полям (и к сумме, и к ранее вычисленному максимуму) применяется функция СУММА.

Посмотрим на пример практической реализации данного запроса:


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

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ.Номенклатура КАК Номенклатура,
    СУММА(ВТ.МаксКоличество) КАК ИтоговоеКоличество,
    СУММА(ВТ.Сумма) КАК ИтоговаяСумма
ИЗ
    ВТ_СвернутыеПоДокументам КАК ВТ
СГРУППИРОВАТЬ ПО
    ВТ.Номенклатура

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

Способ 2. Вычисление суммы максимумов через функции СКД

Если отчет разрабатывается с использованием Системы компоновки данных (СКД), усложнять текст запроса временными таблицами не обязательно. СКД предоставляет специальные функции для работы с агрегатами массивов.

Разберем настройку расчета ресурсов в СКД:

  1. В основном запросе СКД оставляем детальные записи без искусственных предварительных группировок.
  2. Переходим на вкладку Ресурсы.
  3. Для поля КоличествоОбработано в колонке «Выражение» задаем расчет через агрегацию массива:

Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(КоличествоОбработано)", "ДокументСсылка"))

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

Объединение запросов с разным количеством полей (ОБЪЕДИНИТЬ ВСЕ)

Когда требуется соединить в одном отчете разные операции (например, списания/выпуск из технологических операций и приход из документов поступления продукции), часто применяется оператор ОБЪЕДИНИТЬ ВСЕ. При этом возникает ситуация, когда в одной ветке запроса полей больше, чем в другой.

Выясним правила корректного выравнивания колонок:

  1. Одинаковое количество полей: все запросы, участвующие в объединении, обязаны возвращать строго одинаковое число колонок в одном и том же порядке.
  2. Заполнение отсутствующих полей: для недостающих колонок необходимо явно передавать пустые значения. Вместо нетипизированного NULL рекомендуется использовать явное приведение типов с помощью ВЫРАЗИТЬ или литералы нужного типа. Для чисел лучше задавать 0, а для строк — пустую строку "". Это предотвращает ошибки несовместимости типов в СУБД и избавляет от необходимости применять функцию ЕСТЬNULL на последующих этапах.
  3. Псевдонимы полей: имена колонок результирующей таблицы всегда определяются первой выборкой. Во второй и последующих выборках псевдонимы игнорируются.

Посмотрим на пример объединения двух разнородных источников:


ВЫБРАТЬ
    Операции.Номенклатура КАК Номенклатура,
    Операции.ТехОперация КАК ТехОперация,
    Операции.КоличествоОбработано КАК Количество,
    Операции.Сумма КАК Сумма
ИЗ
    ВТ_Операции КАК Операции

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    Поступления.Номенклатура,
    ЗНАЧЕНИЕ(Справочник.ТехнологическиеОперации.ПустаяСсылка),
    Поступления.Количество,
    ВЫРАЗИТЬ(0 КАК ЧИСЛО(15, 2))
ИЗ
    Документ.ПоступлениеТоваровУслуг.Товары КАК Поступления

Рекомендация по оптимизации: если конфигурация использует регистры накопления для учета затрат и выпуска продукции, предпочтительно строить выборки к виртуальным таблицам Обороты или ОстаткиИОбороты, а не к табличным частям документов. Это значительно ускоряет работу запроса и автоматически фильтрует непроведенные документы.

← На главную