Вход | Регистрация


1С:Предприятие :: 1С:Предприятие 8 общая

запрос из регистра, цены последних 5 поступлений по каждой позиции

запрос из регистра, цены последних 5 поступлений по каждой позиции
Я
   MrZLO
 
22.10.18 - 07:20
Здравствуйте!

Есть запрос, как тут сделать так, чтобы добавить условие, только 3 последних Регистратора (у нас всегда это Поступление), а не выводить данные по всем поступлениям, которые были...

ВЫБРАТЬ
    Закупки.Количество,
    Закупки.Стоимость,
    Закупки.Номенклатура КАК Номенклатура1,
    Закупки.Регистратор КАК Регистратор
ИЗ
    РегистрНакопления.Закупки КАК Закупки
ГДЕ
    Закупки.Организация.Ссылка = &Организация
    И Закупки.Номенклатура.Родитель = &Родитель

УПОРЯДОЧИТЬ ПО
    Регистратор УБЫВ
 
 
   MrZLO
 
1 - 22.10.18 - 07:21
на каждую номенклатуру 3 последних поступления... (можно и 5 :))
   shadow_sw
 
2 - 22.10.18 - 07:24
выбрать первые 3
упорядочить по убыванию
   Случайный прохожий
 
3 - 22.10.18 - 07:24
(2) Не так все легко :)
   Случайный прохожий
 
4 - 22.10.18 - 07:26
Делаешь запрос еще на одну таблицу по этому РС с тремя последними регистраторами (выбрать первые 3), но без товаров и потом соединаешь его левым соединением с твоим запросом
   Альбатрос
 
5 - 22.10.18 - 07:28
(4) А если там не окажется поступлений по некоторым позициям? Имхо проще сделать обработкой результата запроса по всем поступлениям.
   Случайный прохожий
 
6 - 22.10.18 - 07:30
(5) Всмысле "не окажется"? :)
   Случайный прохожий
 
7 - 22.10.18 - 07:30
(5) Можно, но не оптимально так делать
   MrZLO
 
8 - 22.10.18 - 07:31
(5) позиции без поступлений меня не интересует, они там все с поступлениями
   Альбатрос
 
9 - 22.10.18 - 07:31
(6) У тебя в группе "товары" 5 позиций, последние три поступления было только по двум из них. По остальным трем поступления далеко не последние.
   Случайный прохожий
 
10 - 22.10.18 - 07:35
(9) я один не понимаю логику этого человека? :)
 
 Рекламное место пустует
   MrZLO
 
11 - 22.10.18 - 07:36
(9) все правильно... как раз и надо 3 последних поступления для каждой позиции, а не 3 последних вообще :)
   Случайный прохожий
 
12 - 22.10.18 - 07:37
(11) а все, я кажется условие задачи не так прочитал :)
   MrZLO
 
13 - 22.10.18 - 07:45
для каждой позиции взять цену (стоимость/кол-во) для 3 её последних поступлений...
   Альбатрос
 
14 - 22.10.18 - 07:47
(11) Если прям хочется запросом, то навскидку что-то типа этого:
1. Сначала получаешь таблицу номенклатуры.
2. потом получаешь таблицу поступлений в соединении с номенклатурой и выборкой поля период.
3. Выбираешь по МАКС(период) поступления для номенклатуры как поступление_1
4. повторяешь 2-3 но с условием что поступление <> поступление_1
   MrZLO
 
15 - 22.10.18 - 11:26
(14) как все замудренно...
   MrZLO
 
16 - 22.10.18 - 12:03
пока так сделал...

Функция ПолучитьСебестоимостьНоменклатуры(Номенклатура, Дата = неопределено) Экспорт 
    Если Не ЗначениеЗаполнено(Номенклатура) Тогда 
        Возврат 0;
    КонецЕсли;    
    
    Дата = ?(Дата = Неопределено, ТекущаяДата(), Дата);
    
    Запрос = Новый Запрос;
    
    Запрос.Текст = "ВЫБРАТЬ
                   |    ВЫБОР
                   |        КОГДА ВложенныйЗапрос.КоличествоОборот = 0
                   |            ТОГДА 0
                   |        ИНАЧЕ ВложенныйЗапрос.СтоимостьОборот / ВложенныйЗапрос.КоличествоОборот
                   |    КОНЕЦ КАК Себестоимость
                   |ИЗ
                   |    (ВЫБРАТЬ
                   |        СУММА(ВложенныйЗапрос.СтоимостьОборот) КАК СтоимостьОборот,
                   |        СУММА(ВложенныйЗапрос.КоличествоОборот) КАК КоличествоОборот
                   |    ИЗ
                   |        (ВЫБРАТЬ ПЕРВЫЕ 5
                   |            ЗакупкиОбороты.Номенклатура КАК Номенклатура,
                   |            ЗакупкиОбороты.КоличествоОборот КАК КоличествоОборот,
                   |            ЗакупкиОбороты.СтоимостьОборот КАК СтоимостьОборот,
                   |            ЗакупкиОбороты.ДокументЗакупки.Дата КАК ДокументЗакупкиДата
                   |        ИЗ
                   |            РегистрНакопления.Закупки.Обороты(
                   |                    ,
                   |                    &Дата,                   
                   |                    ,
                   |                    Номенклатура = &Номенклатура
                   |                        И Организация = &Организация) КАК ЗакупкиОбороты
                   |        
                   |        УПОРЯДОЧИТЬ ПО
                   |            ДокументЗакупкиДата УБЫВ) КАК ВложенныйЗапрос) КАК ВложенныйЗапрос";
                
    Запрос.Параметры.Вставить("Дата", Дата);                
    Запрос.Параметры.Вставить("Номенклатура", Номенклатура);
    Запрос.Параметры.Вставить("Организация", Справочники.Организации.НайтиПоКоду("000000001"));
    
    РЗ = Запрос.Выполнить();
    
    Если рз.Пустой() Тогда 
        Возврат 0;
    КонецЕсли;    
    
    Выборка = рз.Выбрать();
    Выборка.Следующий();
    
    Возврат Выборка.Себестоимость;

КонецФункции

Беру запросом весь справочник, далее для каждой строки в коде обращаюсь через функцию, но все же медленно работает...
   MrZLO
 
17 - 22.10.18 - 12:14
Если кол-во поступлений не ограничивать, то все работает очень быстро одним запросом...
   Buster007
 
18 - 22.10.18 - 12:16
где
Т.Регистратор В (
ВЫБРАТЬ ПЕРВЫЕ 3
...)
   MrZLO
 
19 - 22.10.18 - 12:19
да, хоть 3, хоть 5 уже не важно, мне главное задать ограничение в поступлениях для позиций
   MrZLO
 
20 - 22.10.18 - 13:23
народ, а оператор HAVING, по-местному "ИМЕЮЩИЕ" может тут как-то пригодиться, т.е. в запрос добавлю поле с порядковым номером поступления данной позиции и условие в ИМЕЮЩИЕ это поле не больше 3, а...?
   Alexandr_U1982
 
21 - 22.10.18 - 14:12
(20) Как вариант:


Запрос = Новый Запрос;
Запрос.Текст =
    "ВЫБРАТЬ
    |    ЗакупкиОбороты.Номенклатура КАК Номенклатура,
    |    ЗакупкиОбороты.КоличествоОборот КАК КоличествоОборот,
    |    ЗакупкиОбороты.СтоимостьОборот КАК СтоимостьОборот,
    |    ЗакупкиОбороты.ДокументЗакупки.Дата КАК ДокументЗакупкиДата
    |ИЗ
    |    РегистрНакопления.Закупки.Обороты(
    |        ,
    |        &Дата,                   
    |        ,
    |        Номенклатура В (&Номенклатура)
    |            И Организация = &Организация) КАК ЗакупкиОбороты
    |
    |УПОРЯДОЧИТЬ ПО
    |    Номенклатура,
    |    ДокументЗакупкиДата УБЫВ
    |ИТОГИ ПО
    |    Номенклатура";
        
ВыборкаНоменклатуры = Запрос.Выполнить().Выбрать(ОбходРезультатЗапроса.ПоГруппировкам);
Пока ВыборкаНоменклатуры.Следующий() Цикл
    
    Счетчик = 0;
    Выборка = ВыборкаНоменклатуры.Выбрать();
    
    Пока Выборка.Следующий() Цикл
        
        ...
        
        Счетчик = Счетчик + 1;
        Если Счетчик = 5 Тогда
            Прервать;
        КонецЕсли;
        
    КонецЦикла;
    
КонецЦикла
   MrZLO
 
22 - 23.10.18 - 07:01
(21) спасибо
   Фрэнки
 
23 - 23.10.18 - 08:26
(22) но ты же видишь вероятные недостатки этого решения? Оно должно быть _обязательно_ в контексте Сервера, но не Клиента.
Если предполагается, что это решается в базе с вкл УФ, то скорей всего, что нужная процедура с выборкой данных окажется на сервере, а вот если это Оф, то потенциально возникнут проблемы с передачей данных на толстого клиента и размером памяти толстого клиента.

Но сам код весьма удачный и легко отлаживается.

Есть еще версия решения такой же задачи на СКД
Двумя наборами данных с подачей на второй набор параметром данных из первого набора. Получится запрос в запросе, но это будет внутри СКД и будет исполнено кодом платформе в контексте сервера, даже если этот СКД будет запускаться в толстом клиенте.
   Serg_1960
 
24 - 23.10.18 - 08:52
Не в тему, но... по теме. Ну, почти :)
как выбрать 1 документ поступления по каждой номенклатуре
Используйте МАКСИМУМ() вместо постобработки.
   Фрэнки
 
25 - 23.10.18 - 09:02
(24) есть мнение, что можно еще как-то сделать функцией с таблицей значений на СКД во вкладке Ресурсы. Но не совсем понял как именно... таблицу значений там использовать при выводе ресурса можно. Готового примера такого не видел, поэтому не могу четко себе представить, как оно будет работать


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Рекламное место пустует