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

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, и нож не продадим, его вообще в остатках нет. Но это отдельная история…

Оригинал статьи на моем сайте.

С уважением, Павел Чистов.

партионный учет тэта-запрос

См. также

SALE! 20%

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

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

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

13000 10400 руб.

02.09.2020    122251    673    389    

715

Для чего используют конструкцию запроса "ГДЕ ЛОЖЬ" в СКД на примере конфигурации 1С:ERP

Запросы СКД Платформа 1С v8.3 Запросы Система компоновки данных 1С:ERP Управление предприятием 2 Бесплатно (free)

В типовых конфигурациях разработчики компании 1С иногда используют в отчетах, построенных на СКД, такую конструкцию, как "ГДЕ ЛОЖЬ". Такая конструкция говорит о том, что данные в запросе не будут получены совсем. Для чего же нужен тогда запрос?

13.02.2024    5751    KawaNoNeko    23    

23

Набор-объект для СКД по тексту или запросу

Запросы СКД Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Есть список полей в виде текста, или запрос - закидываем в набор СКД.

1 стартмани

31.01.2024    2006    2    Yashazz    0    

29

Запрос 1С copilot

Инструментарий разработчика Запросы Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Пишем на человеческом языке, что нам надо, и получаем текст запроса на языке 1С. Используются большие языковые модели (LLM GPT) от OpenAI или Яндекс на выбор.

5 стартмани

15.01.2024    6296    31    mkalimulin    25    

50

PrintWizard: поддержка представлений ЗУП в конструкторе

Инструментарий разработчика Запросы Платформа 1С v8.3 Бесплатно (free)

Одной из интересных задач, стоящих в процессе разработки, была поддержка механизма представлений в ЗУП. Но не просто возможность исполнения запросов с ними. Основная проблема была в том, чтобы с ними было удобно работать, а именно: создавать, модифицировать и отлаживать. Кратко о том, что в итоге получилось...

14.12.2023    1746    vandalsvq    7    

29

Объектная модель запроса "Схема запроса" 2

Запросы Платформа 1С v8.3 Запросы Конфигурации 1cv8 Бесплатно (free)

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

06.12.2023    5392    user1923546    26    

43

Начните уже использовать хранилище запросов

HighLoad оптимизация Запросы

Очень немногие из тех, кто занимается поддержкой MS SQL, работают с хранилищем запросов. А ведь хранилище запросов – это очень удобный, мощный и, главное, бесплатный инструмент, позволяющий быстро найти и локализовать проблему производительности и потребления ресурсов запросами. В статье расскажем о том, как использовать хранилище запросов в MS SQL и какие плюсы и минусы у него есть.

11.10.2023    16195    skovpin_sa    14    

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

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

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