Динамическое добавление полей и ресурсов в отчет на СКД

11.06.25

Разработка - СКД

Добавляем поля в отчет на СКД при формировании. Используем объекты системы компоновки данных и схему запроса.

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Динамические добавление полей и ресурсов в отчет:
.erf 8,43Kb
0
0 Скачать (1 SM) Купить за 1 850 руб.

Предисловие

Недавно у меня возникла необходимость во-первых, формировать отчет программно, во-вторых, добавлять в него колонки по итогам получения данных.  Наверняка для многих не составляет сложности сформировать такой отчет, да к тому же многие потребности покрываются возможностью выводить группируемые поля в колонки (мне не подошло). Несмотря на многолетний опыт, с такой задачей столкнулся впервые, поэтому покажу как делал. К сожалению, осмысленного примера не придумал, поэтому будет такой, сверху донизу искусственный.

Если видите ошибки, или как сделать лучше - обязательно пишите комментарии.

 

Постановка задачи

Написать отчет, который выводит для заданного диапазона целых чисел их степени от 2 до указанной.

 

Архитектура решения

Будем делать внешний отчет (для конфигурации на базе БСП) с единственным набором данных - запрос (не потому что это нужно, а потому что это я хочу показать)

 

Реализация

Предварительная настройка

Собственно, создаем внешний отчет, добавляем в него положенные области, чтобы потомки радовались.

Добавляем сведения, чтобы отчет работал в БСП:

#Область ПрограммныйИнтерфейс

Функция СведенияОВнешнейОбработке() Экспорт
	
	ВерсияБСП = СтандартныеПодсистемыСервер.ВерсияБиблиотеки();
	ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке(ВерсияБСП);
	ПараметрыРегистрации.Информация = Метаданные().Синоним;
	ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиДополнительныйОтчет();
	ПараметрыРегистрации.БезопасныйРежим = Ложь;
	ПараметрыРегистрации.Версия = "2025.06.10";
	
	Команда = ПараметрыРегистрации.Команды.Добавить();
	Команда.Представление = ПараметрыРегистрации.Информация;
	Команда.Идентификатор = Метаданные().Имя;
	Команда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыОткрытиеФормы();
	Команда.ПоказыватьОповещение = Истина;
	
	Возврат ПараметрыРегистрации;
	
КонецФункции

Процедура ОпределитьНастройкиФормы(Форма, КлючВарианта, Настройки) Экспорт
КонецПроцедуры
#КонецОбласти

Процедура ОпределитьНастройкиФормы() сразу добавлена для того, чтобы не попадать лишний раз в исключение при отладке - она вызывается общей формой отчета. Но в любом случае она нам понадобится позже.

Теперь создадим макет СКД и вручную добавим параметры, которые будет задавать пользователь - НачальноеЧислоКонечноеЧисло и МаксимальнаяСтепень (тип Число), зададим разумное ограничение размера - чтобы пользователь не баловался - я поставил 3 знака для чисел и 1 для степени. Можем сразу задать пользовательские значения - для отладки.

Можем сразу написать запрос (а кстати, где подсветка запроса 1С?):

ВЫБРАТЬ
	ВЫРАЗИТЬ(Данные.Число КАК Число) КАК Число
ИЗ
	Данные КАК Данные

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

Добавляем обработчик ПриКомпоновкеРезультата() с какой-то валидацией, пишем простой алгоритм (он нам нужен просто для примера).

#Область ОбработчикиСобытий

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

#КонецОбласти

Добиваемся работоспособности отчета:

 

 

Сразу добавляем оптимизацию: СтрШаблон() вместо конкатенации кэширование имен колонок.

Также лучше сразу перенести код в отдельную функцию, а параметры данных, полученные из СКД, сохранить в глобальные переменные - нет смысла их передавать в виде аргумента в функцию, если эта функция - метод самого отчета.

 

Доработка отчета до конечного вида

Отчет у нас есть, данные мы получили, осталось вывести эти данные в этот отчет. Для этого нам понадобится изменить текст запроса набора данных, добавить новые поля в сам макет СКД, а потом вывести эти поля в вариант отчета. Если добавленные поля будут ресурсами, то нужно добавить ещё и ресурсы.

Для изменения текста запроса воспользуемся объектом СхемаЗапроса, для добавления полей в структуру отчета объектом НастройкиКомпоновкиДанных, а собственно текст запроса нужно править в самом объекте СхемаКомпоновкиДанных:

#Область СлужебныеПроцедурыИФункции

Функция НастройкиКомпоновкиСУчетомДанных()
	
	Схема = Новый СхемаЗапроса;
	Схема.УстановитьТекстЗапроса(СхемаКомпоновкиДанных.НаборыДанных.НаборДанных1.Запрос);
	// у нас простой запрос, поэтому просто получаем последний оператор:
	ЗапросСхемы = Схема.ПакетЗапросов[Схема.ПакетЗапросов.Количество() - 1];
	ОператорВыбрать = ЗапросСхемы.Операторы[ЗапросСхемы.Операторы.Количество() - 1];
	Источник = ОператорВыбрать.Источники[0].Источник;
	
	Для к = 2 По МаксимальнаяСтепень Цикл
		ИмяКолонки = ИменаКолонок.Получить(к);
		Источник.ДоступныеПоля.Добавить(ИмяКолонки);
		ОператорВыбрать.ВыбираемыеПоля.Добавить(СтрШаблон("ВЫРАЗИТЬ(%1 КАК ЧИСЛО(10))", ИмяКолонки));
		ЗапросСхемы.Колонки[ЗапросСхемы.Колонки.Количество() - 1].Псевдоним = ИмяКолонки;
		
		// добавим само поле в набор данных СКД:
		ПолеСКД1 = СхемаКомпоновкиДанных.НаборыДанных.НаборДанных1.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
		ПолеСКД1.Поле = ИмяКолонки;
		ПолеСКД1.ПутьКДанным = ИмяКолонки;
		ПолеСКД1.Заголовок = ИмяКолонки; // можно задать красивый заголовок
		
		// и ресурс:
		ПолеИтога1 = СхемаКомпоновкиДанных.ПоляИтога.Добавить();
		ПолеИтога1.Выражение = СтрШаблон("СУММА(%1)", ИмяКолонки);
		ПолеИтога1.ПутьКДанным = ИмяКолонки;
	КонецЦикла;
	
	// вернем доработанный запрос в СКД:
	СхемаКомпоновкиДанных.НаборыДанных.НаборДанных1.Запрос = Схема.ПолучитьТекстЗапроса();
	
	// теперь нужно переинициализировать настройки и добавить наши новые поля:
	КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных));
	НастройкиКомпоновки = КомпоновщикНастроек.ПолучитьНастройки();
	
	// также для примера добавим для новых полей условное оформление:
	УсловноеОформление = НастройкиКомпоновки.УсловноеОформление.Элементы.Добавить();
	
	Для к = 2 По МаксимальнаяСтепень Цикл
		ИмяКолонки = ИменаКолонок.Получить(к);
		
		ВыбранноеПолеКомпоновкиДанных = НастройкиКомпоновки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
		ВыбранноеПолеКомпоновкиДанных.Использование = Истина;
		ВыбранноеПолеКомпоновкиДанных.Поле = Новый ПолеКомпоновкиДанных(ИмяКолонки);
		
		ПолеУсловногоОформления = УсловноеОформление.Поля.Элементы.Добавить();
		ПолеУсловногоОформления.Использование = Истина;
		ПолеУсловногоОформления.Поле = Новый ПолеКомпоновкиДанных(ИмяКолонки);
	КонецЦикла;
	
	УсловноеОформление.Оформление.УстановитьЗначениеПараметра(Новый ПараметрКомпоновкиДанных("МинимальнаяШирина"), 10);
	УсловноеОформление.Оформление.УстановитьЗначениеПараметра(Новый ПараметрКомпоновкиДанных("Формат"), "ЧДЦ=2");
	УсловноеОформление.Использование = Истина;
	
	Возврат НастройкиКомпоновки;
	
КонецФункции

#КонецОбласти

Вот и всё, отчет работает, условное оформление тоже, ресурсы считаются:

 

 

Есть недостаток с точки зрения пользователя: так как макет СКД мы изменили уже при формировании, то пользователь никак не может повлиять на наши добавленные поля - он их просто не видит. В качестве какого-то компромисса можно добавлять поля в группу полей, которую пользователь сможет скрывать и двигать в настройках, хотя это, конечно, не совсем очевидно.

Вот и всё, надеюсь, кто-нибудь воспользуется этим как шпаргалкой, и потратит чуть меньше времени, чем потратил я)

 

P.S. В процессе обратил внимание на забавный факт: то, что мы в настройках СКД видим как "ресурсы", называется на самом деле "поля итога", а "поле" - это "путь к данным". Так что традиция запутывать пользователей несоответствием имени и синонима, оказывается, идет еще от разработчиков платформы.

Проверено на следующих конфигурациях и релизах:

  • 1С:Библиотека стандартных подсистем, редакция 3.1, релизы 3.1.9.209

СКД Схема запроса Отчет

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Руководитель проекта Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

15500 руб.

02.09.2020    192456    1064    405    

992

СКД Программист Платформа 1С v8.3 Система компоновки данных Бесплатно (free)

Хорошая отчетная форма - сродни искусству. Есть какое-то невероятное эстетическое удовольствие в том, чтобы разобраться в логике учета и анализируемых показателях, спроектировать архитектуру хранения данных так, чтобы оптимально собрать эти показатели вместе с аналитическими разрезами в запросе, а затем настроить отображение так, чтобы, глядя на результат, сразу было понятно, что это за отчет и какие задачи он призван решать. Система компоновки данных - это моя первая, главная и, наверное, единственная "рабочая" любовь. Ее я использую везде, где только можно и где нельзя тоже. Хочу поделиться с вами некоторыми практическими приемами в работе с отчетами на СКД, которые, надеюсь, будут полезны.

27.02.2025    10868    ovetgana    50    

89

СКД Программист Платформа 1С v8.3 Система компоновки данных Бесплатно (free)

СКД – инструмент, на базе которого в современных конфигурациях реализованы практически все отчеты. СКД используется в динамических списках, печатных формах и универсальных механизмах. Если построить простейший отчет может каждый разработчик, то с нюансами знакомы далеко не все. Расскажем о неочевидных на первый взгляд приемах, способных значительно повысить качество отчетов.

24.12.2024    8142    Akcium    13    

45

Запросы СКД Программист Стажер Система компоновки данных Россия Бесплатно (free)

Часто при разработке отчетов в СКД возникает ситуация, когда не совсем понятно, почему отчет выводит не те данные, которые нужны, либо не выводит вовсе. Возникает потребность увидеть конечный запрос, который формирует СКД. Как это сделать, рассмотрим в этой статье.

15.05.2024    15010    implecs    7    

52

Инструментарий разработчика СКД Программист Платформа 1С v8.3 1C:Бухгалтерия Абонемент ($m)

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

3 стартмани

05.02.2024    9736    67    obmailok    21    

83

Запросы СКД Программист Платформа 1С v8.3 Управляемые формы 1C:Бухгалтерия Абонемент ($m)

Есть список полей в виде текста, или запрос - закидываем в набор СКД.

1 стартмани

31.01.2024    3874    7    Yashazz    2    

34

СКД WEB-интеграция Программист Платформа 1С v8.3 1C:Бухгалтерия Абонемент ($m)

Долгое время поддерживаю web-портал, в котором появилась необходимость создавать отчеты. Просмотрев различные фреймворки на js, я решил сделать свое решение, которое позволяло бы быстро разрабатывать и добавлять новые отчеты на web-портал.

2 стартмани

11.12.2023    13316    27    John_d    30    

128
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. ixijixi 2024 11.06.25 09:46 Сейчас в теме
Разрешите докопаться - любое число в нулевой степени равно единице.
2. alexey_kurdyukov 173 11.06.25 13:19 Сейчас в теме
Оставьте свое сообщение