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

Отзывов (29)FavoriteLoadingВ закладки

С задачей получения среза последних на каждую дату рано или поздно сталкиваются все. Безусловно, это задача достаточно просто решается запросом с соединением по максимальной дате из меньших или равных дат. Но эту же задачу можно решить и с помощью компоновки данных. Не будем рассуждать о том, какой из способов более производителен, все может зависеть от конкретной задачи.

Первый набор данных:

В качестве примера, создадим отчет по продажам, в котором отдельной колонкой будем выводить цену из прайса на дату продажи.

Создадим набор данных-запрос “ПродажиОбороты”:

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

Рис. 1 Вкладка ресурсы набора данных ПродажиОбороты

Рис. 2 Настройки отчета

Сейчас наш отчет будет иметь следующий вид:

Рис. 3 Формирование отчета с одним набором данных

Теперь необходимо добавить в отчет колонку “Цена по прайсу”, которая будет подтягиваться из регистра сведений “Цены номенклатуры” на дату продажи.

Второй набор данных:

Добавим второй набор данных-запрос “Цены”, цены будем брать для фиксированного типа цен:

ВЫБРАТЬ
    &Дата КАК Дата,
    ЦеныНоменклатурыСрезПоследних.Номенклатура КАК Номенклатура,
    ЦеныНоменклатурыСрезПоследних.Цена КАК Цена
{ВЫБРАТЬ
    Дата,
    Номенклатура.*,
    Цена}
ИЗ
    РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
            &Дата,
            Номенклатура = &Номенклатура
                И ТипЦен = &ТипЦен) КАК ЦеныНоменклатурыСрезПоследних
{ГДЕ
    (&Дата),
    ЦеныНоменклатурыСрезПоследних.Номенклатура.*,
    ЦеныНоменклатурыСрезПоследних.Цена}

В данном наборе данных три параметра: Дата, Номенклатура и тип цен. Из низ самые интересные Дата и Номенклатура. Они будут использованы при соединении наборов данных, причем параметр данных присутствует как в параметрах виртуальной таблицы, так и в выбранных полях.

Соединения наборов:

Приступим к основной “фишке” данного метода – соединениям наборов:

Рис. 4 Соединение наборов данных

Здесь самое основное правильно настроить параметры. Если указан параметр,то  СКД передает в приемник связи параметры, указанные в соединении. Значениями этих параметров будут значения соответствующих полей источника связи.

Далее добавим поле цена в ресурсы и в выбранные поля.

Рис. 5 Вкладка ресурсы

Рис. 6 Выбранные поля

Результат:

Теперь можно формировать отчет. Проверим правильность работы отчета на примере “Дивана для отдыха”.

Рис. 7 Итоговый отчет

В запросе:

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

Текст запроса:

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

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

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

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

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

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

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

Данный пакетный запрос содержит три подзапроса. Рассмотрим их подробнее.

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

Во втором подзапросе мы соединяем временную таблицу с регистром сведений “ЦеныНоменклатуры” при этом из регистра сведений мы выбираем МАКСИМАЛЬНУЮ дату из меньших или равных дат.  Результат этого подзапроса также помещаем во временную таблицу (втМаксПериод). Посмотрим, какие данные попадают в эту таблицу:

Рис. 8 Временная таблица втМаксПериод

В последнем запросе пакета, мы еще раз соединяем временную таблицу с таблицей цен номенклатуры. На этот мы соединяем таблице по номенклатуре и периоду.

Итоговый результат запроса:

Рис. 9 Итоговый результат запроса

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

google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru

29 Коммент.

  1. Уважаемый also, вы упоминали в начале статьи, что данную задачу можно решить в запросе. Не могли бы вы, дополнив эту статью, или в отдельной статье, описать выполнение срезов на несколько дат в запросе с подробным примером. Заранее спасибо.

    • У группировки “ПериодМесяц” (если не менял название, то так) нужно указать тип дополнения “Месяц” и установить дату начала и дату окончания периода

  2. Извините вопрос не так задал, как в СКД вывести остатки за каждый день если не было оборотов?

  3. это я смотрел но он там не пишет как он это сделал,Поставил “период” тип дополнения “месяц” установил дату нач и кон,а он если нет оборота то остатки не выводит

  4. 01.11.2010 0:00:00
    01.11.2010 0:00:00
    01.11.2010 0:00:00
    02.11.2010 0:00:00
    03.11.2010 0:00:00
    03.11.2010 0:00:00
    05.11.2010 0:00:00
    05.11.2010 0:00:00
    08.11.2010 0:00:00
    08.11.2010 0:00:00
    09.11.2010 0:00:00
    10.11.2010 0:00:00
    11.11.2010 0:00:00
    12.11.2010 0:00:00
    12.11.2010 0:00:00
    17.11.2010 0:00:00
    18.11.2010 0:00:00
    19.11.2010 0:00:00
    19.11.2010 0:00:00
    22.11.2010 0:00:00
    23.11.2010 0:00:00
    25.11.2010 0:00:00
    25.11.2010 0:00:00
    25.11.2010 0:00:00
    почти работает,
    в периоде некоторых дат не хватает чем это связано

  5. Можно ли тоже самое провернуть с регистрами остатков?

    Пытаюсь соединить ОборотыДС и ОстаткиДС, там чтобы остатки рассчитывались на дату оборотов. Но параметр не срабатывает.

    • Теоретически работать должно, но
      а) я не пробовал
      б) Таблица остатков и оборотов чем не угодила?

  6. к сожалению выскакивает такая ощибка:
    Ошибка обработки представления “РегистрСведений.ЦеныНоменклатуры.СрезПоследних:Несоответствие типов (параметр номер “”1″”)”
    <>РегистрСведений.ЦеныНоменклатуры.СрезПоследних(

    • Проверьте внимательно по шагам. Что-то не так сделали. Ну или привидите тексты запросов обоих наборов данных и скриншот вкладки “Связи наборов данных”

  7. Очень интересная статья. Работа с запросом намного упрощается теперь. Единственное замечание: у меня работает запрос только в случае, если все параметры второго запроса указываются в выборке полей. Если идет связка по параметрам Дата и Номенклатура, то нужно писать:
    ВЫБРАТЬ
    &Дата КАК Дата,
    &Номенклатура КАК Номенклатура,
    ЦеныНоменклатурыСрезПоследних.Цена КАК Цена

    Что интересно, если пишу ЦеныНоменклатурыСрезПоследних.Номенклатура, то запрос вообще не выдает ничего, в смысле и основной запрос тоже пустой. У меня другой регистр и другие данные, но вряд ли дело в этом.

  8. Пример с СКД интересен.

    Интересно имеет ли решение задача получения остатков из регистра накоплений на каждую дату с помощью запроса?

  9. Не совсем понятно зачем при использовании СКД в запросе

    ВЫБРАТЬ
    &Дата КАК Дата,
    ЦеныНоменклатурыСрезПоследних.Номенклатура КАК Номенклатура,
    ЦеныНоменклатурыСрезПоследних.Цена КАК Цена
    {ВЫБРАТЬ
    Дата,
    Номенклатура.*,
    Цена}
    ИЗ
    РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
    &Дата,
    Номенклатура = &Номенклатура
    И ТипЦен = &ТипЦен) КАК ЦеныНоменклатурыСрезПоследних
    {ГДЕ
    (&Дата),
    ЦеныНоменклатурыСрезПоследних.Номенклатура.*,
    ЦеныНоменклатурыСрезПоследних.Цена}

    использовать условие

    {ГДЕ
    (&Дата),
    ЦеныНоменклатурыСрезПоследних.Номенклатура.*,
    ЦеныНоменклатурыСрезПоследних.Цена}

    ведь эти же параметры используется у виртуальной таблицы

  10. Добрый день, подскажите пожалуйста по моей задаче. Необходимо получать сумму по курсу валюты на каждый день. У меня в регистре 2 записи по ресурсу ВалютнаяСуммаКонечныйОстатокКт:
    12.01 10000
    12.02 10000
    Необходимо выводить курс валюты на каждый день и на 13.01, 14.01 даже если оборотов не было.
    У меня получилось вывести курс валют на каждый день – но только когда были обороты. Когда я использую группировку по периоду в настройках отчета и ставлю период дополнения “День” – то СКД не выводит курсы за дни, когда оборотов не было. Помогите пжл как вывести сумму по ресурсу ВалютнаяСуммаКонечныйОстатокКт по курсу за те дни когда оборотов не было
    Спасибо

  11. Не получается!
    Повторил все точь в точь, только без суммы – выдает ошибку про несоответствие первого параметра в регистре во втором наборе данных

  12. А у меня такая проблема была, что цена выдавалась самая последняя, то есть параметр Дата не передавался. (Задача: Розница, в отчет по продажам добавить цену по типу цены “Цена Закупки” на дату продажи). Решилась эта проблема также отключением параметра Автозаполнение в запросе-приемнике.

Трекбеки/Пинги

  1. Elvisushastik - 27/oct/2010... http://1cskd.ru/2010/10/srez-poslednix-na-kazhduyu-datu-v-skd/...

Оставить комментарий

RSSКомментарии в RSS

Авторизация

Логин:
Пароль:
Регистрация

Архивы

Закладки

  • Your favorites will be here.