Имя: Пароль:
1C
1С v8
Итоги в отчете при использовании компановки результата
,
0 asder117
 
27.02.19
09:04
Доброго времени суток.
Имеется отчет по номенклатуре и расчетам с обходом всех элементов спецификации. При формировании используется рекурсия.
Вопрос встал в формировании итогов если по процедуре проходит одна номенклатура и особенно когда несколько единиц номенклатуры. Как можно накопить сумму и потом использовать ее в итогах.
Спасибо
КОд модуля
[COD]Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    КоэфНДС = ?(СебестоимостьБезНДС, 1.18, 1);
    
    Макет = ПолучитьМакет("Макет");
    
    Если СпособСравнения = "проект" Тогда
        ОбластьШапкаПроекта = Макет.ПолучитьОбласть("ШапкаПроекта");
        ОбластьСтрокаПроекта = Макет.ПолучитьОбласть("СтрокаПроекта");
        ДокументРезультат.Вывести(ОбластьШапкаПроекта);
        для каждого строкаПроекта из ТаблицаПроекта цикл
        ОбластьСтрокаПроекта.Параметры.НоменклатураПроект = строкаПроекта.Продукция.Наименование;
        ОбластьСтрокаПроекта.Параметры.НоменклатураПроект = строкаПроекта.Количество;
        ДокументРезультат.Вывести(ОбластьСтрокаПроекта);
        КонецЦикла;
    КонецЕсли;

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




Процедура ВывестиСтроки(НоменклатураВх, Себестоимость, Макет, ДокументРезультат, Знач ИндексОтступа, Количество, ЭтоКорень = Ложь, ЗП)
    
    ИндексОтступа = ИндексОтступа + 1;
    
    //сначала узнаем какую номенклатуру выводить в отчет. Если есть актуальный аналог и он пришел позже, то выводим его
    
    Номенклатура = ПолучитьАктуальныйАналог(НоменклатураВх);
    
    Себестоимость = ПолучитьСебестоимость(Номенклатура, Количество);
    Если ЭтоКорень Тогда
        ДЦ            = ПолучитьДилерскуюЦену(Номенклатура, Количество);
        ДПЦ           = ПолучитьДилерскуюПроектнуюЦену(Номенклатура, Количество);
    КонецЕсли;    

    
    СтрокаНоменклатура = "" +
                         ?(ЭтоКорень, Номенклатура, "- "+Номенклатура)+
                         ?(Количество=0, "", " (" + Количество + ")");
                        
    Строка = Макет.ПолучитьОбласть("Строка1");
    Строка.Параметры.Номенклатура = СтрокаНоменклатура;
    Строка.Параметры.Себестоимость = Себестоимость;
    Если ЭтоКорень Тогда
        Строка.Параметры.ДЦ = ДЦ;
        Строка.Параметры.ДПЦ = ДПЦ;
    КонецЕсли;    
    Строка.Области.Номенклатура.Расшифровка = Номенклатура;
    Строка.Области.Номенклатура.Отступ = ИндексОтступа;
    
    Если ЭтоКорень Тогда
        Строка.Области.Номенклатура.Шрифт         = новый Шрифт("Arial", 8, Истина);
        Строка.Области.Себестоимость.Шрифт        = новый Шрифт("Arial", 8, Истина);
        Строка.Области.ЗарплатаСдельнаяИтог.Шрифт = новый Шрифт("Arial", 8, Истина);
        Строка.Области.ДЦ.Шрифт                   = новый Шрифт("Arial", 8, Истина);
        Строка.Области.НакладныеРасходы.Шрифт   = новый Шрифт("Arial", 8, Истина);
        Строка.Области.РентабельностьПоДЦ.Шрифт   = новый Шрифт("Arial", 8, Истина);
        Строка.Области.ДПЦ.Шрифт                  = новый Шрифт("Arial", 8, Истина);
        Строка.Области.НакладныеРасходыСеб.Шрифт  = новый Шрифт("Arial", 8, Истина);
        Строка.Области.РентабельностьПоДПЦ.Шрифт  = новый Шрифт("Arial", 8, Истина);
    КонецЕсли;    
        
    Если ЭтоКорень Тогда
    ДокументРезультат.Вывести(Строка, ИндексОтступа-1, , Ложь);
КонецЕсли;

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

        
    КонецЕсли;
    
    Если ЭтоКорень Тогда
        НакладныеРасходыСебТаб = Себестоимость + Себестоимость*НакладныеРасходы/100;
        ВаловаяПрибыльПоДЦ = ДЦ - НакладныеРасходыСебТаб - ЗП;
        РентабельностьПоДЦ = ?(ДЦ=0, 0, ВаловаяПрибыльПоДЦ * 100 / ДЦ);
        НакладныеРасходыТаб = Себестоимость*НакладныеРасходы/100;
        //НакладныеРасходыСебТаб = Себестоимость + Себестоимость*НакладныеРасходы/100;
        ВаловаяПрибыльПоДПЦ = ДПЦ - НакладныеРасходыСебТаб - ЗП;
        РентабельностьПоДПЦ = ?(ДПЦ=0, 0, ВаловаяПрибыльПоДПЦ * 100 / ДПЦ);
        
        ДокументРезультат.Область(НомерСтрокиКорень,НомерКолонкиНакладныеРасходы,НомерСтрокиКорень,НомерКолонкиНакладныеРасходы).Значение = НакладныеРасходыТаб;
        ДокументРезультат.Область(НомерСтрокиКорень,НомерКолонкиРентабельностьПоДЦ,НомерСтрокиКорень,НомерКолонкиРентабельностьПоДЦ).Значение = РентабельностьПоДЦ;
        ДокументРезультат.Область(НомерСтрокиКорень,НомерКолонкиНакладныеРасходыСеб,НомерСтрокиКорень,НомерКолонкиНакладныеРасходыСеб).Значение = НакладныеРасходыСебТаб;
        ДокументРезультат.Область(НомерСтрокиКорень,НомерКолонкиРентабельностьПоДПЦ,НомерСтрокиКорень,НомерКолонкиРентабельностьПоДПЦ).Значение = РентабельностьПоДПЦ;
    КонецЕсли;    
    
        
КонецПроцедуры    
[/COD]
1 aleks_default
 
27.02.19
09:18
Одно непонятно. Зачем вам СКД?
2 aleks_default
 
27.02.19
09:19
Порадовало

  Пока Выборка.Следующий() Цикл
            
            ОбработкаПрерыванияПользователя();
3 asder117
 
27.02.19
09:24
(2) Это сделано если номенклатуры много чтобы можно было прервать выполнение.
(1) До меня начали делать. городить перенос в виде объекта в СКД не очень хочется честно говоря. Вот и ище как можно сделать без использования и накопить общую сумму
4 aleks_default
 
27.02.19
09:29
Накопить общую сумму передав отдельный параметр в процедуру ВывестиСтроку перед первым ее вызовом
5 asder117
 
27.02.19
09:33
(4) Вопрос понять какой параметр и как машина должна понять сколько номенклатур было рассчитано и выведено в таблицу результат. Я грешным делом решил (пока не пойму как) в конце обойти ДокументРезультат и взяв оттуда строки посчитать сумму. но чувствую это не то
6 aleks_default
 
27.02.19
09:39
Сначала нужно тебя понять. О какой сумме идет речь? О себестоимости или валовой прибыли или еще о чем? Чувствую тебе подобная задача вряд ли по плечу.
7 asder117
 
27.02.19
09:45
(6) И себестоимость и рентабельность надо суммировать. Ничего, главное понять как делать а дальше все по плечу..
8 aleks_default
 
27.02.19
10:19
тогда пойми сначала вот это дальше пойдет легше

//обходим спецификацию и накапливаем себестоимость
        
        Для Каждого СтрокаСпецификации Из Спецификация.ИсходныеКомплектующие Цикл
            
            ОбработкаПрерыванияПользователя();
            
            новСебестоимость = 0;
            новЗП = 0;
            
            ВывестиСтроки(СтрокаСпецификации.Номенклатура, новСебестоимость, Макет, ДокументРезультат, ИндексОтступа, СтрокаСпецификации.Количество*Количество,,новЗП);
            
            Себестоимость = Себестоимость + новСебестоимость;
            ЗП = ЗП + новЗП;
        КонецЦикла;