Версия для печати темы (https://pro1c.org.ua/index.php?s=3678f2824f7011fcc50f714cc4d3ba11&showtopic=59843)

Нажмите сюда для просмотра этой темы в обычном формате

Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 _ Программирование в 1С Предприятие 8.3 _ Ускорить работу запроса-объект по поиску данных

Автор: Constantus 24.06.20, 11:44

Приветствую, Форумчане!
1с8.3.12, УФ, самопис

Имеется некий запрос объект, в модуле которого прописывается код поиска остатка позиций по Регистру накопления.

    РезультатСЗ = Запрос.Выполнить().Выгрузить();
    
    РезультатСЗ.Колонки.Добавить("ОстатокСклада", ОбщегоНазначения.ОписаниеТипаЧисло(15,2));    
    РезультатСЗ.Колонки.Добавить("Проблема",       ОбщегоНазначения.ОписаниеТипаСтрока(100));
                                    
    Для Каждого СТР Из РезультатСЗ Цикл
        
        Если СТР.Параметр = "СТЛ" Тогда
            СТР.ОстатокСклада = ОстатокСтел(СТР.Номенклатура, СТР.Модель, СТР.РазмерИзделия, СТР.ПолировкаИзделия, СТР.Склад, СТР.Период);
        ИначеЕсли СТР.Параметр = "ОСН" Тогда
            СТР.ОстатокСклада = ОстатокНоменклатуры(СТР.Номенклатура, СТР.РазмерИзделия, СТР.ПолировкаИзделия, СТР.Склад, СТР.Период);
        ИначеЕсли СТР.Параметр = "ДОП" Тогда    
            СТР.ОстатокСклада = ОстатокДопов(СТР.Номенклатура, СТР.Склад, СТР.Период);
        КонецЕсли;    
            
    КонецЦикла;




Где функции "ОстатокСтел/Номенклатуры/Допов" имеет одинаковый смысл поиска из регистра накопления, только с разными параметрами поиска:Таких запросов аж 3-и штуки

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



Запрос работает правильно, но очень медлено, т.к. каждая строка имеет свой параметр поиска "Период" и "Склад"
Можно ли как-то ускорить работу запроса по поиску остатков по каждой строке с разными параметрами поиска?

Автор: daveal 24.06.20, 13:25

Я обычно в таких случаях определяю Мин/Макс период, беру остатки на Мин дату + обороты за интервал

Автор: Bernet 24.06.20, 13:36

Constantus @ Сегодня, 12:44 * ,
У вас запрос в цикле - не есть хорошо.
Сделайте так чтобы запрос выполнялся 1 раз и потом работайте с таблицей результата - будет вам ускорение

Автор: Constantus 24.06.20, 15:13

Bernet @ Сегодня, 17:36 * ,
А как мне сделать "универсальный отчет" по определению остатка позиций, если этот запрос по определению остатков зависит от периода
(он разный в строках основного отчета

РезультатСЗ = Запрос.Выполнить().Выгрузить();
)

да еще зависит от разных параметров структуры поиска по каждой строке?

Constantus @ Сегодня, 19:13 * ,

В смысле есть 3-и варианта поиска + дата в каждой позиции

Автор: Bernet 24.06.20, 16:24

Constantus @ Сегодня, 16:13 * ,
Дата - это не проблема, можно сделать запрос в котором сможете получить остатки по дням, т.е. на каждую вашу дату. Аналитика тоже думаю не проблема - сформируйте таблицу значений с этими всеми параметрами, передайте её в запрос в качестве основной таблицы и к ней прицепите остатки

Пример получения запрос остатков по дням:
Текст запроса

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

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

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

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    0 КАК Цифра
ПОМЕСТИТЬ Цифры

ОБЪЕДИНИТЬ

ВЫБРАТЬ
    1

ОБЪЕДИНИТЬ

ВЫБРАТЬ
    2

ОБЪЕДИНИТЬ

ВЫБРАТЬ
    3

ОБЪЕДИНИТЬ

ВЫБРАТЬ
    4

ОБЪЕДИНИТЬ

ВЫБРАТЬ
    5

ОБЪЕДИНИТЬ

ВЫБРАТЬ
    6

ОБЪЕДИНИТЬ

ВЫБРАТЬ
    7

ОБЪЕДИНИТЬ

ВЫБРАТЬ
    8

ОБЪЕДИНИТЬ

ВЫБРАТЬ
    9
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Тысячи.Цифра * 1000 + Сотни.Цифра * 100 + Десятки.Цифра * 10 + Единицы.Цифра КАК Дней
ПОМЕСТИТЬ СписокДней
ИЗ
    Цифры КАК Тысячи,
    Цифры КАК Сотни,
    Цифры КАК Десятки,
    Цифры КАК Единицы
ГДЕ
    Тысячи.Цифра * 1000 + Сотни.Цифра * 100 + Десятки.Цифра * 10 + Единицы.Цифра <= РАЗНОСТЬДАТ(&НачалоПериода, &КонецПериода, ДЕНЬ)
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ДОБАВИТЬКДАТЕ(&НачалоПериода, ДЕНЬ, СписокДней.Дней) КАК Период
ПОМЕСТИТЬ ВтСписокДат
ИЗ
    СписокДней КАК СписокДней
;

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

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

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

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

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

Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7
https://pro1c.org.ua