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

11.06.25

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

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

Файлы

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

Наименование Скачано Купить файл
Динамические добавление полей и ресурсов в отчет:
.erf 8,43Kb
5 2 500 руб. Купить

Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний

Оформите подписку на компанию для решения рабочих задач

Оформить подписку и скачать решение со скидкой

Предисловие

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

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

 

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

Написать отчет, который выводит для заданного диапазона целых чисел их степени от 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С:Предприятие 8 Платные (руб)

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

16500 руб.

02.09.2020    246481    1353    419    

1131

Инструментарий разработчика СКД Программист 1С 8.3 Бесплатно (free)

В этой статье представлен СКДБилдер — общий модуль-обёртка над объектной моделью СКД, который сокращает код в 3-4 раза и делает его читаемым.

29.01.2026    5084    286    shapa_pro    25    

66

СКД Программист 1С:Предприятие 8 Бесплатно (free)

Статья написана по результатам проведенного внутреннего обучающего вебинара для разработчиков ГК «СофтБаланс». Если осилить 25 000 знаков - задача для вас непосильная, где-то на бескрайних просторах интернета видео есть (или будет). Но здесь информация точнее. Разберем, чем запрос для СКД принципиально отличается от обычного запроса и как модифицируется в зависимости от настроек. Изучим «базовый рецепт» написания запроса для СКД, сформируем чек-лист. Полезно будет всем – от стажеров до тех. лидов. Всем, кто не снимает галку «автозаполнение» и пишет запросы для отчетов в консоли запросов – читать (вдумчиво) обязательно.

29.10.2025    15819    ovetgana    112    

105

СКД Программист 1С:Предприятие 8 Бесплатно (free)

Описан способ заполнения списка доступных значений для полей наборов данных и параметров в схеме компоновки данных для любых конфигураций (с использованием БСП или без).

01.07.2025    9221    krasnoshchekovpavel    5    

67

СКД Программист Стажер 1С:Предприятие 8 Россия Бесплатно (free)

Несколько способов управления формами выбора параметров и отборов СКД.

10.04.2025    8405    Neti    0    

41

СКД Программист 1С:Предприятие 8 Бесплатно (free)

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

27.02.2025    15560    ovetgana    50    

93

СКД Программист 1С:Предприятие 8 Бесплатно (free)

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

24.12.2024    13131    Akcium    17    

46

СКД Механизмы типовых конфигураций Запросы Программист 1С:Предприятие 8 1С:Зарплата и кадры государственного учреждения 3 1С:Зарплата и Управление Персоналом 3.x Россия Бесплатно (free)

Работая с типовыми отчетами в конфигурациях «Зарплата и управление персоналом, редакция 3», «Зарплата и кадры государственного учреждения, редакция 3» и подобных, в схемах компоновки данных можно встретить конструкции запросов, которые обращаются к некоторым виртуальным таблицам.

20.08.2024    9611    AlexeyPROSTO_1C    1    

32
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. ixijixi 2134 11.06.25 09:46 Сейчас в теме
Разрешите докопаться - любое число в нулевой степени равно единице.
2. alexey_kurdyukov 192 11.06.25 13:19 Сейчас в теме
3. artbear 1587 19.06.25 17:29 Сейчас в теме
(1) Разрешите докопаться - ноль в нулевой степени считается неопределенным значением )
4. ixijixi 2134 20.06.25 08:52 Сейчас в теме
(3) Чёрт) Не знал, кстати
Для отправки сообщения требуется регистрация/авторизация