Получение данных для партионного списания запросом
Всегда, когда заглядываю в шпаргалки моментально вспоминаю весь алгоритм построения запроса для партионного списания. И я не про запрос, который просто получает остатки из регистра партий товаров, а про запрос, который получает таблицу которую можно просто загрузить в движения, то есть рассчитывает какие партии должны списаться, сколько с партии списать товаров и какая стоимость списания каждой партии в итоге должна быть получена.
Последний раз не хорошо получилось перед группой — я сдался и не дописал запрос.
Исправляюсь, теперь у меня будет шпаргалка в виде статьи 😉 Надеюсь пригодится не только мне.
- Описание
- Подробнее
Описание
Исходная конфигурация
Конфигурация примитивная. два документа с классическим составом и регистр накопления остатков. Партия в регистре — это ссылка на документ “ПриходнаяНакладная”. Остальное, надеюсь, очевидно.
В тестовой конфигурации были проведены “Приходные”, для формирования остатков по партиям.
Примечание
Да, статья исключительно академическая, в реальной эксплуатации сомнительно применение подобного подхода.
Да — нет контроля остатков.
Да — только метод FIFO. Если есть вопрос как реализовать это методом LIFO — то повторное прочтение статьи Вам вряд ли поможет, как собственно и сама статья — вряд ли будет для Вас полезной.
Да — все можно свести к 3 запросам в пакете и не плодить кучу временных таблиц. Да — можно, я расписал подробно для пущего понимания.
Поехали
Я буду очень подробно показывать получение данных. Прямо по шагам.
Получаем данные документа который проводится
ВЫБРАТЬ
Товар КАК Товар,
СУММА(Количество) КАК Количество
ПОМЕСТИТЬ ДокТЧ
ИЗ
Документ.РасходнаяНакладная.Товары
ГДЕ
Ссылка = &Ссылка
СГРУППИРОВАТЬ ПО
Товар
ИНДЕКСИРОВАТЬ ПО
ТоварИз документа нам нужно только количество и сам товар. На всякий случай данные сгруппируем и поместим все во временную таблицу.
Получим остатки партий
Далее выберем остатки из регистра с отбором по товарам из таблицы документа.
ВЫБРАТЬ
Товар,
Партия,
Партия.МоментВремени КАК МоментВремени,
КоличествоОстаток,
СтоимостьОстаток
ПОМЕСТИТЬ Остатки
ИЗ
РегистрНакопления.ПартииТоваров.Остатки(
,
Товар В
(ВЫБРАТЬ
ДокТЧ.Товар
ИЗ
ДокТЧ КАК ДокТЧ))
ИНДЕКСИРОВАТЬ ПО
ТоварИтого получили 2 временные таблицы. Соединяя таблицу “Остатки” саму с собой можем получить накопительный итог по партиям.
Соединяем таблицы
ВЫБРАТЬ
*
ИЗ
ДокТЧ КАК ДокТЧ
ЛЕВОЕ СОЕДИНЕНИЕ
Остатки КАК Т1
ПО ДокТЧ.Товар = Т1.Товар
ЛЕВОЕ СОЕДИНЕНИЕ
Остатки КАК Т2
ПО Т1.Товар = Т2.Товар И Т1.МоментВремени > Т2.МоментВремениВ итоге получаем таблицу вида:
В таблице из ДокТЧ мы узнаем сколько списать товаров надо.
В Т1 количество остатка по конкретной партии.
В Т2, после группирования записей будет накопительный итог по партиям.
Выберем только нужные поля:
ВЫБРАТЬ
ДокТЧ.Товар,
ДокТЧ.Количество КАК КоличествоДокумента,
Т1.Партия,
Т1.КоличествоОстаток КАК КоличествоПартии,
ISNULL(Т2.КоличествоОстаток,0) КАК НакопительныйИтог
ИЗ
ДокТЧ КАК ДокТЧ
ЛЕВОЕ СОЕДИНЕНИЕ
Остатки КАК Т1
ПО ДокТЧ.Товар = Т1.Товар
ЛЕВОЕ СОЕДИНЕНИЕ
Остатки КАК Т2
ПО Т1.Товар = Т2.Товар И Т1.МоментВремени > Т2.МоментВремениПри необходимости остаток по стоимости можно получить потом, а можно и в этой же выборке.
Для наглядности поместим все во временную таблицу “Данные” и следующим запросом выберем и сгруппируем данные из нее.
Получаем данные о том, сколько списать нужно с конкретной партии
ВЫБРАТЬ
Товар,
Партия,
МАКСИМУМ(КоличествоДокумента) КАК КоличествоДокумента,
МАКСИМУМ(КоличествоПартии) КАК КоличествоПартии,
СУММА(НакопительныйИтог) КАК НакопительныйИтог
ИЗ
Данные КАК Данные
СГРУППИРОВАТЬ ПО Товар, Партия Данные теперь сгруппированы, товары и партии уникальны.
И опять поместим результат во временную таблицу “Данные2” и очередным запросом рассчитаем сколько необходимо списать с конкретной партии:
ВЫБРАТЬ
*,
КоличествоДокумента - НакопительныйИтог КАК ОсталосьСписать
ИЗ
Данные2 КАК ДанныеИ последняя итерация: получим в условии сколько нужно списать с конкретной партии (ага, опять с временной таблицей):
ВЫБРАТЬ
*,
ВЫБОР КОГДА ОсталосьСписать < КоличествоПартии ТОГДА ОсталосьСписать ИНАЧЕ КоличествоПартии КОНЕЦ КАК Списать
ИЗ
Данные3 КАК Данные
ГДЕ
НакопительныйИтог < КоличествоДокументаДополнительное условие уберет “лишние” партии, списывать которые не нужно.
Осталось убрать столбцы, которые нам не нужны и получим таблицу для партионного списания.
ВЫБРАТЬ
Товар КАК Товар,
СУММА(Количество) КАК Количество
ПОМЕСТИТЬ ДокТЧ
ИЗ
Документ.РасходнаяНакладная.Товары
ГДЕ
Ссылка = &Ссылка
СГРУППИРОВАТЬ ПО
Товар
ИНДЕКСИРОВАТЬ ПО
Товар
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Товар КАК Товар,
Партия,
Партия.МоментВремени КАК МоментВремени,
КоличествоОстаток,
СтоимостьОстаток
ПОМЕСТИТЬ Остатки
ИЗ
РегистрНакопления.ПартииТоваров.Остатки(
,
Товар В
(ВЫБРАТЬ
ДокТЧ.Товар
ИЗ
ДокТЧ КАК ДокТЧ)) КАК ПартииТоваровОстатки
ИНДЕКСИРОВАТЬ ПО
Товар
;
ВЫБРАТЬ
*
ИЗ
ДокТЧ КАК ДокТЧ
ЛЕВОЕ СОЕДИНЕНИЕ
Остатки КАК Т1
ПО ДокТЧ.Товар = Т1.Товар
ЛЕВОЕ СОЕДИНЕНИЕ
Остатки КАК Т2
ПО Т1.Товар = Т2.Товар И Т1.МоментВремени > Т2.МоментВремени
;
ВЫБРАТЬ
ДокТЧ.Товар,
ДокТЧ.Количество КАК КоличествоДокумента,
Т1.Партия,
Т1.КоличествоОстаток КАК КоличествоПартии,
ISNULL(Т2.КоличествоОстаток,0) КАК НакопительныйИтог
ПОМЕСТИТЬ Данные
ИЗ
ДокТЧ КАК ДокТЧ
ЛЕВОЕ СОЕДИНЕНИЕ
Остатки КАК Т1
ПО ДокТЧ.Товар = Т1.Товар
ЛЕВОЕ СОЕДИНЕНИЕ
Остатки КАК Т2
ПО Т1.Товар = Т2.Товар И Т1.МоментВремени > Т2.МоментВремени
;
ВЫБРАТЬ
Товар,
Партия,
МАКСИМУМ(КоличествоДокумента) КАК КоличествоДокумента,
МАКСИМУМ(КоличествоПартии) КАК КоличествоПартии,
СУММА(НакопительныйИтог) КАК НакопительныйИтог
ПОМЕСТИТЬ Данные2
ИЗ
Данные КАК Данные
СГРУППИРОВАТЬ ПО Товар, Партия
;
ВЫБРАТЬ
*,
КоличествоДокумента - НакопительныйИтог КАК ОсталосьСписать
ПОМЕСТИТЬ Данные3
ИЗ
Данные2 КАК Данные
;
ВЫБРАТЬ
Товар, Партия,
ВЫБОР КОГДА ОсталосьСписать < КоличествоПартии ТОГДА ОсталосьСписать ИНАЧЕ КоличествоПартии КОНЕЦ КАК Списать
ИЗ
Данные3 КАК Данные
ГДЕ
НакопительныйИтог < КоличествоДокументаВот и все.
В приведенном примере, естественно, мы не сможем продать ложки, их мало, нужно 100, и нож не продадим, его вообще в остатках нет. Но это отдельная история…
Оригинал статьи на моем сайте.
С уважением, Павел Чистов.
Крупнейшая региональная сеть среди 1С:Франчайзи
// //

