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