Формирование любого отчета в таблицу значений. УТ 11.4

Отчет доходы и расходы показывает только доходы и расходы, а клиент хочет свести данные из нескольких отчетов в полноценный отчет P&L.

Первоначально я хотел изменить поведение отчета «Доходы и расходы предприятия», чтобы выгрузить его в таблицу значений, а дальше упаковать таблицу значений как нужно.

Первым делом вызываю вместо типового кода построителя отчета свой:

Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;
	ПользовательскиеНастройкиМодифицированы = Ложь;

	УстановитьОбязательныеНастройки(ПользовательскиеНастройкиМодифицированы);
	
	СхемаКомпоновкиДанных.НаборыДанных.ДоходыИРасходы.Элементы.Расходы.Запрос = ТекстЗапросаРасходы();

	
	НастроитьПользовательскиеНастройкиПоФункциональнымОпциям(КомпоновщикНастроек);
	НастройкиОтчета = КомпоновщикНастроек.ПолучитьНастройки();

	//Осипов - выводим и все - вставтлять когда настройки отчета получены в алгоритме
	СобственныйВыводОтчета(НастройкиОтчета, ДанныеРасшифровки, ДокументРезультат);
	Возврат;
	
	...
	
КонецПроцедуры

Далее программно создаю свой собственный макет для вывода в таблицу значений ТЗИсх.

Обрабатываю таблицу значений и получаю таблицу значений для вывода ТЗ.

Далее ее вывожу, используя свой простой макет:

Код несложный и понятный:

Процедура СобственныйВыводОтчета(НастройкиОтчета, ДанныеРасшифровки, ДокументРезультат)     
	
	//Осипов
	НастройкиОтчета.Структура.Очистить();	
	ГК = НастройкиОтчета.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
	//Поле = ГК.ПоляГруппировки.Элементы.Добавить(Тип("АвтоПолеГруппировкиКомпоновкиДанных"));
	Поле = ГК.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
	Поле.Поле = Новый ПолеКомпоновкиДанных("ПериодМесяц");

	Поле = ГК.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
	Поле.Поле = Новый ПолеКомпоновкиДанных("Раздел");

	Поле = ГК.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
	Поле.Поле = Новый ПолеКомпоновкиДанных("СтатьяДоходов");

	Поле = ГК.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
	Поле.Поле = Новый ПолеКомпоновкиДанных("СтатьяРасходов");

	Поле = ГК.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
	Поле.Поле = Новый ПолеКомпоновкиДанных("ПрибыльУбыток");
	
	КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
	МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, НастройкиОтчета, ДанныеРасшифровки,, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
	
	КомпоновкаДанныхСервер.УстановитьЗаголовкиМакетаКомпоновки(СтруктураЗаголовковПолей(), МакетКомпоновки);
	
	ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
	ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);

	ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;

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



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

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

Но потом я думаю — а почему бы не получать данные из отчета «Доходы и расходы предприятия» по сохраненному варианту под выгрузку в таблицу значений? И так можно собрать данные из нескольких отчетов, что более универсально. Эта тема искушает меня и я начинаю ее реализовывать.

В итоге получилось довольно быстро, еще за час.

На этот раз целиком заменяю событие при компоновке:

Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
	//Осипов - выводим и все - вставтлять когда настройки отчета получены в алгоритме
	СобственныйВыводОтчета(ДанныеРасшифровки, ДокументРезультат);
	СтандартнаяОбработка = Ложь;
	Возврат;
	...
КонецПроцедуры


В принципе, можно было бы использовать шаблон внешнего отчета с периодом, по сути там важны только параметры (я использую только период, т.к. организация одна, но можно добавить еще и организацию).

Я делаю вариант отчета — плоский, для выгрузки в ТЗ:

Записи без группировок, поэтому их много. К сожалению, в этом отчете нельзя добавить поле Период в группировку, поэтому получить свернутый плоский отчет нельзя.

Ну а сам код довольно простой:

  1. Нахожу нужный вариант отчета, получаю из него настройки.
  2. Получаю нужную схему компоновки из макета отчета. Тут важно, что иногда 1С подменяет текст запроса, что и произошло в данном случае.
  3. Устанавливаю из текущих настроек период в сохраненном варианте. Тут важно, что в текущих настройках период хранится в пользовательских настройках.
  4. Ну а далее все штатно — вывожу в таблицу значений и дальше как в прошлом случае.
Процедура СобственныйВыводОтчета(ДанныеРасшифровки, ДокументРезультат)     
	
	//Текущие настройки отчета
	НастройкиОтчета = КомпоновщикНастроек.ПолучитьНастройки();
	
	//Получаем сохраненные настройки
	ДопСхемаКомпоновкиДанных = Отчеты.АнализДоходовРасходов.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");  
	
	//Важно! Скопировано из типового отчета - текст запроса подменяется
	ДопСхемаКомпоновкиДанных.НаборыДанных.ДоходыИРасходы.Элементы.Расходы.Запрос = ТекстЗапросаРасходы();
	ДопВариант = Справочники.ВариантыОтчетов.НайтиПоНаименованию("Доходы и расходы предприятия для ТЗ");
	ДопНастройки = ДопВариант.Настройки.Получить();         
	
	//Важно! Период хранится в пользовательских настройках
	ТекПараметрПериод = НайтиПользовательскийПараметр(КомпоновщикНастроек, Новый ПараметрКомпоновкиДанных("Период"));
	ДопПараметр = ДопНастройки.ПараметрыДанных.Элементы.Найти("Период");
	ДопПараметр.Использование = Истина;
    ДопПараметр.Значение.ДатаНачала    = ТекПараметрПериод.Значение.ДатаНачала;
    ДопПараметр.Значение.ДатаОкончания = ТекПараметрПериод.Значение.ДатаОкончания;
	
	
	КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
	МакетКомпоновки = КомпоновщикМакета.Выполнить(ДопСхемаКомпоновкиДанных, ДопНастройки, ДанныеРасшифровки,, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
	
	ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
	ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);

	ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;

	//Осипов
	ТЗИсх = Новый ТаблицаЗначений;
	ПроцессорВывода.НачатьВывод();
	ПроцессорВывода.УстановитьОбъект(ТЗИсх);   
	ТЗИсх = ПроцессорВывода.Вывести(ПроцессорКомпоновки);     

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


Таким образом, можно использовать данные нескольких отчетов, не повторяя их код.

Среда 11.4.13.46. Платформа 8.3.19.1723 Объем 2 час.

fixin

Программирую на 1С с 1999 года. В 1С просто Гений. В 2020 году ушел из офиса на вольные хлеба фриланса. Принимаю заказы.

Читайте также:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *