1с блог в кирове - 1С: Франчайзи - сервис

Срез последних на каждую дату в запросе

Срез последних на каждую дату в запросе

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

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

СГРУППИРОВАТЬ ПО
ПродажиОбороты.Период,
ПродажиОбороты.Контрагент,
ПродажиОбороты.Номенклатура

ИНДЕКСИРОВАТЬ ПО
Номенклатура,
Дата,
Контрагент
;

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

СГРУППИРОВАТЬ ПО
втБезЦены.Дата,
втБезЦены.Контрагент,
втБезЦены.Номенклатура,
втБезЦены.Количество,
втБезЦены.Стоимость

ИНДЕКСИРОВАТЬ ПО
Номенклатура,
Дата,
Контрагент,
Период
;

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