При разработке аналитических панелей или мониторов показателей в 1С часто возникает задача вывести неопределенное количество графиков на одну форму. Количество графиков может зависеть от данных в информационной базе (например, сколько активных показателей заведено в регистре сведений, столько и графиков должно отобразиться). Рассмотрим подробнее, как реализовать такую динамическую форму, разберем типичные ошибки при создании реквизитов и научимся правильно выводить данные из Системы компоновки данных (СКД) в программно созданные поля.
Разберем ситуацию, с которой часто сталкиваются начинающие разработчики. При попытке программно добавить реквизит формы через конструктор РеквизитФормы, возникает ошибка: "Недопустимое значение параметра (параметр номер '2')".
Проанализируем причину. Ошибка кроется в том, что в качестве второго параметра конструктора РеквизитФормы ожидается объект типа ОписаниеТипов, а не просто строка или ссылка на тип. Кроме того, важно понимать различие между Реквизитом формы (данными) и Элементом формы (визуальным полем). Сначала мы создаем структуру данных (реквизит), а затем привязываем к ней визуальный объект.
Для начала нам необходимо определить, сколько именно табличных документов нам потребуется, и создать их в процедуре ПриСозданииНаСервере. Мы будем использовать запрос к регистру сведений, чтобы получить список показателей, и для каждого создадим свой ТабличныйДокумент.
Выполним следующие действия в модуле формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Получаем список показателей из регистра
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| АктуальныеПоказатели.Показатель КАК Показатель
|ИЗ
| РегистрСведений.АктуальныеПоказатели КАК АктуальныеПоказатели";
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
ДобавляемыеРеквизиты = Новый Массив;
Счетчик = 1;
// Формируем массив новых реквизитов типа ТабличныйДокумент
Пока Выборка.Следующий() Цикл
ИмяРеквизита = "ТабДокПоказатель_" + Счетчик;
// Важный момент: второй параметр - это Новый ОписаниеТипов("ТабличныйДокумент")
НовыйРеквизит = Новый РеквизитФормы(ИмяРеквизита, Новый ОписаниеТипов("ТабличныйДокумент"), , Выборка.Показатель, Истина);
ДобавляемыеРеквизиты.Добавить(НовыйРеквизит);
Счетчик = Счетчик + 1;
КонецЦикла;
// Добавляем реквизиты в контекст формы
ИзменитьРеквизиты(ДобавляемыеРеквизиты);
// Теперь создаем визуальные элементы (Поля формы) для каждого реквизита
Счетчик = 1;
Для Каждого Реквизит Из ДобавляемыеРеквизиты Цикл
// Создаем поле на форме, привязываем его к родителю (например, группе "ГруппаОтчеты")
ИмяЭлемента = "Поле_" + Реквизит.Имя;
ЭлементФормы = Элементы.Добавить(ИмяЭлемента, Тип("ПолеФормы"), Элементы.ГруппаОтчеты);
ЭлементФормы.Вид = ВидПоляФормы.ПолеТабличногоДокумента;
ЭлементФормы.ПутьКДанным = Реквизит.Имя; // Связываем с созданным реквизитом
ЭлементФормы.Заголовок = Реквизит.Заголовок;
Счетчик = Счетчик + 1;
КонецЦикла;
КонецПроцедуры
В данном примере мы использовали ИзменитьРеквизиты. Обратите внимание, что эта операция является ресурсоемкой, поэтому ее рекомендуется выполнять один раз при создании формы.
Теперь, когда структура формы готова, нам нужно заполнить каждый табличный документ своим графиком. Это удобно делать по нажатию кнопки "Сформировать". Основная задача — в цикле обходить показатели, настраивать параметры СКД и выводить результат в соответствующий реквизит.
Рассмотрим код формирования на сервере:
&НаСервере
Процедура СформироватьНаСервере()
// Получаем макет отчета из конфигурации
ОтчетОбъект = Отчеты.ГрафикПоказателя.Создать();
СхемаСКД = ОтчетОбъект.СхемаКомпоновкиДанных;
Настройки = СхемаСКД.НастройкиПоУмолчанию;
// Снова получаем список показателей (или кэшируем его заранее)
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Показатель ИЗ РегистрСведений.АктуальныеПоказатели";
Выборка = Запрос.Выполнить.Выбрать();
Номер = 1;
Пока Выборка.Следующий() Цикл
ИмяРеквизита = "ТабДокПоказатель_" + Номер;
// Получаем сам объект табличного документа из реквизита формы
ТекущийТабДок = ЭтотОбъект[ИмяРеквизита];
ТекущийТабДок.Очистить(); // Обязательно очищаем перед выводом
// Устанавливаем параметр "Показатель" в настройках СКД
ПараметрСКД = Настройки.ПараметрыДанных.Элементы.Найти("Показатель");
Если ПараметрСКД <> Неопределено Тогда
ПараметрСКД.Значение = Выборка.Показатель;
ПараметрСКД.Использование = Истина;
КонецЕсли;
// Инициализируем макет компоновки
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаСКД, Настройки);
// Процессор компоновки
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
// Процессор вывода в конкретный табличный документ
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТекущийТабДок);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
// Настройка отображения графиков (опционально)
Если ТекущийТабДок.Рисунки.Количество() > 0 Тогда
Диаграмма = ТекущийТабДок.Рисунки[0]; // Предполагаем, что график - первый рисунок
// Здесь можно программно подогнать размер рисунка под область
КонецЕсли;
Номер = Номер + 1;
КонецЦикла;
КонецПроцедуры
Проанализируем ситуацию: если в базе данных окажется 50 показателей, форма будет перегружена 50-ю полями табличных документов. Это может привести к значительным задержкам в работе интерфейса (так называемым "фризам"). Чтобы этого избежать, рассмотрим несколько советов:
ГруппаСтраницы. Для каждого показателя создавайте отдельную вкладку (ГруппаСтраница) и размещайте табличный документ на ней. Это упростит восприятие информации пользователем.ТабличныйДокумент, разделяя их горизонтальными разделителями страниц. Для этого используется метод ВывестиГоризонтальныйРазделительСтраниц(). Это избавит от необходимости динамически менять структуру реквизитов формы.ТабличныйДокумент без указания размеров, он может отобразиться слишком мелким.Таким образом, мы рассмотрели полный цикл решения задачи: от программного создания реквизитов формы с правильным указанием типов данных до вывода сложных графиков через процессор компоновки. Помните, что динамическое управление формой — это мощный инструмент, который требует внимательного отношения к производительности системы.