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

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

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

Автор: bizisoft 26.05.20, 11:23

1С 8.2 Альфа-Авто 4.1.

Для выбранного товара первым запросом получаю список Аналогов, а потом для них получаю продажи (квартал, 6 мес, год), но знаний хватило только на получение продаж отдельным запросом для каждого периода.

//Получаем список значений с набором всех Аналогов по выбранному Артикулу

        Запрос = Новый Запрос;
    Запрос.Текст =
        "ВЫБРАТЬ
        |    ГруппыАналогов.Артикул,
        |    ГруппыАналогов.Производитель,
        |    ГруппыАналогов.тАртикул
        |ИЗ
        |    РегистрСведений.ГруппыАналогов КАК ГруппыАналогов
        |        ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ГруппыАналогов КАК ГруппыАналогов1
        |        ПО ГруппыАналогов.ИдентификаторГруппы = ГруппыАналогов1.ИдентификаторГруппы
        |ГДЕ
        |    ГруппыАналогов1.Артикул = &Артикул";

    Запрос.УстановитьПараметр("Артикул", Товар);
    Результат = Запрос.Выполнить();
    Выб = Результат.Выбрать();
    СпЗн = Новый СписокЗначений;
    СпЗн.Очистить();    
    Пока Выб.Следующий() Цикл
        СпЗн.Добавить(Выб.Артикул,Выб.Артикул);
    КонецЦикла;

//Для полученного списка (Аналогов) получаем продажи (Квартал, 6 мес, Год)

        Для Счетчик = 1 По 3 Цикл
        Если       Счетчик = 1 Тогда    
             НачПериод = НачалоДня(ДобавитьМесяц(ТекущаяДата(),-3));    // квартал
        ИначеЕсли Счетчик = 2 Тогда    
            НачПериод = НачалоДня(ДобавитьМесяц(ТекущаяДата(),-6));    // пол года  
        ИначеЕсли Счетчик = 3 Тогда    
            НачПериод = НачалоДня(ДобавитьМесяц(ТекущаяДата(),-12));// год
        КонецЕсли;        
        КонПериод = КонецДня(ТекущаяДата());

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

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



Попробовал сделать так:
ВЫБРАТЬ
            |    Продажи.Номенклатура,
            |    Продажи.Номенклатура.Артикул КАК Артикул,
            |    Продажи.Номенклатура.тАртикул КАК тАртикул,
            |    Продажи.Номенклатура.Производитель КАК Производитель,
            |    Продажи.Количество КАК ПродажаКвартал,
            |    Продажи1.Количество КАК ПродажаПолгода,
            |    Продажи2.Количество КАК ПродажаГод
            |ИЗ
            |    РегистрНакопления.Продажи КАК Продажи1
            |        ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи КАК Продажи
            |            ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи КАК Продажи2
            |            ПО Продажи2.Номенклатура = Продажи.Номенклатура
            |        ПО Продажи1.Номенклатура = Продажи.Номенклатура
            |ГДЕ
            |    Продажи.Период МЕЖДУ &НачПериодК И &КонПериод
            |    И Продажи.Номенклатура.Артикул В(&СпЗнАртикул)
            |    И Продажи1.Период МЕЖДУ &НачПериодПГ И &КонПериод
            |    И Продажи2.Период МЕЖДУ &НачПериодГ И &КонПериод


Но что-то мне подсказывает, что это не верно в корне.
Забил запрос в Запросник, но результата нет, да и запрос выполняется гораздо дольше чем если через цикл с запросами.


Подскажите пожалуйста, как правильно создать запрос, чтобы исключить цикл со вложенными запросами и как правильно обозначить параметры с разделением по периодам (квартал, 6 мес, год), чтобы вывести периоды были в столбцах
Номенклатура | Квартал | 6 мес | Год

Автор: sava1 26.05.20, 12:48

как-то так. Обратите внимание на период в каждой выборке

|ВЫБРАТЬ
|    Продажи.Период,
|    Продажи.Номенклатура,
|    Продажи.Количество КвоКвартал,
|      0 КвоПолгода,
|      0 КвоГод,
|    Продажи.Номенклатура.Артикул КАК Артикул,
|    Продажи.Номенклатура.тАртикул КАК тАртикул,
|    Продажи.Номенклатура.Производитель КАК Производитель
|ИЗ
|    РегистрНакопления.Продажи КАК Продажи
|ГДЕ
|    Продажи.Период МЕЖДУ &НачПериодКвартал И &КонПериодКвартал
|    И Продажи.Номенклатура.Артикул В(&СпЗнАртикул)
|
|UNION ALL
|
|ВЫБРАТЬ
|    Продажи.Период,
|    Продажи.Номенклатура,
|    0 КвоКвартал,
|      Продажи.Количество КвоПолгода,
|      0 КвоГод,
|    Продажи.Номенклатура.Артикул КАК Артикул,
|    Продажи.Номенклатура.тАртикул КАК тАртикул,
|    Продажи.Номенклатура.Производитель КАК Производитель
|ИЗ
|    РегистрНакопления.Продажи КАК Продажи
|ГДЕ
|    Продажи.Период МЕЖДУ &НачПериодПолгода И &КонПериодПолгода
|    И Продажи.Номенклатура.Артикул В(&СпЗнАртикул)
|
|UNION ALL
|
|ВЫБРАТЬ
|    Продажи.Период,
|    Продажи.Номенклатура,
|    0 КвоКвартал,
|      0 КвоПолгода,
|      Продажи.Количество КвоГод,
|    Продажи.Номенклатура.Артикул КАК Артикул,
|    Продажи.Номенклатура.тАртикул КАК тАртикул,
|    Продажи.Номенклатура.Производитель КАК Производитель
|ИЗ
|    РегистрНакопления.Продажи КАК Продажи
|ГДЕ
|    Продажи.Период МЕЖДУ &НачПериодГод И &КонПериодГод
|    И Продажи.Номенклатура.Артикул В(&СпЗнАртикул)

Автор: bizisoft 26.05.20, 16:27

sava1 @ Сегодня, 13:48 * ,
Премного благодарен, получилось.


Можно-ли к этому запросу добавить в пакет запросов:

ВЫБРАТЬ
            ГруппыАналогов.Артикул
        ПОМЕСТИТЬ СписокАналоги
        ИЗ
            РегистрСведений.ГруппыАналогов КАК ГруппыАналогов
                ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ГруппыАналогов КАК ГруппыАналогов1
                ПО ГруппыАналогов.ИдентификаторГруппы = ГруппыАналогов1.ИдентификаторГруппы
        ГДЕ
            ГруппыАналогов1.тАртикул = &Артикул


а результат этого запроса (временная таблица СписокАналоги) передать в качестве параметра &СпЗнАртикул в основной запрос?
Принципиальная-ли разница где этот запрос нужно вставлять перед основным запросом или можно после?

Также не понятно, как временную таблицу СписокАналоги можно передать в качестве параметра &СпЗнАртикул в основном запросе, который в данном случае встречается аж 3 раза (в каждом из объединенных запросов)?
Я попробовал заменить В (&СпЗнАртикул) на В (СписокАналоги) , но походу эти два запроса не видят друг друга.
В случае же отдельного выполнения запроса, можно проверить на пустой результат и если Пусто, то в СписокЗначения добавить текущий Артикул в качестве единственного значения списка.

bizisoft @ Сегодня, 16:59 * ,
Тут подумал и наверное такое не прокатит, т.к. в случае отсутствия Аналогов у текущей позиции запрос вернет пустой результат и соответственно основной запрос также вернет пустой результат, что не есть верным.

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