Форум 1С
Программистам, бухгалтерам, администраторам, пользователям
Задай вопрос - получи решение проблемы
26 июн 2024, 16:15

Как ускорить и оптимизировать проверку остатков

Автор Erkhan, 30 янв 2023, 09:17

0 Пользователей и 1 гость просматривают эту тему.

Erkhan

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

Пытаюсь в запросе произвести проверку остатков, дальше не могу ввести сообщения об ошибке

LexaK

Erkhan, самая главная "оптимизация" уберите из цикла Запрос,
вставьте получение Лимитов в основной!
да и его тоже сначала протестируйте (исправьте ошибки) в консоли запросов.

и еще, в основном запросе, в виртуальной таблице Остатки(, "Условие отбора") рекомендуют задавать условия отбора,
значительно повышает производительность (на маленьких, учебных базах, это не заметно)
но подход, навык писания таких запросов должен формироваться с учетом таких оптимизаций (и многих других).
если помогло нажмите: Спасибо!

Erkhan

LexaK, возможно ли условие которые выполняется в если добавить в запрос?

LexaK

Цитата: Erkhan от 30 янв 2023, 10:08LexaK, возможно ли условие которые выполняется в если добавить в запрос?
да, конечно
если помогло нажмите: Спасибо!

Erkhan

LexaK, можно еще один вопрос?
Запрос.Текст = "ВЫБРАТЬ
                  |   Товары.Номенклатура КАК Номенклатура,
                  |   Товары.Количество КАК Количество,
                  |   Остатки.КоличествоОстаток КАК Остаток,
                  |   Лимиты.Лимит КАК Лимит
                  |ИЗ
                  |   (ВЫБРАТЬ
                  |      Товары.Номенклатура КАК Номенклатура,
                  |      СУММА(Товары.Количество) КАК Количество
                  |   ИЗ
                  |      Документ.Реализация.Товары КАК Товары
                  |   ГДЕ
                  |      Товары.Ссылка = &ДокументСсылка
                  |   
                  |   СГРУППИРОВАТЬ ПО
                  |      Товары.Номенклатура) КАК Товары
                  |      ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(, ) КАК Остатки
                  |      ПО (Остатки.Номенклатура = Товары.Номенклатура)
                  |      ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Лимиты КАК Лимиты
                  |      ПО Товары.Номенклатура = Лимиты.Номенклатура
                  |ГДЕ
                  |   Остатки.Склад = &Склад
                  |   И Лимиты.Лимит = &Лимит > Остатки.КоличествоОстаток - Товары.Количество";


Здесь условие которое выполнялось в если добавил в сам запрос! Теперь я не знаю как мне вывести сообщения об ошибке пользователю

Максим75

Erkhan, ну первое - запрос в цикле, категорически запрещен.
второе: таблица виртуальных остатков, для оптимизации необходимо сразу накладывать отборы, в данном случае по товарам из накладной, т.е. в условии прописать что-то такое:
Товар в (Выбрать ВТ.Товар из ВТ как ВТ), где ВТ - временная таблица с товарами из накладной, Товар - измерение регистра (может называть ТМЦ или еще как-то).
Если этот запрос реализуется в процедуре проведения документа, то там есть еще одна заморочка, которую активно продвигает сама 1С.

Afinogen

Лимиты периодический регистр?

Erkhan


LexaK

Erkhan, посмотрите, попробуйте этот код

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


    ...
    ВыборкаОстатков = Запрос.Выполнить().Выбрать();
    Пока ВыборкаОстатков.Следующий() Цикл   
         Сообщить ("Превышен лимит по товару: " + ВыборкаОстатков.Номенклатура
         + ", Кол/Ост/Лим: " + ВыборкаОстатков.Количество 
         + "," + ВыборкаОстатков.Остаток
         + "," + ВыборкаОстатков.Лимит
         );  //вывод справочной информации
    КонецЦикла;   
если помогло нажмите: Спасибо!

Afinogen

Согласен с предыдущим оратором, лучше через временные таблицы

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

как то так

Теги:

Похожие темы (5)

Рейтинг@Mail.ru

Поиск