Имя: Пароль:
1C
1С v8
Расчёт средних продаж
0 TemkaTV
 
19.01.16
11:15
1
1 PR третий
 
19.01.16
11:16
Да
2 TemkaTV
 
19.01.16
11:18
Привет всем, помогите пожалуйста. Внешняя Обработка. Вообщем она рассчитывает средние продажи за день. Если продажи за период по номенклатуре не было - то в карточке номенклатуры средние продажи должны в ноль записаться..
3 TemkaTV
 
19.01.16
11:18
Запрос = Новый Запрос;
    Запрос.Текст =
        "ВЫБРАТЬ
        |    Продажи.Номенклатура КАК Номенклатура,
        |    Продажи.Номенклатура.Производитель КАК Производитель,
        |    Продажи.КоличествоОборот,
        |    Продажи.Период КАК Период
        |ИЗ
        |    (ВЫБРАТЬ
        |        АналитикаПоПартнерам.Партнер КАК Партнер,
        |        АналитикаНоменклатуры.Номенклатура КАК Номенклатура,
        |        АналитикаНоменклатуры.Склад КАК Склад,
        |        Продажи.Регистратор КАК Регистратор,
        |        Продажи.КоличествоОборот КАК КоличествоОборот,
        |        Продажи.Период КАК Период
        |    ИЗ
        |        РегистрНакопления.ВыручкаИСебестоимостьПродаж.Обороты(&НачПериода, &КонПериода, Регистратор, ) КАК Продажи
        |            {ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.АналитикаУчетаНоменклатуры КАК АналитикаНоменклатуры
        |            ПО Продажи.АналитикаУчетаНоменклатуры = АналитикаНоменклатуры.КлючАналитики}
        |            {ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.АналитикаУчетаПоПартнерам КАК АналитикаПоПартнерам
        |            ПО Продажи.АналитикаУчетаПоПартнерам = АналитикаПоПартнерам.КлючАналитики}
        |    ГДЕ
        |        Продажи.Регистратор.Ссылка ССЫЛКА Документ.РеализацияТоваровУслуг) КАК Продажи
        |ГДЕ
        |   Продажи.Склад <> &Склад
        |    И Продажи.Партнер <> &ИнкомЦентрЙошкарОла
        |    И Продажи.Номенклатура В ИЕРАРХИИ(&Товар)
        |    И Продажи.Номенклатура.Производитель = &Производитель
        |
        |УПОРЯДОЧИТЬ ПО
        |    Продажи.Номенклатура.Наименование,
        |    Период
        |ИТОГИ ПО
        |    Номенклатура";

    Запрос.УстановитьПараметр("Товар", ТоварнаяГруппаДляРасчета);
    Если СокрЛП(Отчет.Производитель) <> "" Тогда
        Запрос.УстановитьПараметр("Производитель", Справочники.Производители.НайтиПоНаименованию(СокрЛП(Отчет.Производитель)));
    Иначе    
        Запрос.Текст = СтрЗаменить(Запрос.Текст, "И Продажи.Номенклатура.Производитель = &Производитель", "");
    КонецЕсли;        
    Если Отчет.УчитыватьФилиалы = Ложь Тогда
        Запрос.УстановитьПараметр("ИнкомЦентрЙошкарОла", Справочники.Партнеры.НайтиПоНаименованию("Инкомцентр-М ООО г. Йошкар-Ола"));
    Иначе    
        Запрос.Текст = СтрЗаменить(Запрос.Текст, "И Продажи.Партнер <> &ИнкомЦентрЙошкарОла", "");
    КонецЕсли;        
    Запрос.УстановитьПараметр("НачПериода", НачалоДня(НачПериода));
    Запрос.УстановитьПараметр("КонПериода", КонецДня(КонПериода));
    Запрос.УстановитьПараметр("Склад", Справочники.Склады.НайтиПоНаименованию("Склад транзита"));

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

    ВыборкаНоменклатура = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

    Пока ВыборкаНоменклатура.Следующий() Цикл
        // Вставить обработку выборки ВыборкаНоменклатура

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

        
        СредниеПродажи  = ?(КолДней = 0, 0,  ПродажиЗаПериод/КолДней);        
        МинОстаток1     = ?(КолДнейМО = 0, 0,  ПродажиЗаПериод/КолДнейМО);
        
        Результат1 = Запрос.Выполнить();    
        
        Если Отчет.МинимальныйОстатокВвестиВРучную = Истина и Отчет.МинимальныйОстаток > 0 Тогда
            МинОстаток1 = Отчет.МинимальныйОстаток;
            Сообщить("Используем установленный минимальный остаток - "+МинОстаток1);
        КонецЕсли;
        
        ВыборкаПериод1 = Результат1.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам,"Период","ВСЕ");        
        Пока ВыборкаПериод1.Следующий() Цикл
            Если ЗначениеЗаполнено(ВыборкаПериод1.ВНаличииКонечныйОстаток) Тогда
                Если ВыборкаПериод1.ВНаличииКонечныйОстаток >= МинОстаток1 Тогда
                    КолДнейВ = КолДнейВ + 1;
                КонецЕсли;
            КонецЕсли;    
        КонецЦикла;
        
        СредниеПродажи1 = ?(КолДнейВ = 0, 0,  ПродажиЗаПериод/КолДнейВ);
        
        СредниеПродажи  = Окр(СредниеПродажи1,3,0);        
        СредниеПродажи1 = Окр(СредниеПродажи1,3,0);
        МинОстаток1     = Окр(МинОстаток1,3,0);
        Сообщить("Дней когда кон остаток больше чем мин (старая мет) - "+КолДней);
        Сообщить("Дней когда остатки больше чем мин - "+КолДнейВ);
        Сообщить("Дней когда товар на складе был (больше чем 1) - "+КолДнейМО);
        Сообщить("Средние продажи: старая методика - "+СредниеПродажи);
        Сообщить("Мин остаток: старая методика - "+МинОстаток);
        Сообщить("Средние продажи; новая методика - "+СредниеПродажи1);
        Сообщить("Мин остаток: новая методика - "+МинОстаток1);
        
        Если Отчет.ЗаписатьРасчет = Истина Тогда
            СпрОбъект = ВыборкаНоменклатура.Номенклатура.ПолучитьОбъект();
            СпрОбъект.СредниеПродажиЗаДень     = СредниеПродажи1;
            СпрОбъект.НижнийПорогЗаказа = МинОстаток1;
            СпрОбъект.Записать();
        КонецЕсли;
        
    КонецЦикла;
4 mehfk
 
19.01.16
11:19
Предлагаю сделать правое соединение со справочником "Номенклатура".
5 Garykom
 
гуру
19.01.16
11:19
(4) а почему не левое?
6 mehfk
 
19.01.16
11:20
(5) Ну либо левое, но тогда справочника "Номенклатура" со всей этой байдой.
7 TemkaTV
 
19.01.16
11:24
(4) а можно чуть подробнее? Я начинающий, пожалуйста
8 Garykom
 
гуру
19.01.16
11:24
(6) а может все таки переписать все это по нормальному?

а то там классика "запрос в цикле"...
9 mehfk
 
19.01.16
11:25
10 Garykom
 
гуру
19.01.16
11:25
(8)+ мдяя.. в двойном цикле к тому же...
11 TemkaTV
 
19.01.16
11:29
(8) Писал не я, используется подобная обработка не всегда. Сейчас как быть? потом исправлять буду.. срочно попросили, а спросить не у кого, в отпуске опытный программист..
12 Smile 8D
 
19.01.16
11:31
(11) Если конкретный совет про соединение не помог, то читать предложенную книгу. Она совсем тоненькая и в любом случае полезная.
13 TemkaTV
 
19.01.16
11:33
(11) В 1 запросе?
14 Garykom
 
гуру
19.01.16
11:38
(11) перед всем этим геморроем, сделай простую переборку номенклатуры и для каждой:

СпрОбъект = ВыборкаНоменклатура.Номенклатура.ПолучитьОбъект();
СпрОбъект.СредниеПродажиЗаДень     = 0;
//СпрОбъект.НижнийПорогЗаказа = МинОстаток1;
СпрОбъект.Записать();