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