Имя: Пароль:
1C
 
Количество дней отсутствия товаров на складе УТ 10.3
,
0 Krasotka
 
11.05.22
08:57
Помогите запрос записать, на входе ТЗ с номенклатурой, на выходе ТЗ с номенклатурой и днями отсутствия на складе за все время.
1 Ненавижу 1С
 
гуру
11.05.22
08:59
(0) Подхода два:
1. Вы находите заказчика, договариваетесь и он делает.
2. Вы пишите, что пробовали и что не получилось - здесь подсказывают возможно.
2 Kassern
 
11.05.22
09:21
(0) поищите Остатки на каждый день и попробуйте от этого оттолкнуться
3 slafor
 
11.05.22
09:45
(2) Не думаю, что это подходящий вариант. А если товара утром не было, днем он пришел и днем же ушел - количество на конец дня будет 0. То есть в отчет он попадет, но в реальности он же был!

Тогда уж остатки на каждый день + анализировать, были ли приходы.
4 Kassern
 
11.05.22
09:50
(3) это все зависит от определения ТС "отсутствие товара", может если на конец, или начало дня товара не было, значит отсутствовал и этого достаточно
5 Ryzeman
 
11.05.22
09:51
(3) Простое решение "в лоб" этой проблемы - связать с последними приходами и выбрать последнюю дату из двух.
6 Krasotka
 
11.05.22
09:58
Есть конечная дата, сколько дней до нее не было товара с момента последнего присутствия
7 Ненавижу 1С
 
гуру
11.05.22
09:59
(6) это не совсем то, что вы пишите в (0)
почему меняете условия задачи?
8 Krasotka
 
11.05.22
09:59
(5)
Приходы бывают когда товар есть на складе
9 Krasotka
 
11.05.22
10:00
(7)
Ну вот есть у меня сложности с формулировкой, в 6 более точная
10 sitex
 
naïve
11.05.22
10:01
(0) В чем надобность этого календаря отсутствия товара на складе ?
11 Bigbro
 
11.05.22
10:04
а если товар поступил но по предварительному заказу, он весь сразу в резерв.
то есть поступить то поступил но по факту доступного товара по прежнему ноль.
12 Kassern
 
11.05.22
10:06
(11) Вы усложняете)) Я думаю у ТС гораздо проще ситуация, ей скорее всего нужно получить дату, когда остаток стал нулевым после последнего прихода и посчитать количество дней до конечной даты.
13 Ryzeman
 
11.05.22
10:06
(11) Не надо плодить сущностей. У меня тут написал человек для подобной цели функцию, которая циклично выполняет запрос, так эта хрень ещё и в полях СКД использовалась в трёх отчётах. Таких тормозов я не видел со времён чёрных запросов семёрки в цикле.
14 sitex
 
naïve
11.05.22
10:08
(11) Тогда считать что его нет, раз в резерве. И брать все на конец дня.
15 ptiz
 
11.05.22
10:15
(6) Сначала смотрим то, что сейчас на остатках. По остальным товарам - ищем дату последнего расхода, это и будет последний день.
16 ptiz
 
11.05.22
10:17
Вообще, в (0) и (6) - разные задачи.

Дарю функцию для расчета количества дней товара на остатках (на собеседовании давали такую задачку):

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

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    МАКСИМУМ(ДвиженияДо.Период) КАК ПериодДо,
    Движения.Период КАК Период,
    Движения.Склад КАК Склад,
    Движения.Номенклатура КАК Номенклатура
ПОМЕСТИТЬ ДвиженияДоПериоды
ИЗ
    Движения КАК Движения
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Движения КАК ДвиженияДо
        ПО (ДвиженияДо.Период < Движения.Период)
            И (ДвиженияДо.Склад = Движения.Склад)
            И (ДвиженияДо.Номенклатура = Движения.Номенклатура)

СГРУППИРОВАТЬ ПО
    Движения.Период,
    Движения.Склад,
    Движения.Номенклатура
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    СУММА(ВЫБОР
            КОГДА ДвиженияДоПериодыСКоличеством.Период ЕСТЬ NULL
                ТОГДА ВЫБОР
                        КОГДА Движения.КоличествоКонечныйОстаток > 0
                            ТОГДА 1
                        ИНАЧЕ 0
                    КОНЕЦ
            ИНАЧЕ ВЫБОР
                    КОГДА Движения.КоличествоКонечныйОстаток > 0
                        ТОГДА 1
                    ИНАЧЕ 0
                КОНЕЦ + ВЫБОР
                    КОГДА ДвиженияДоПериодыСКоличеством.КоличествоКонечныйОстаток > 0
                        ТОГДА РАЗНОСТЬДАТ(ДвиженияДоПериодыСКоличеством.Период, Движения.Период, ДЕНЬ) - 1
                    ИНАЧЕ 0
                КОНЕЦ
        КОНЕЦ) КАК КоличествоДнейНаОстатках,
    Движения.Склад КАК Склад,
    Движения.Номенклатура КАК Номенклатура
ИЗ
    Движения КАК Движения
        ЛЕВОЕ СОЕДИНЕНИЕ ДвиженияДоПериоды КАК ДвиженияДоПериоды
        ПО (ДвиженияДоПериоды.Период = Движения.Период)
            И (ДвиженияДоПериоды.Склад = Движения.Склад)
            И (ДвиженияДоПериоды.Номенклатура = Движения.Номенклатура)
        ЛЕВОЕ СОЕДИНЕНИЕ Движения КАК ДвиженияДоПериодыСКоличеством
        ПО (ДвиженияДоПериодыСКоличеством.Период = ДвиженияДоПериоды.ПериодДо)
            И (ДвиженияДоПериодыСКоличеством.Склад = ДвиженияДоПериоды.Склад)
            И (ДвиженияДоПериодыСКоличеством.Номенклатура = ДвиженияДоПериоды.Номенклатура)

СГРУППИРОВАТЬ ПО
    Движения.Склад,
    Движения.Номенклатура

УПОРЯДОЧИТЬ ПО
    Движения.Склад.Наименование,
    Движения.Номенклатура.Наименование
17 Ненавижу 1С
 
гуру
11.05.22
10:30
вот запрос выдаете интервалы наличия

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

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ТЗ.Номенклатура КАК Номенклатура,
    ТЗ.Период КАК Период
ПОМЕСТИТЬ КонцыПериодов
ИЗ
    ТЗ КАК ТЗ
ГДЕ
    (ТЗ.ВНаличииКонечныйОстаток = 0
            ИЛИ ТЗ.Период = НАЧАЛОПЕРИОДА(&КонДата, ДЕНЬ))
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ТЗ.Номенклатура КАК Номенклатура,
    МИНИМУМ(ТЗ.Период) КАК Период
ПОМЕСТИТЬ НачалаПериодов
ИЗ
    ТЗ КАК ТЗ

СГРУППИРОВАТЬ ПО
    ТЗ.Номенклатура

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    ТЗ.Номенклатура,
    МИНИМУМ(ТЗ.Период)
ИЗ
    ТЗ КАК ТЗ
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ КонцыПериодов КАК КонцыПериодов
        ПО ТЗ.Номенклатура = КонцыПериодов.Номенклатура
            И ТЗ.Период > КонцыПериодов.Период

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

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    НачалаПериодов.Номенклатура КАК Номенклатура,
    НачалаПериодов.Период КАК НачПериода,
    МИНИМУМ(КонцыПериодов.Период) КАК КонПериода
ИЗ
    НачалаПериодов КАК НачалаПериодов
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ КонцыПериодов КАК КонцыПериодов
        ПО (НачалаПериодов.Номенклатура = КонцыПериодов.Номенклатура
                И НачалаПериодов.Период < КонцыПериодов.Период)

СГРУППИРОВАТЬ ПО
    НачалаПериодов.Номенклатура,
    НачалаПериодов.Период

если вы решаете задачу (0), то достаточно просуммировать длины периодов и вычесть их из общей длины периода
в случае задачи (6) достаточно найти максимальные концы периодов и найти разность между ними и концом общего периода
18 Krasotka
 
11.05.22
10:49
(17)
Мне консоль запросов пишет "не найдено поле ТоварыНаСкладахОстаткиИОбороты.ВНаличииКонечныйОстаток"
19 Ненавижу 1С
 
гуру
11.05.22
10:50
(18) ну вы немного творчества проявите
у меня например УТ 11.4, но сути это не меняет
просто названия таблиц надо заменить
20 Krasotka
 
11.05.22
11:17
А как вам такой запрос в цикле, вроде работает
ЗАпросОст=новый запрос;
        ЗапросОст.Текст="ВЫБРАТЬ
                        |    ТоварыНаСкладахОстатки.Склад,
                        |    ТоварыНаСкладахОстатки.КоличествоОстаток
                        |ИЗ
                        |    РегистрНакопления.ТоварыНаСкладах.Остатки(
                        |            &период,
                        |            Склад = &склад
                        |                И Номенклатура = &номенклатура) КАК ТоварыНаСкладахОстатки";
        ЗапросОст.УстановитьПараметр("склад",этотобъект.Склад);
        ЗапросОст.УстановитьПараметр("номенклатура",стр.номенклатура);
        ЗапросОст.УстановитьПараметр("период",этотобъект.КонецПериода);
        ИтогОст= ЗАпросОст.Выполнить().Выгрузить();
        ДнейОтсутствия=0;
        Если ИтогОст.Количество()=0 тогда
            ДнейОтсутствия=1;
            Для й=1 по 100 цикл
                ЗАпросОст1=новый запрос;
        ЗапросОст1.Текст="ВЫБРАТЬ
                        |    ТоварыНаСкладахОстатки.Склад,
                        |    ТоварыНаСкладахОстатки.КоличествоОстаток
                        |ИЗ
                        |    РегистрНакопления.ТоварыНаСкладах.Остатки(
                        |            &период,
                        |            Склад = &склад
                        |                И Номенклатура = &номенклатура) КАК ТоварыНаСкладахОстатки";
        ЗапросОст1.УстановитьПараметр("склад",этотобъект.Склад);
        ЗапросОст1.УстановитьПараметр("номенклатура",стр.номенклатура);
        ЗапросОст1.УстановитьПараметр("период",этотобъект.КонецПериода-60*60*24*й);
            ИтогОст1= ЗАпросОст1.Выполнить().Выгрузить();
            Если ИтогОст1.Количество()=0 тогда
                ДнейОтсутствия=ДнейОтсутствия+1;

            Конецесли;    
            Конеццикла;    
        Конецесли;    
        стр.ДниОтсутствия=ДнейОтсутствия;
21 Kassern
 
11.05.22
11:26
(20) "А как вам такой запрос в цикле, вроде работает" - Не оптимальное решение, данную задачу можно решить одним запросом. Запрос в цикле используется в исключительных случаях.
Вот еще Для й=1 по 100 цикл - а почему не по 200? С чего вы решили, что вам 100 хватит? А если товар полтора года без остатка висит?
22 Kassern
 
11.05.22
11:27
Получается решение не верное у вас в общем случае
23 Krasotka
 
11.05.22
11:29
(21)
Юзеры говорят, что 100 хватит, и в пределах этой цифры все за секунду отрабатывает.
24 Kassern
 
11.05.22
11:30
(23) а вы для них это делаете, или для руководства? Юзверам может быть вообще все равно, а через месяц уже и забудут про костыль в 100 дней.
25 Krasotka
 
11.05.22
11:33
(24)
Ну вот пусть потом и вспомнят, будет дополнительная задача
26 Kassern
 
11.05.22
11:39
(25) Классная логика... Когда вас попросят сделать по всей номенклатуре такой анализ, вы сверху еще один цикл забабахаете Справочники.Номенклатура.Выбрать() ?)
А на вопросы, почему так долго отчет открывается, ответите, мол а задачи не было писать оптимально, если хотите, можно дополнительной задачей решить))
27 Kassern
 
11.05.22
11:53
Ладно бы еще правильно считал ваш алгоритм. А теперь сами подумайте какое количество дней вы получите:
Период Товар Приход Расход Остаток
01.04  Ложка 100           100
05.04  Ложка       100     0
20.04  Ложка 50            50
01.05  Ложка       50      0

По вашей логике, этот товар у вас не продавался за 100 дней 25 дней.
А теперь берем ваше ТЗ из (6) которое более точное: "Есть конечная дата, сколько дней до нее не было товара с момента последнего присутствия", в этом случае получается 10 дней (с 1 по 10 мая включительно)
28 Kassern
 
11.05.22
11:55
Или правильные цифры тоже путь вспомнят -будет дополнительная задача?)
29 Krasotka
 
11.05.22
11:58
Вы мне сделайте конечный запрос на 10.3, я пока не понимаю как переделать. Если не сделаете, останется так.
30 Krasotka
 
11.05.22
12:01
(27)
Вот у меня улучшенная версия

//-------------------------------дни отсутствия
        ДнейОтсутствия=0;

            Если стр.КоличествоСвободныйОстаток=0 тогда
                ДнейОтсутствия=1;
                Для й=1 по 100 цикл
                    ЗАпросОст1=новый запрос;
                    ЗапросОст1.Текст="ВЫБРАТЬ
                    |    ТоварыНаСкладахОстатки.Склад,
                    |    ТоварыНаСкладахОстатки.КоличествоОстаток
                    |ИЗ
                    |    РегистрНакопления.ТоварыНаСкладах.Остатки(
                    |            &период,
                    |            Склад = &склад
                    |                И Номенклатура = &номенклатура) КАК ТоварыНаСкладахОстатки";
                    ЗапросОст1.УстановитьПараметр("склад",этотобъект.Склад);
                    ЗапросОст1.УстановитьПараметр("номенклатура",стр.номенклатура);
                    ЗапросОст1.УстановитьПараметр("период",этотобъект.КонецПериода-60*60*24*й);
                    ИтогОст1= ЗАпросОст1.Выполнить().Выгрузить();
                    Если ИтогОст1.Количество()=0 тогда
                        ДнейОтсутствия=ДнейОтсутствия+1;
                    иначе
                        прервать;
                        
                    Конецесли;    
                Конеццикла;    
            Конецесли;                
            стр.ДниОтсутствия=ДнейОтсутствия;
            //-------------------------------дни отсутствия
31 Kassern
 
11.05.22
12:02
(30) Уже лучше) Осталось теперь в один запрос объединить и будет сказка