Срез последних на каждую дату в СКД и в запросе
С задачей получения среза последних на каждую дату рано или поздно сталкиваются все. Безусловно, это задача достаточно просто решается запросом с соединением по максимальной дате из меньших или равных дат. Но эту же задачу можно решить и с помощью компоновки данных. Не будем рассуждать о том, какой из способов более производителен, все может зависеть от конкретной задачи.
- Описание
- Подробнее
Описание
Первый набор данных:
В качестве примера, создадим отчет по продажам, в котором отдельной колонкой будем выводить цену из прайса на дату продажи.
Создадим набор данных-запрос «ПродажиОбороты»:
ВЫБРАТЬ ПродажиОбороты.Период КАК Дата, ПродажиОбороты.Контрагент КАК Контрагент, ПродажиОбороты.Номенклатура КАК Номенклатура, ПродажиОбороты.КоличествоОборот КАК Количество, ПродажиОбороты.СтоимостьОборот КАК Стоимость {ВЫБРАТЬ Дата, Контрагент.*, Номенклатура.*, Количество, Стоимость} ИЗ РегистрНакопления.Продажи.Обороты({(&НачалоПериода)}, {(&КонецПериода)}, День, ) КАК ПродажиОбороты {ГДЕ ПродажиОбороты.Период, ПродажиОбороты.Контрагент.*, ПродажиОбороты.Номенклатура.*, ПродажиОбороты.КоличествоОборот, ПродажиОбороты.СтоимостьОборот}
Сейчас наш отчет будет иметь следующий вид:
Теперь необходимо добавить в отчет колонку «Цена по прайсу», которая будет подтягиваться из регистра сведений «Цены номенклатуры» на дату продажи.
Второй набор данных:
Добавим второй набор данных-запрос «Цены», цены будем брать для фиксированного типа цен:
ВЫБРАТЬ &Дата КАК Дата, ЦеныНоменклатурыСрезПоследних.Номенклатура КАК Номенклатура, ЦеныНоменклатурыСрезПоследних.Цена КАК Цена {ВЫБРАТЬ Дата, Номенклатура.*, Цена} ИЗ РегистрСведений.ЦеныНоменклатуры.СрезПоследних( &Дата, Номенклатура = &Номенклатура И ТипЦен = &ТипЦен) КАК ЦеныНоменклатурыСрезПоследних {ГДЕ (&Дата), ЦеныНоменклатурыСрезПоследних.Номенклатура.*, ЦеныНоменклатурыСрезПоследних.Цена}
В данном наборе данных три параметра: Дата, Номенклатура и тип цен. Из низ самые интересные Дата и Номенклатура. Они будут использованы при соединении наборов данных, причем параметр данных присутствует как в параметрах виртуальной таблицы, так и в выбранных полях.
Соединения наборов:
Приступим к основной «фишке» данного метода – соединениям наборов:
Здесь самое основное правильно настроить параметры. Если указан параметр,то СКД передает в приемник связи параметры, указанные в соединении. Значениями этих параметров будут значения соответствующих полей источника связи.
Далее добавим поле цена в ресурсы и в выбранные поля.
Результат:
Теперь можно формировать отчет. Проверим правильность работы отчета на примере «Дивана для отдыха».
В запросе:
Рассмотрим решение этой же задачи в запросе. Данная задача может быть решена как с использованием вложенных запросов, так и с помощью. временных таблиц. Попробуем решить задачу, используя временные таблицы. Сначала приведем весь текст запроса, а потом кратко разберем по частям принцип его работы.
Текст запроса:
ВЫБРАТЬ ПродажиОбороты.Период КАК Дата, ПродажиОбороты.Контрагент КАК Контрагент, ПродажиОбороты.Номенклатура КАК Номенклатура, СУММА(ПродажиОбороты.КоличествоОборот) КАК Количество, СУММА(ПродажиОбороты.СтоимостьОборот) КАК Стоимость ПОМЕСТИТЬ втБезЦены ИЗ РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, День, ) КАК ПродажиОбороты СГРУППИРОВАТЬ ПО ПродажиОбороты.Период, ПродажиОбороты.Контрагент, ПродажиОбороты.Номенклатура ИНДЕКСИРОВАТЬ ПО Номенклатура, Дата, Контрагент ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ втБезЦены.Дата КАК Дата, втБезЦены.Контрагент КАК Контрагент, втБезЦены.Номенклатура КАК Номенклатура, втБезЦены.Количество, втБезЦены.Стоимость, МАКСИМУМ(ЦеныНоменклатуры.Период) КАК Период ПОМЕСТИТЬ втМаксПериод ИЗ втБезЦены КАК втБезЦены ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры ПО втБезЦены.Номенклатура = ЦеныНоменклатуры.Номенклатура И втБезЦены.Дата >= ЦеныНоменклатуры.Период СГРУППИРОВАТЬ ПО втБезЦены.Дата, втБезЦены.Контрагент, втБезЦены.Номенклатура, втБезЦены.Количество, втБезЦены.Стоимость ИНДЕКСИРОВАТЬ ПО Номенклатура, Дата, Контрагент, Период ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ втМаксПериод.Дата, втМаксПериод.Контрагент, втМаксПериод.Номенклатура, втМаксПериод.Количество, втМаксПериод.Стоимость, ЦеныНоменклатуры.Цена ИЗ втМаксПериод КАК втМаксПериод ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры ПО втМаксПериод.Номенклатура = ЦеныНоменклатуры.Номенклатура И втМаксПериод.Период = ЦеныНоменклатуры.Период ГДЕ ЦеныНоменклатуры.ТипЦен = &ТипЦен АВТОУПОРЯДОЧИВАНИЕ
Данный пакетный запрос содержит три подзапроса. Рассмотрим их подробнее.
Первый запрос пакета группирует данные по периоду, контрагенту и номенклатуре и помещает их во временную таблицу втБезЦены. Далее мы будем соединять эту таблицу с таблицей цен номенклатуры и получим небольшой выигрыш в том, что соединять будем уже сгруппированные данные.
Во втором запросе пакета мы соединяем временную таблицу с регистром сведений «ЦеныНоменклатуры» при этом из регистра сведений мы выбираем МАКСИМАЛЬНУЮ дату из меньших или равных дат. Результат этого запроса также помещаем во временную таблицу (втМаксПериод). Посмотрим, какие данные попадают в эту таблицу:
В последнем запросе пакета, мы еще раз соединяем временную таблицу с таблицей цен номенклатуры. На этот мы соединяем таблице по номенклатуре и периоду.
Итоговый результат запроса:
Как мы видим, результаты вывода цен в обоих случаях (через СКД и через запрос) оказались одинаковы.