Формирование любого отчета в таблицу значений. УТ 11.4
Отчет доходы и расходы показывает только доходы и расходы, а клиент хочет свести данные из нескольких отчетов в полноценный отчет P&L.
Первоначально я хотел изменить поведение отчета «Доходы и расходы предприятия», чтобы выгрузить его в таблицу значений, а дальше упаковать таблицу значений как нужно.
Первым делом вызываю вместо типового кода построителя отчета свой:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) СтандартнаяОбработка = Ложь; ПользовательскиеНастройкиМодифицированы = Ложь; УстановитьОбязательныеНастройки(ПользовательскиеНастройкиМодифицированы); СхемаКомпоновкиДанных.НаборыДанных.ДоходыИРасходы.Элементы.Расходы.Запрос = ТекстЗапросаРасходы(); НастроитьПользовательскиеНастройкиПоФункциональнымОпциям(КомпоновщикНастроек); НастройкиОтчета = КомпоновщикНастроек.ПолучитьНастройки(); //Осипов - выводим и все - вставтлять когда настройки отчета получены в алгоритме СобственныйВыводОтчета(НастройкиОтчета, ДанныеРасшифровки, ДокументРезультат); Возврат; ... КонецПроцедуры
Далее программно создаю свой собственный макет для вывода в таблицу значений ТЗИсх.
Обрабатываю таблицу значений и получаю таблицу значений для вывода ТЗ.
Далее ее вывожу, используя свой простой макет:
Код несложный и понятный:
Процедура СобственныйВыводОтчета(НастройкиОтчета, ДанныеРасшифровки, ДокументРезультат) //Осипов НастройкиОтчета.Структура.Очистить(); ГК = НастройкиОтчета.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных")); //Поле = ГК.ПоляГруппировки.Элементы.Добавить(Тип("АвтоПолеГруппировкиКомпоновкиДанных")); Поле = ГК.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных")); Поле.Поле = Новый ПолеКомпоновкиДанных("ПериодМесяц"); Поле = ГК.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных")); Поле.Поле = Новый ПолеКомпоновкиДанных("Раздел"); Поле = ГК.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных")); Поле.Поле = Новый ПолеКомпоновкиДанных("СтатьяДоходов"); Поле = ГК.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных")); Поле.Поле = Новый ПолеКомпоновкиДанных("СтатьяРасходов"); Поле = ГК.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных")); Поле.Поле = Новый ПолеКомпоновкиДанных("ПрибыльУбыток"); КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, НастройкиОтчета, ДанныеРасшифровки,, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений")); КомпоновкаДанныхСервер.УстановитьЗаголовкиМакетаКомпоновки(СтруктураЗаголовковПолей(), МакетКомпоновки); ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных; ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина); ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений; //Осипов ТЗИсх = Новый ТаблицаЗначений; ПроцессорВывода.НачатьВывод(); ПроцессорВывода.УстановитьОбъект(ТЗИсх); ТЗИсх = ПроцессорВывода.Вывести(ПроцессорКомпоновки); ТЗ = Новый ТаблицаЗначений(); ТЗ.Колонки.Добавить("Показатель"); ТЗ.Колонки.Добавить("Статья"); ТЗ.Колонки.Добавить("Период"); ТЗ.Колонки.Добавить("Значение"); Для Каждого Строка ИЗ ТЗИсх Цикл НСтр = ТЗ.Добавить(); НСтр.Период = Строка.ПериодМесяц; НСтр.Показатель = Строка.Раздел; Если ЗначениеЗаполнено(Строка.СтатьяРасходов) Тогда НСтр.Статья = Строка.СтатьяРасходов; ИначеЕсли ЗначениеЗаполнено(Строка.СтатьяДоходов) Тогда НСтр.Статья = Строка.СтатьяДоходов; КонецЕсли; НСтр.Значение = Строка.ПрибыльУбыток; КонецЦикла; СхемаКомпоновкиДоп = ПолучитьМакет("PL"); КомпоновщикНастроекДоп = Новый КомпоновщикНастроекКомпоновкиДанных(); КомпоновщикНастроекДоп.ЗагрузитьНастройки(СхемаКомпоновкиДоп.НастройкиПоУмолчанию); ДанныеРасшифровкиДоп = Неопределено; СтруктураВнешнихДанных = Новый Структура("ТЗ", ТЗ); ВывестиОтчетВСКД(ДокументРезультат, СхемаКомпоновкиДоп, КомпоновщикНастроекДоп, ДанныеРасшифровкиДоп, СтруктураВнешнихДанных); КонецПроцедуры //Осипов Функция ВывестиОтчетВСКД(ДокументРезультат, СхемаКомпоновкиДанных, КомпоновщикНастроек, ДанныеРасшифровки, СтруктураВнешнихДанных = Неопределено) Экспорт КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных(); Настройки = КомпоновщикНастроек.ПолучитьНастройки(); МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки); ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных(); ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки, СтруктураВнешнихДанных, ДанныеРасшифровки); ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент(); ПроцессорВывода.УстановитьДокумент(ДокументРезультат); ПроцессорВывода.НачатьВывод(); Пока Истина Цикл ЭлементРезультата = ПроцессорКомпоновкиДанных.Следующий(); Если ЭлементРезультата = Неопределено Тогда Прервать; Иначе ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата); КонецЕсли; КонецЦикла; ПроцессорВывода.ЗакончитьВывод(); КонецФункции
На это я трачу час времени, иногда ошибаясь, но в итоге получив этот код.
Но потом я думаю — а почему бы не получать данные из отчета «Доходы и расходы предприятия» по сохраненному варианту под выгрузку в таблицу значений? И так можно собрать данные из нескольких отчетов, что более универсально. Эта тема искушает меня и я начинаю ее реализовывать.
В итоге получилось довольно быстро, еще за час.
На этот раз целиком заменяю событие при компоновке:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) //Осипов - выводим и все - вставтлять когда настройки отчета получены в алгоритме СобственныйВыводОтчета(ДанныеРасшифровки, ДокументРезультат); СтандартнаяОбработка = Ложь; Возврат; ... КонецПроцедуры
В принципе, можно было бы использовать шаблон внешнего отчета с периодом, по сути там важны только параметры (я использую только период, т.к. организация одна, но можно добавить еще и организацию).
Я делаю вариант отчета — плоский, для выгрузки в ТЗ:
Записи без группировок, поэтому их много. К сожалению, в этом отчете нельзя добавить поле Период в группировку, поэтому получить свернутый плоский отчет нельзя.
Ну а сам код довольно простой:
- Нахожу нужный вариант отчета, получаю из него настройки.
- Получаю нужную схему компоновки из макета отчета. Тут важно, что иногда 1С подменяет текст запроса, что и произошло в данном случае.
- Устанавливаю из текущих настроек период в сохраненном варианте. Тут важно, что в текущих настройках период хранится в пользовательских настройках.
- Ну а далее все штатно — вывожу в таблицу значений и дальше как в прошлом случае.
Процедура СобственныйВыводОтчета(ДанныеРасшифровки, ДокументРезультат) //Текущие настройки отчета НастройкиОтчета = КомпоновщикНастроек.ПолучитьНастройки(); //Получаем сохраненные настройки ДопСхемаКомпоновкиДанных = Отчеты.АнализДоходовРасходов.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных"); //Важно! Скопировано из типового отчета - текст запроса подменяется ДопСхемаКомпоновкиДанных.НаборыДанных.ДоходыИРасходы.Элементы.Расходы.Запрос = ТекстЗапросаРасходы(); ДопВариант = Справочники.ВариантыОтчетов.НайтиПоНаименованию("Доходы и расходы предприятия для ТЗ"); ДопНастройки = ДопВариант.Настройки.Получить(); //Важно! Период хранится в пользовательских настройках ТекПараметрПериод = НайтиПользовательскийПараметр(КомпоновщикНастроек, Новый ПараметрКомпоновкиДанных("Период")); ДопПараметр = ДопНастройки.ПараметрыДанных.Элементы.Найти("Период"); ДопПараметр.Использование = Истина; ДопПараметр.Значение.ДатаНачала = ТекПараметрПериод.Значение.ДатаНачала; ДопПараметр.Значение.ДатаОкончания = ТекПараметрПериод.Значение.ДатаОкончания; КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; МакетКомпоновки = КомпоновщикМакета.Выполнить(ДопСхемаКомпоновкиДанных, ДопНастройки, ДанныеРасшифровки,, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений")); ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных; ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина); ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений; //Осипов ТЗИсх = Новый ТаблицаЗначений; ПроцессорВывода.НачатьВывод(); ПроцессорВывода.УстановитьОбъект(ТЗИсх); ТЗИсх = ПроцессорВывода.Вывести(ПроцессорКомпоновки); ТЗИсх.Свернуть("ПериодМесяц,СтандартныйРаздел,СтатьяДоходовРасходов", "ПрибыльУбыток"); //СтандартныйРаздел СтатьяДоходовРасходов ПериодМесяц ПрибыльУбыток ТЗ = Новый ТаблицаЗначений(); ТЗ.Колонки.Добавить("Показатель"); ТЗ.Колонки.Добавить("Статья"); ТЗ.Колонки.Добавить("Период"); ТЗ.Колонки.Добавить("Значение"); Для Каждого Строка ИЗ ТЗИсх Цикл НСтр = ТЗ.Добавить(); НСтр.Период = Строка.ПериодМесяц; НСтр.Показатель = Строка.СтандартныйРаздел; НСтр.Статья = Строка.СтатьяДоходовРасходов; НСтр.Значение = Строка.ПрибыльУбыток; КонецЦикла; СхемаКомпоновкиДоп = ПолучитьМакет("PL"); КомпоновщикНастроекДоп = Новый КомпоновщикНастроекКомпоновкиДанных(); КомпоновщикНастроекДоп.ЗагрузитьНастройки(СхемаКомпоновкиДоп.НастройкиПоУмолчанию); ДанныеРасшифровкиДоп = Неопределено; СтруктураВнешнихДанных = Новый Структура("ТЗ", ТЗ); ВывестиОтчетВСКД(ДокументРезультат, СхемаКомпоновкиДоп, КомпоновщикНастроекДоп, ДанныеРасшифровкиДоп, СтруктураВнешнихДанных); КонецПроцедуры
Таким образом, можно использовать данные нескольких отчетов, не повторяя их код.
Среда 11.4.13.46. Платформа 8.3.19.1723 Объем 2 час.
Свежие комментарии