Добрый день, коллеги!
Шпаргалка запроса остатки партий по LIFO / FIFO и нарастающий итог LIFO / FIFO
Предисловие
Поставили задачу - разработать отчёт с необходимостью отразить остатки на складах в разрезе приобретения товаров по LIFO. Данные необходимо вывести в кросс-таблицу в разрезе полугодий. Для решения хотел изначально применить функцию СКД «ВычислитьВыражение», которую где-то на просторах рекомендовал использовать Павел Чистов. Спасибо Дмитрию Иванову, который хорошо описал как пользоваться данной функцией //infostart.ru/public/1101676/. Но не взлетело, кросс-таблица разрушила работу функции. С обычной группировкой всё отлично работало.
Фактически, хоть партионный учёт не ведётся, но данные получаются схожим образом, по этому гугл привел меня опять к ранее упомянутому Павлу Чистову и его публикации //infostart.ru/public/266377/ отлично, попутно прочитал статью опять же ранее упомянутого Дмитрия Иванова //infostart.ru/public/1132420/ и пошёл писать запрос, откинув язык выражений и функцию «ВычислитьВыражение».
Запрос – Остатки по LIFO
// Получаем таблицу номенклатуры по которой есть остатки
ВЫБРАТЬ
СебестоимостьТоваровОстатки.АналитикаУчетаНоменклатуры.Номенклатура КАК Номенклатура,
СУММА(СебестоимостьТоваровОстатки.КоличествоОстаток) КАК КоличествоОстаток
ПОМЕСТИТЬ врОстатки
ИЗ
РегистрНакопления.СебестоимостьТоваров.Остатки(&ДатаОстатков, ) КАК СебестоимостьТоваровОстатки
СГРУППИРОВАТЬ ПО
СебестоимостьТоваровОстатки.АналитикаУчетаНоменклатуры.Номенклатура
;
////////////////////////////////////////////////////////////////////////////////
// Получаем таблицу с оборотами в разрезе регистратора
ВЫБРАТЬ
СебестоимостьТоваровОбороты.АналитикаУчетаНоменклатуры.Номенклатура КАК Номенклатура,
СебестоимостьТоваровОбороты.Регистратор КАК Регистратор,
СебестоимостьТоваровОбороты.Регистратор.МоментВремени КАК РегистраторМоментВремени,
СебестоимостьТоваровОбороты.Период КАК Период,
СУММА(СебестоимостьТоваровОбороты.КоличествоОборот) КАК КоличествоОборот
ПОМЕСТИТЬ врОборотРегистратор
ИЗ
РегистрНакопления.СебестоимостьТоваров.Обороты(
,
&ДатаОстатков,
Регистратор,
АналитикаУчетаНоменклатуры.Номенклатура В
(ВЫБРАТЬ
врОстатки.Номенклатура
ИЗ
врОстатки КАК врОстатки)) КАК СебестоимостьТоваровОбороты
ГДЕ
(СебестоимостьТоваровОбороты.Регистратор ССЫЛКА Документ.ПриобретениеТоваровУслуг
ИЛИ СебестоимостьТоваровОбороты.Регистратор ССЫЛКА Документ.ВводОстатков)
СГРУППИРОВАТЬ ПО
СебестоимостьТоваровОбороты.АналитикаУчетаНоменклатуры.Номенклатура,
СебестоимостьТоваровОбороты.Регистратор,
СебестоимостьТоваровОбороты.Регистратор.МоментВремени,
СебестоимостьТоваровОбороты.Период
;
////////////////////////////////////////////////////////////////////////////////
// Из-за специфики, убираем все строчки с минусами
ВЫБРАТЬ
врОборотРегистратор.Номенклатура КАК Номенклатура,
врОборотРегистратор.Регистратор КАК Регистратор,
врОборотРегистратор.РегистраторМоментВремени КАК РегистраторМоментВремени,
врОборотРегистратор.Период КАК Период,
врОборотРегистратор.КоличествоОборот КАК КоличествоОборот
ПОМЕСТИТЬ врОборотРегистраторБезМинусов
ИЗ
врОборотРегистратор КАК врОборотРегистратор
ГДЕ
врОборотРегистратор.КоличествоОборот > 0
;
////////////////////////////////////////////////////////////////////////////////
// Классика. Первая важная выборка - Нарастающий итог
// Объединяем одну таблицу с оборотом по номенклатуре и моменту времени саму с собой
ВЫБРАТЬ
Документы.Номенклатура КАК Номенклатура,
Документы.Регистратор КАК Регистратор,
Документы.Период КАК Период,
СУММА(ЕСТЬNULL(Движения.КоличествоОборот, 0)) КАК НарастающийИтог,
МАКСИМУМ(Документы.КоличествоОборот) КАК КоличествоРегистратор
ПОМЕСТИТЬ врОстаткиНарастающийИтог
ИЗ
врОборотРегистраторБезМинусов КАК Документы
ЛЕВОЕ СОЕДИНЕНИЕ врОборотРегистраторБезМинусов КАК Движения
ПО Документы.Номенклатура = Движения.Номенклатура
И Документы.РегистраторМоментВремени > Движения.РегистраторМоментВремени
СГРУППИРОВАТЬ ПО
Документы.Номенклатура,
Документы.Регистратор,
Документы.Период
;
////////////////////////////////////////////////////////////////////////////////
// Вторая важная выборка - Формируем таблицу с остатками по партиям
ВЫБРАТЬ
врОстаткиНарастающийИтог.Номенклатура КАК Номенклатура,
врОстаткиНарастающийИтог.Регистратор КАК Регистратор,
врОстаткиНарастающийИтог.Период КАК Период,
врОстаткиНарастающийИтог.НарастающийИтог КАК НарастающийИтог,
врОстатки.КоличествоОстаток КАК ИтогоОстаток,
ВЫБОР
КОГДА врОстаткиНарастающийИтог.НарастающийИтог < врОстатки.КоличествоОстаток
ТОГДА ВЫБОР
КОГДА врОстаткиНарастающийИтог.КоличествоРегистратор > врОстатки.КоличествоОстаток - врОстаткиНарастающийИтог.НарастающийИтог
ТОГДА врОстатки.КоличествоОстаток - врОстаткиНарастающийИтог.НарастающийИтог
ИНАЧЕ врОстаткиНарастающийИтог.КоличествоРегистратор
КОНЕЦ
ИНАЧЕ 0
КОНЕЦ КАК КоличествоОстатокПартии,
НАЧАЛОПЕРИОДА(врОстаткиНарастающийИтог.Период, ПОЛУГОДИЕ) КАК ПериодПолугодие,
врОстаткиНарастающийИтог.КоличествоРегистратор КАК КоличествоРегистратор
ПОМЕСТИТЬ врОстаткиПартий
ИЗ
врОстаткиНарастающийИтог КАК врОстаткиНарастающийИтог
ЛЕВОЕ СОЕДИНЕНИЕ врОстатки КАК врОстатки
ПО (врОстатки.Номенклатура = врОстаткиНарастающийИтог.Номенклатура)
;
////////////////////////////////////////////////////////////////////////////////
// В конечной выборке исключаем строки с пустыми остатками по партиям - ФИНИШ
ВЫБРАТЬ
врОстаткиПартий.Номенклатура КАК Номенклатура,
врОстаткиПартий.Регистратор КАК Регистратор,
врОстаткиПартий.Период КАК Период,
врОстаткиПартий.ИтогоОстаток КАК ИтогоОстаток,
врОстаткиПартий.НарастающийИтог КАК НарастающийИтог,
врОстаткиПартий.КоличествоРегистратор КАК КоличествоРегистратор,
врОстаткиПартий.КоличествоОстатокПартии КАК КоличествоОстатокПартии,
врОстаткиПартий.ПериодПолугодие КАК ПериодПолугодие
ИЗ
врОстаткиПартий КАК врОстаткиПартий
ГДЕ
врОстаткиПартий.КоличествоОстатокПартии > 0
УПОРЯДОЧИТЬ ПО
Номенклатура,
Период
Запрос – Остатки по FIFO
Достаточно поменять знак равенства и поменять упорядочивание, и мы получаем остатки по партиям FIFO.
ВЫБРАТЬ
СебестоимостьТоваровОстатки.АналитикаУчетаНоменклатуры.Номенклатура КАК Номенклатура,
СУММА(СебестоимостьТоваровОстатки.КоличествоОстаток) КАК КоличествоОстаток
ПОМЕСТИТЬ врОстатки
ИЗ
РегистрНакопления.СебестоимостьТоваров.Остатки(&ДатаОстатков, ) КАК СебестоимостьТоваровОстатки
СГРУППИРОВАТЬ ПО
СебестоимостьТоваровОстатки.АналитикаУчетаНоменклатуры.Номенклатура
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
СебестоимостьТоваровОбороты.АналитикаУчетаНоменклатуры.Номенклатура КАК Номенклатура,
СебестоимостьТоваровОбороты.Регистратор КАК Регистратор,
СебестоимостьТоваровОбороты.Регистратор.МоментВремени КАК РегистраторМоментВремени,
СебестоимостьТоваровОбороты.Период КАК Период,
СУММА(СебестоимостьТоваровОбороты.КоличествоОборот) КАК КоличествоОборот
ПОМЕСТИТЬ врОборотРегистратор
ИЗ
РегистрНакопления.СебестоимостьТоваров.Обороты(
,
&ДатаОстатков,
Регистратор,
АналитикаУчетаНоменклатуры.Номенклатура В
(ВЫБРАТЬ
врОстатки.Номенклатура
ИЗ
врОстатки КАК врОстатки)) КАК СебестоимостьТоваровОбороты
ГДЕ
(СебестоимостьТоваровОбороты.Регистратор ССЫЛКА Документ.ПриобретениеТоваровУслуг
ИЛИ СебестоимостьТоваровОбороты.Регистратор ССЫЛКА Документ.ВводОстатков)
СГРУППИРОВАТЬ ПО
СебестоимостьТоваровОбороты.АналитикаУчетаНоменклатуры.Номенклатура,
СебестоимостьТоваровОбороты.Регистратор,
СебестоимостьТоваровОбороты.Регистратор.МоментВремени,
СебестоимостьТоваровОбороты.Период
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
врОборотРегистратор.Номенклатура КАК Номенклатура,
врОборотРегистратор.Регистратор КАК Регистратор,
врОборотРегистратор.РегистраторМоментВремени КАК РегистраторМоментВремени,
врОборотРегистратор.Период КАК Период,
врОборотРегистратор.КоличествоОборот КАК КоличествоОборот
ПОМЕСТИТЬ врОборотРегистраторБезМинусов
ИЗ
врОборотРегистратор КАК врОборотРегистратор
ГДЕ
врОборотРегистратор.КоличествоОборот > 0
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Документы.Номенклатура КАК Номенклатура,
Документы.Регистратор КАК Регистратор,
Документы.Период КАК Период,
СУММА(ЕСТЬNULL(Движения.КоличествоОборот, 0)) КАК НарастающийИтог,
МАКСИМУМ(Документы.КоличествоОборот) КАК КоличествоРегистратор
ПОМЕСТИТЬ врОстаткиНарастающийИтог
ИЗ
врОборотРегистраторБезМинусов КАК Документы
ЛЕВОЕ СОЕДИНЕНИЕ врОборотРегистраторБезМинусов КАК Движения
ПО Документы.Номенклатура = Движения.Номенклатура
//Об этом знаке равенства шла речь
И Документы.РегистраторМоментВремени < Движения.РегистраторМоментВремени
СГРУППИРОВАТЬ ПО
Документы.Номенклатура,
Документы.Регистратор,
Документы.Период
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
врОстаткиНарастающийИтог.Номенклатура КАК Номенклатура,
врОстаткиНарастающийИтог.Регистратор КАК Регистратор,
врОстаткиНарастающийИтог.Период КАК Период,
врОстаткиНарастающийИтог.НарастающийИтог КАК НарастающийИтог,
врОстатки.КоличествоОстаток КАК ИтогоОстаток,
ВЫБОР
КОГДА врОстаткиНарастающийИтог.НарастающийИтог < врОстатки.КоличествоОстаток
ТОГДА ВЫБОР
КОГДА врОстаткиНарастающийИтог.КоличествоРегистратор > врОстатки.КоличествоОстаток - врОстаткиНарастающийИтог.НарастающийИтог
ТОГДА врОстатки.КоличествоОстаток - врОстаткиНарастающийИтог.НарастающийИтог
ИНАЧЕ врОстаткиНарастающийИтог.КоличествоРегистратор
КОНЕЦ
ИНАЧЕ 0
КОНЕЦ КАК КоличествоОстатокПартии,
НАЧАЛОПЕРИОДА(врОстаткиНарастающийИтог.Период, ПОЛУГОДИЕ) КАК ПериодПолугодие,
врОстаткиНарастающийИтог.КоличествоРегистратор КАК КоличествоРегистратор
ПОМЕСТИТЬ врОстаткиПартий
ИЗ
врОстаткиНарастающийИтог КАК врОстаткиНарастающийИтог
ЛЕВОЕ СОЕДИНЕНИЕ врОстатки КАК врОстатки
ПО (врОстатки.Номенклатура = врОстаткиНарастающийИтог.Номенклатура)
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
врОстаткиПартий.Номенклатура КАК Номенклатура,
врОстаткиПартий.Регистратор КАК Регистратор,
врОстаткиПартий.Период КАК Период,
врОстаткиПартий.ИтогоОстаток КАК ИтогоОстаток,
врОстаткиПартий.НарастающийИтог КАК НарастающийИтог,
врОстаткиПартий.КоличествоРегистратор КАК КоличествоРегистратор,
врОстаткиПартий.КоличествоОстатокПартии КАК КоличествоОстатокПартии,
врОстаткиПартий.ПериодПолугодие КАК ПериодПолугодие
ИЗ
врОстаткиПартий КАК врОстаткиПартий
ГДЕ
врОстаткиПартий.КоличествоОстатокПартии > 0
УПОРЯДОЧИТЬ ПО
Номенклатура,
//Данную сортировку изменил
Период УБЫВ
Послесловие
Запросы тестировал на 1С:ERP 2.4.8.92, платформа 8.3.12.1714
Вариант использования запроса остатки по FIFO в отчёте с разрезом по полугодиям:
Всем удачного коддинга!