Имя: Пароль:
1C
1С v8
Оцените запрос, оптимален ли
0 saradip
 
10.09.19
14:36
ВЫБРАТЬ
    ПереченьНоменклатуры.Номенклатура КАК Номенклатура,
    СУММА(ПереченьНоменклатуры.Количество) КАК Количество,
    ТоварыНаСкладахОстатки.СуммаОстаток / ТоварыНаСкладахОстатки.КоличествоОстаток КАК СебестоимостьЕдиницы
ПОМЕСТИТЬ СписокНоменклатуры
ИЗ
    Документ.ПеремещениеТоваров.ПереченьНоменклатуры КАК ПереченьНоменклатуры
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(
                &МоментВремени,
                Склад = &СкладОтправитель
                    И Номенклатура В
                        (ВЫБРАТЬ
                            ПеремещениеТоваровПереченьНоменклатуры.Номенклатура КАК Номенклатура
                        ИЗ
                            Документ.ПеремещениеТоваров.ПереченьНоменклатуры КАК ПеремещениеТоваровПереченьНоменклатуры
                        ГДЕ
                            ПеремещениеТоваровПереченьНоменклатуры.Ссылка = &Ссылка)) КАК ТоварыНаСкладахОстатки
        ПО ПереченьНоменклатуры.Номенклатура = ТоварыНаСкладахОстатки.Номенклатура
ГДЕ
    ПереченьНоменклатуры.Ссылка = &Ссылка

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

ИНДЕКСИРОВАТЬ ПО
    Номенклатура
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    СписокНоменклатуры.Номенклатура КАК Номенклатура,
    СписокНоменклатуры.Количество КАК Количество,
    СписокНоменклатуры.СебестоимостьЕдиницы * СписокНоменклатуры.Количество КАК Сумма
ИЗ
    СписокНоменклатуры КАК СписокНоменклатуры
1 piter3
 
10.09.19
14:37
Руками что ли писал?
2 sqr4
 
10.09.19
14:37
не плохой запрос, переписывай
4 piter3
 
10.09.19
14:40
А зачем группировка по ТоварыНаСкладахОстатки.СуммаОстаток / ТоварыНаСкладахОстатки.КоличествоОстаток?
В чем прикол?
А если одна и та же ном-ра в ТЧ дока?
5 saradip
 
10.09.19
14:45
(2) почему? (4) провтыкал, спасибо
6 sqr4
 
10.09.19
14:48
(5) когда делишь на ноль надо проверять. Нахрена индекс по Номенклатуре, если дальше нет соединений? Слыхал что не нужно соединять с виртуальными таблицами регистров?
7 VladZ
 
10.09.19
14:53
Я бы делал так:
1. Получил данные из табличной части документа. => ВТТабличнаяЧасть.
2. Получил остатки по номенклатуре из ВТТабличнаяЧасть по указанному складу с расчетом себестоимости единицы. => ВТОстатки.
3. Собрал итоги: ВТТабличнаяЧасть плюс левое соединение с ВТОстатки плюс расчет Суммы.
8 saradip
 
10.09.19
14:53
(6) А если так?
ВЫБРАТЬ
    ПереченьНоменклатуры.Номенклатура КАК Номенклатура,
    СУММА(ПереченьНоменклатуры.Количество) КАК Количество
ПОМЕСТИТЬ СписокНоменклатуры
ИЗ
    Документ.ПеремещениеТоваров.ПереченьНоменклатуры КАК ПереченьНоменклатуры
ГДЕ
    ПереченьНоменклатуры.Ссылка = &Ссылка

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

ИНДЕКСИРОВАТЬ ПО
    Номенклатура
;

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

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    СписокНоменклатуры.Номенклатура КАК Номенклатура,
    СписокНоменклатуры.Количество КАК Количество,
    СебестоимостьЕдиницы.СебестоимостьЕдицины * СписокНоменклатуры.Количество КАК Сумма
ИЗ
    СписокНоменклатуры КАК СписокНоменклатуры,
    СебестоимостьЕдиницы КАК СебестоимостьЕдиницы
9 saradip
 
10.09.19
14:54
+ связь по номенклатуре
10 saradip
 
10.09.19
14:54
|ВЫБРАТЬ
    |    СписокНоменклатуры.Номенклатура КАК Номенклатура,
    |    СписокНоменклатуры.Количество КАК Количество,
    |    СебестоимостьЕдиницы.СебестоимостьЕдицины * СписокНоменклатуры.Количество КАК Сумма
    |ИЗ
    |    СписокНоменклатуры КАК СписокНоменклатуры
    |        ЛЕВОЕ СОЕДИНЕНИЕ СебестоимостьЕдиницы КАК СебестоимостьЕдиницы
    |        ПО СписокНоменклатуры.Номенклатура = СебестоимостьЕдиницы.Номенклатура";
11 H A D G E H O G s
 
10.09.19
14:54
(8) нет

И Номенклатура В

(выборка из 1-ой ВТ)
12 piter3
 
10.09.19
14:55
Зачем делать вт СписокНоменклатуры если во 2 запросе опять в тч дока лезешь?.Попробуй (7)
13 piter3
 
10.09.19
14:55
Толко не забудь различные что ли в 1 части
14 sqr4
 
10.09.19
14:57
(9) попробуй планы запроса покурить, как раз задачка простая, наглядно должно быть.
15 Конструктор1С
 
10.09.19
15:04
(0) походу ты начинаешь заморачиваться на оптимизации там, где она особо не требуется. Твой запрос не самый оптимальный, но он заведомо и не тянет на большие объемы
16 saradip
 
10.09.19
15:19
(14) ВЫБРАТЬ
    ПереченьНоменклатуры.Номенклатура КАК Номенклатура,
    СУММА(ПереченьНоменклатуры.Количество) КАК Количество
ПОМЕСТИТЬ ВТТабличнаяЧасть
ИЗ
    Документ.ПеремещениеТоваров.ПереченьНоменклатуры КАК ПереченьНоменклатуры
ГДЕ
    ПереченьНоменклатуры.Ссылка = &Ссылка

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

ИНДЕКСИРОВАТЬ ПО
    Номенклатура
;

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

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТТабличнаяЧасть.Номенклатура КАК Номенклатура,
    ВТТабличнаяЧасть.Количество КАК Количество,
    ВТТабличнаяЧасть.Количество * ВТОстатки.СебестоимостьЕдицины КАК Сумма
ИЗ
    ВТТабличнаяЧасть КАК ВТТабличнаяЧасть,
    ВТОстатки КАК ВТОстатки
17 saradip
 
10.09.19
15:19
А если так?
18 saradip
 
10.09.19
15:20
ВОТ:
ВЫБРАТЬ
    ПереченьНоменклатуры.Номенклатура КАК Номенклатура,
    СУММА(ПереченьНоменклатуры.Количество) КАК Количество
ПОМЕСТИТЬ ВТТабличнаяЧасть
ИЗ
    Документ.ПеремещениеТоваров.ПереченьНоменклатуры КАК ПереченьНоменклатуры
ГДЕ
    ПереченьНоменклатуры.Ссылка = &Ссылка

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

ИНДЕКСИРОВАТЬ ПО
    Номенклатура
;

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

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТТабличнаяЧасть.Номенклатура КАК Номенклатура,
    ВТТабличнаяЧасть.Количество КАК Количество,
    ВТТабличнаяЧасть.Количество * ВТОстатки.СебестоимостьЕдицины КАК Сумма
ИЗ
    ВТТабличнаяЧасть КАК ВТТабличнаяЧасть
        ЛЕВОЕ СОЕДИНЕНИЕ ВТОстатки КАК ВТОстатки
        ПО ВТТабличнаяЧасть.Номенклатура = ВТОстатки.Номенклатура
19 hi1C
 
10.09.19
15:21
isnull(ВТОстатки.СебестоимостьЕдицины,0)
20 sqr4
 
10.09.19
15:22
Проверку на нулы еще сделай когда левое соединение, для правой таблицы
21 pasha_d
 
10.09.19
15:28
А вдруг ТоварыНаСкладахОстатки.КоличествоОстаток < 0? ))

ВЫБОР
        КОГДА ТоварыНаСкладахОстатки.КоличествоОстаток = 0
            ТОГДА 0
        ИНАЧЕ ТоварыНаСкладахОстатки.СуммаОстаток / ТоварыНаСкладахОстатки.КоличествоОстаток
    КОНЕЦ КАК СебестоимостьЕдицины
22 saradip
 
10.09.19
15:41
(20) А как так может быть NULL? (21) Спасибо!
23 Вафель
 
10.09.19
15:44
тут вт вообще не нужна
24 saradip
 
10.09.19
15:45
Короче вот что вышло
ВЫБРАТЬ
    ПереченьНоменклатуры.Номенклатура КАК Номенклатура,
    СУММА(ПереченьНоменклатуры.Количество) КАК Количество
ПОМЕСТИТЬ ВТТабличнаяЧасть
ИЗ
    Документ.ПеремещениеТоваров.ПереченьНоменклатуры КАК ПереченьНоменклатуры
ГДЕ
    ПереченьНоменклатуры.Ссылка = &Ссылка

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

ИНДЕКСИРОВАТЬ ПО
    Номенклатура
;

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

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТТабличнаяЧасть.Номенклатура КАК Номенклатура,
    ВТТабличнаяЧасть.Количество КАК Количество,
    ЕСТЬNULL(ВТОстатки.СебестоимостьЕдиницы, 0) * ВТТабличнаяЧасть.Количество КАК Поле1
ИЗ
    ВТТабличнаяЧасть КАК ВТТабличнаяЧасть
        ЛЕВОЕ СОЕДИНЕНИЕ ВТОстатки КАК ВТОстатки
        ПО ВТТабличнаяЧасть.Номенклатура = ВТОстатки.Номенклатура
25 Вафель
 
10.09.19
15:45
ну уж точне индекс по ней не нужен.
сколько в среднем позиций в документе?
26 Вафель
 
10.09.19
15:46
ну и ради 1 соединения смысл индекс делать никакого.
27 saradip
 
10.09.19
15:50
(26) Убрал, вот весь код...



Процедура ОбработкаПроведения(Отказ, Режим)
    
    // 1. Получение запросом данных документа
    
    Запрос = Новый Запрос;
    
    Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
    
    Запрос.Текст =
    
    "ВЫБРАТЬ
    |    ПереченьНоменклатуры.Номенклатура КАК Номенклатура,
    |    СУММА(ПереченьНоменклатуры.Количество) КАК Количество
    |ПОМЕСТИТЬ ВТТабличнаяЧасть
    |ИЗ
    |    Документ.ПеремещениеТоваров.ПереченьНоменклатуры КАК ПереченьНоменклатуры
    |ГДЕ
    |    ПереченьНоменклатуры.Ссылка = &Ссылка
    |
    |СГРУППИРОВАТЬ ПО
    |    ПереченьНоменклатуры.Номенклатура
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    Остатки.Номенклатура КАК Номенклатура,
    |    ВЫБОР
    |        КОГДА Остатки.КоличествоОстаток = 0
    |            ТОГДА 0
    |        ИНАЧЕ Остатки.СуммаОстаток / Остатки.КоличествоОстаток
    |    КОНЕЦ КАК СебестоимостьЕдиницы
    |ПОМЕСТИТЬ ВТОстатки
    |ИЗ
    |    РегистрНакопления.ТоварыНаСкладах.Остатки(
    |            &МоментВремени,
    |            Склад = &СкладОтправитель
    |                И Номенклатура В
    |                    (ВЫБРАТЬ
    |                        ВТТабличнаяЧасть.Номенклатура КАК Номенклатура
    |                    ИЗ
    |                        ВТТабличнаяЧасть КАК ВТТабличнаяЧасть)) КАК Остатки
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    ВТТабличнаяЧасть.Номенклатура КАК Номенклатура,
    |    ВТТабличнаяЧасть.Количество КАК Количество,
    |    ЕСТЬNULL(ВТОстатки.СебестоимостьЕдиницы, 0) * ВТТабличнаяЧасть.Количество КАК Сумма
    |ИЗ
    |    ВТТабличнаяЧасть КАК ВТТабличнаяЧасть
    |        ЛЕВОЕ СОЕДИНЕНИЕ ВТОстатки КАК ВТОстатки
    |        ПО ВТТабличнаяЧасть.Номенклатура = ВТОстатки.Номенклатура";  
    
    Запрос.УстановитьПараметр("Ссылка", Ссылка);
    
    Запрос.УстановитьПараметр("СкладОтправитель", Отправитель);
    
    Запрос.УстановитьПараметр("МоментВремени", МоментВремени());
    
    РезультатЗапроса = Запрос.Выполнить();
    
    // 2. Формирование движений-расход регистра
    
    Движения.ТоварыНаСкладах.Очистить();
    
    Выборка = РезультатЗапроса.Выбрать();
    
    Пока Выборка.Следующий() Цикл
        
        // регистр ОстаткиТоваров Расход
        Движение = Движения.ТоварыНаСкладах.Добавить();
        Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
        Движение.Период = Дата;
        Движение.Склад = Отправитель;
        Движение.Номенклатура = Выборка.Номенклатура;
        Движение.Количество = Выборка.Количество;
        Движение.Сумма = Выборка.Сумма;
        
        // регистр ОстаткиТоваров Приход    
        Движение = Движения.ТоварыНаСкладах.Добавить();
        Движение.ВидДвижения = ВидДвиженияНакопления.Приход;
        Движение.Период = Дата;
        Движение.Склад = Получатель;
        Движение.Номенклатура = Выборка.Номенклатура;
        Движение.Количество = Выборка.Количество;
        Движение.Сумма = Выборка.Сумма;
        
    КонецЦикла;
    
    // 3. Запись движений в БД
    
    Движения.ТоварыНаСкладах.Записывать = Истина;
    Движения.Записать();
    
    // 4. Запрос, получающий отрицательные остатки из регистра
    
    Запрос.Текст =
    "ВЫБРАТЬ
    |    Остатки.Номенклатура КАК Номенклатура,
    |    ПРЕДСТАВЛЕНИЕССЫЛКИ(Остатки.Номенклатура) КАК НоменклатураПредставление,
    |    -Остатки.КоличествоОстаток КАК Дефецит
    |ИЗ
    |    РегистрНакопления.ТоварыНаСкладах.Остатки(
    |            &МоментВремени,
    |            Номенклатура В
    |                (ВЫБРАТЬ
    |                    ВТТабличнаяЧасть.Номенклатура КАК Номенклатура
    |                ИЗ
    |                    ВТТабличнаяЧасть КАК ВТТабличнаяЧасть)) КАК Остатки
    |ГДЕ
    |    Остатки.КоличествоОстаток < 0";
    
    ГраницаКонтроля = Новый Граница(МоментВремени(), ВидГраницы.Включая);
    
    Запрос.УстановитьПараметр("МоментВремени", ГраницаКонтроля);
    
    РезультатЗапроса = Запрос.Выполнить();
    
    // 5. Вывод сообщений о недостатке товаров
    
    Если Не РезультатЗапроса.Пустой() Тогда
        
        Отказ = Истина;
        
        ВыборкаОшибки = РезультатЗапроса.Выбрать();
        
        Пока ВыборкаОшибки.Следующий() Цикл
            
            Сообщение = Новый СообщениеПользователю;
            
            Сообщение.Текст = "Товара " + ВыборкаОшибки.НоменклатураПредставление +
            " недостаточно в количестве " + ВыборкаОшибки.Дефецит + " шт.";
            
            Сообщение.Сообщить();
            
        КонецЦикла;
        
    КонецЕсли;    
    
КонецПроцедуры
28 saradip
 
10.09.19
15:50
Что скажете?
29 Timon1405
 
10.09.19
15:54
скажем что тут это расписано подробнее и лучше чем у вас https://1c.chistov.pro/2013/07/blog-post_25.html
30 H A D G E H O G s
 
10.09.19
15:54
Хрень какая-то
31 saradip
 
10.09.19
15:56
(30) XDD
32 saradip
 
10.09.19
15:57
(29) А что плохого у меня?
33 saradip
 
10.09.19
16:18
Только склад еще указать
    // 4. Запрос, получающий отрицательные остатки из регистра
    
    Запрос.Текст =     
    
    "ВЫБРАТЬ
    |    Остатки.Номенклатура КАК Номенклатура,
    |    ПРЕДСТАВЛЕНИЕССЫЛКИ(Остатки.Номенклатура) КАК НоменклатураПредставление,
    |    -Остатки.КоличествоОстаток КАК Дефецит
    |ИЗ
    |    РегистрНакопления.ТоварыНаСкладах.Остатки(
    |            &МоментВремени,
    |            Склад = &СкладОтправитель
    |                И Номенклатура В
    |                    (ВЫБРАТЬ
    |                        ВТТабличнаяЧасть.Номенклатура КАК Номенклатура
    |                    ИЗ
    |                        ВТТабличнаяЧасть КАК ВТТабличнаяЧасть)) КАК Остатки
    |ГДЕ
    |    Остатки.КоличествоОстаток < 0";
    
    ГраницаКонтроля = Новый Граница(МоментВремени(), ВидГраницы.Включая);
    
    Запрос.УстановитьПараметр("МоментВремени", ГраницаКонтроля);
    
    Запрос.УстановитьПараметр("СкладОтправитель", Отправитель);
34 sqr4
 
10.09.19
16:24
(33) у тя все гуд, изучи ссылку что ребята прислали
35 saradip
 
10.09.19
16:25
(34) Хорошо, спасибо
Выдавать глобальные идеи — это удовольствие; искать сволочные маленькие ошибки — вот настоящая работа. Фредерик Брукс-младший