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