При разработке на платформе 1С:Предприятие 8.3 (управляемые формы) часто возникают задачи, когда состав формы должен меняться динамически в зависимости от прав пользователя, настроек программы или данных конкретного документа. Одной из базовых задач является программное создание реквизита типа Булево и вывод его на форму в виде флажка. Разберем этот процесс подробно, пройдя по всем этапам: от создания структуры данных до обработки действий пользователя.
Прежде чем приступать к коду, проанализируем важный нюанс архитектуры 1С. Управляемая форма состоит из двух независимых, но связанных уровней:
Нельзя просто добавить флажок на форму, не создав для него «контейнер» в данных. Если вы добавите элемент формы без привязки к реквизиту, он будет бесполезен, так как ему негде будет хранить свое состояние.
Для добавления нового реквизита используется метод ИзменитьРеквизиты. Рассмотрим процедуру, которую необходимо выполнять в контексте &НаСервере, например, в обработчике ПриСозданииНаСервере.
&НаСервере
Процедура ДобавитьРеквизитНаФорму()
// 1. Создаем массив для новых реквизитов
ДобавляемыеРеквизиты = Новый Массив;
// 2. Описываем тип данных. В нашем случае это Булево
ОписаниеТиповБулево = Новый ОписаниеТипов("Булево");
// 3. Создаем объект "РеквизитФормы"
// Параметры: Имя, Тип, Путь, Заголовок, СохраняемыеДанные
НовыйРеквизит = Новый РеквизитФормы("ФлагТехОсмотра", ОписаниеТиповБулево, , "Пройден техосмотр", Истина);
// 4. Добавляем в массив
ДобавляемыеРеквизиты.Добавить(НовыйРеквизит);
// 5. Применяем изменения к форме
ЭтаФорма.ИзменитьРеквизиты(ДобавляемыеРеквизиты);
КонецПроцедуры
Важный момент по оптимизации: Метод ИзменитьРеквизиты является ресурсоемким, так как вызывает перегенерацию всей структуры формы. Если вам нужно добавить 10 реквизитов, никогда не вызывайте метод в цикле. Сначала соберите все реквизиты в один массив и вызовите метод один раз. Для удобного описания большого количества реквизитов можно использовать конструктор для программной модификации управляемых форм.
Теперь, когда в структуре формы появился реквизит ФлагТехОсмотра, нам нужно создать элемент управления, который позволит пользователю менять его значение. Выясним, как связать визуальный элемент с данными через свойство ПутьКДанным.
&НаСервере
Процедура СоздатьВизуальныйЭлемент()
// Проверим, не создан ли элемент ранее (во избежание ошибок при повторном вызове)
Если Элементы.Найти("ДекоративныйФлажок") = Неопределено Тогда
// Добавляем новый элемент. Параметры: Имя, Тип, Родитель (куда поместить)
// Если родитель не указан, элемент попадет в корень формы
НовЭлемент = Элементы.Добавить("ДекоративныйФлажок", Тип("ПолеФормы"), ЭтаФорма);
// Указываем, что это будет именно флажок
НовЭлемент.Вид = ВидПоляФормы.ПолеФлажка;
// Связываем элемент с созданным ранее реквизитом
НовЭлемент.ПутьКДанным = "ФлагТехОсмотра";
НовЭлемент.Заголовок = "Статус проверки";
НовЭлемент.Видимость = Истина;
КонецЕсли;
КонецПроцедуры
Часто возникает вопрос: как поместить созданный элемент не просто «вниз формы», а в конкретную группу или панель? Проанализируем ситуацию с командной панелью.
Ограничение: В стандартную Командную панель формы (ту, где обычно кнопки "Записать" и "Провести") нельзя напрямую поместить поле ввода или флажок. Платформа 1С позволяет размещать там только кнопки.
Решение: Если вам нужно визуально расположить флажок рядом с кнопками, создайте обычную группу с видом Группа - Горизонтальная или Группа - Группа кнопок, и уже в неё добавляйте и кнопки, и ваш флажок.
// Пример добавления в конкретную группу
ГруппаНаФорме = Элементы.ГруппаПодробности; // Ссылка на существующую группу
НовЭлемент = Элементы.Добавить("МойФлаг", Тип("ПолеФормы"), ГруппаНаФорме);
Если нужно переместить элемент в определенную позицию внутри группы (например, первым в списке), используйте метод Переместить:
Элементы.Переместить(НовЭлемент, ГруппаНаФорме, Элементы.НужныйСоседнийЭлемент);
Чтобы программа реагировала на нажатие флажка пользователем, необходимо назначить обработчик события ПриИзменении. Рассмотрим, как это сделать программно.
&НаКлиенте.УстановитьДействие.
&НаКлиенте
Процедура МойОбработчикПриИзменении(Элемент)
// Элемент - это программно созданное поле, которое вызвало событие
Сообщить("Значение изменено на: " + ЭтаФорма[Элемент.ПутьКДанным]);
КонецПроцедуры
&НаСервере
Процедура ПривязатьДействиеКЭлементу(НовЭлемент)
// Указываем имя события и имя процедуры-обработчика строкой
НовЭлемент.УстановитьДействие("ПриИзменении", "МойОбработчикПриИзменении");
КонецПроцедуры
Проанализируем критически важную деталь: динамически созданные реквизиты формы не сохраняются автоматически в базе данных. Как только пользователь закроет форму, значение флажка исчезнет.
Для сохранения состояния можно использовать следующие подходы:
ЭтаФорма.ФлагТехОсмотра и записывать в дополнительные реквизиты объекта.ХранилищеОбщихНастроек, чтобы восстанавливать значение при открытии формы.Соберем все части кода в единую рабочую процедуру, которую можно разместить в модуле управляемой формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// 1. Добавление данных
МассивРеквизитов = Новый Массив;
МассивРеквизитов.Добавить(Новый РеквизитФормы("ПрограммныйФлаг", Новый ОписаниеТипов("Булево")));
ИзменитьРеквизиты(МассивРеквизитов);
// 2. Добавление в интерфейс
// Поместим флаг в существующую группу "ГруппаШапка"
Родитель = Элементы.Найти("ГруппаШапка");
Если Родитель = Неопределено Тогда
Родитель = ЭтаФорма;
КонецЕсли;
НовоеПоле = Элементы.Добавить("ПолеПрограммныйФлаг", Тип("ПолеФормы"), Родитель);
НовоеПоле.Вид = ВидПоляФормы.ПолеФлажка;
НовоеПоле.ПутьКДанным = "ПрограммныйФлаг";
НовоеПоле.Заголовок = "Активировать спецрежим";
// 3. Установка события
НовоеПоле.УстановитьДействие("ПриИзменении", "ПрограммныйФлагПриИзменении");
КонецПроцедуры
&НаКлиенте
Процедура ПрограммныйФлагПриИзменении(Элемент)
Если ПрограммныйФлаг Тогда
ПоказатьПредупреждение(, "Специальный режим активирован!");
КонецЕсли;
КонецПроцедуры
Рассмотренный метод позволяет гибко управлять интерфейсом. Главное — помнить о разделении реквизитов и элементов, а также о том, что тяжелые операции по изменению структуры формы должны выполняться на сервере минимальное количество раз. Для изучения готового практического решения подойдёт обработка с примером динамического создания и удаления элементов на форме.