Получение данных для партионного списания запросом

20.03.14

Разработка - Запросы

Всегда, когда заглядываю в шпаргалки моментально вспоминаю весь алгоритм построения запроса для партионного списания. И я не про запрос, который просто получает остатки из регистра партий товаров, а про запрос, который получает таблицу которую можно просто загрузить в движения, то есть рассчитывает какие партии должны списаться, сколько с партии списать товаров и какая стоимость списания каждой партии в итоге должна быть получена. Последний раз не хорошо получилось перед группой - я сдался и не дописал запрос. Исправляюсь, теперь у меня будет шпаргалка в виде статьи ;) Надеюсь, пригодится не только мне.

Исходная конфигурация

Конфигурация примитивная. два документа с классическим составом и регистр накопления остатков. Партия в регистре - это ссылка на документ “ПриходнаяНакладная”. Остальное, надеюсь, очевидно.

В тестовой конфигурации были проведены “Приходные”, для формирования остатков по партиям.

Примечание

Да, статья исключительно академическая, в реальной эксплуатации сомнительно применение подобного подхода.

Да - нет контроля остатков.

Да - только метод 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С v8.3 Управляемые формы Запросы Система компоновки данных Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

15500 руб.

02.09.2020    184672    1029    403    

967

Обновление 1С Запросы Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 Абонемент ($m)

Данный инструмент помогает анализировать доработанную конфигурацию после обновления на новый релиз и находить «битые» тексты запросов, в которых участвуют несуществующие в новом релизе метаданные.

2 стартмани

06.02.2025    2198    17    XilDen    26    

36

Запросы Программист Платформа 1С v8.3 Запросы 1C:Бухгалтерия Бесплатно (free)

В статье приведена удобная возможность отладки исполняемого запроса динамического списка.

03.12.2024    5731    artemusII    11    

23

Запросы Программист Бесплатно (free)

Увидел cheatsheet по SQL и захотелось нарисовать подобное, но про запросы.

18.10.2024    13135    sergey279    18    

66

Запросы Программист Платформа 1С v8.3 Запросы 1C:Бухгалтерия Бесплатно (free)

Столкнулся с интересной ситуацией, которую хотел бы разобрать, ввиду её неочевидности. Речь пойдёт про использование функции запроса АВТОНОМЕРЗАПИСИ() и проблемы, которые могут возникнуть.

11.10.2024    8217    XilDen    36    

90

СКД Механизмы типовых конфигураций Запросы Программист Платформа 1С v8.3 1С:Зарплата и кадры государственного учреждения 3 1С:Зарплата и Управление Персоналом 3.x Россия Бесплатно (free)

Работая с типовыми отчетами в конфигурациях «Зарплата и управление персоналом, редакция 3», «Зарплата и кадры государственного учреждения, редакция 3» и подобных, в схемах компоновки данных можно встретить конструкции запросов, которые обращаются к некоторым виртуальным таблицам.

20.08.2024    3191    PROSTO-1C    0    

23

Запросы Программист Запросы Бесплатно (free)

Отлаживая взаимодействие с базой данных, мы регулярно сталкиваемся с зависающими или подозрительно долго выполняющимися обращениями, негативно влияющими на производительность. О том, как в PostgreSQL выявить подозрительные запросы, основываясь на доступной о них информации, расскажем в статье.

16.08.2024    10797    user1840182    5    

29
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Pervuy 65 20.03.14 13:43 Сейчас в теме
Хорошая статья!
Хотелось бы конечно увидеть контроль остатков, если делать списание таким методом.
2. GROOVY 2512 20.03.14 13:57 Сейчас в теме
(1) Pervuy, контроль остатков можно сделать соединив первые 2 таблицы и получив итоги без учета партий. Там все элементарно.
Или сгруппировав вот этот результат

Чтойта картинки в комменты не вставляются.
agrustny; Pervuy; +2 Ответить
3. Pervuy 65 20.03.14 14:06 Сейчас в теме
4. glek 119 01.04.14 11:17 Сейчас в теме
5. Artem1405 25 05.07.15 20:52 Сейчас в теме
Павел, спасибо за статью! Скажите не планируется ли у вас урок по партионному учету с характеристиками? Не получается их правильно сгруппировать.
6. SmArtist 101 01.02.18 14:22 Сейчас в теме
Вот спасибо, Павел, классный способ с накопительным итогом. Работает правда медленно. Пригодилось для похожей задачи. Переделал на LIFO.
7. melis 97 06.09.20 05:40 Сейчас в теме
Добрый день
Почему при получении таблицы Остатки не использовать внутренние соединение вместо конструкции "В" с вложенным запросом в параметрах таблица?

мне кажется, что так должно быстрее работать - или я в чем-то ошибаюсь?
8. melis 97 06.09.20 05:42 Сейчас в теме
может я что-то упускаю?
9. monster6666 50 29.04.21 10:39 Сейчас в теме
(8) Если вы будете использовать внутреннее соединение, без параметров таблицы, вы сначала получите виртуальную таблицу ВСЕХ партий (что есть афигенно долго в реальных базах), и потом ее соедините с таблицей товаров документа. Сильно сомневаюсь, что так будет быстрее. Именно поэтому, всегда рекомендуется использовать условия в параметрах виртуальных таблиц.
10. melis 97 04.05.21 02:50 Сейчас в теме
Все таблицы в запросах нужно выбирирать всегда с отборами в параметрах только по нужным данным, если есть такая возможность. В ответах для анализа может потребоваться полный набор, но это отчет
11. user642695_crocus.vladikina 20.04.23 19:25 Сейчас в теме
послушайте ну не будет птички по партиям. и что так правильно?
Оставьте свое сообщение