К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как программно создать элемент формы в 1С

Как программно создать элемент формы в 1С: добавление полей, кнопок и команд через Элементы.Добавить, примеры кода, типичные ошибки и проверка результата.

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

В управляемых формах для этого используется коллекция Элементы и метод Элементы.Добавить(), а для отображения данных дополнительно создаются реквизиты формы через ИзменитьРеквизиты(). В обычных формах (толстый клиент, старые конфигурации) механика похожая, но коллекция называется ЭлементыФормы.

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

Когда элемент нужно создавать программно, а когда — в конфигураторе

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

Типичные ситуации: форма настроек с произвольным списком параметров, динамические отборы, вывод колонок по данным таблицы значений, конструкторы отчётов, мастера с переменным числом шагов. Ещё один частый случай — добавление полей во внешней обработке, где нет возможности править основную конфигурацию.

Программный подход имеет цену: код создания элементов выполняется при каждом открытии формы, его сложнее отлаживать, а ошибки проявляются только в runtime. Поэтому правило простое — если элемент можно нарисовать в конфигураторе, рисуйте его там.

Маршрут решения

Как выбрать подход

Состав полей известен заранее и не меняетсяСоздавайте элементы в редакторе формы конфигуратора
Набор полей зависит от данных или настроек пользователяСоздавайте элементы программно в ПриСозданииНаСервере
Нужно изменить типовую форму без доработки конфигурацииИспользуйте расширение конфигурации или внешнюю обработку с программным добавлением

Добавление реквизита формы перед созданием элемента

Элемент формы — это только «витрина». Полю ввода нужен источник данных: реквизит формы, реквизит объекта или колонка таблицы. Если подходящего реквизита нет, его создают программно методом ИзменитьРеквизиты(), доступным на сервере.

Метод принимает два массива: добавляемые и удаляемые реквизиты. Каждый новый реквизит описывается объектом Новый РеквизитФормы(Имя, ОписаниеТипов, Путь, Заголовок, СохраняемыеДанные). Вызов возможен только в серверном контексте, обычно в обработчике ПриСозданииНаСервере.

// Добавление строкового реквизита формы

МассивДобавляемых = Новый Массив;

ОписаниеТипа = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(100));

НовыйРеквизит = Новый РеквизитФормы("КомментарийДинамический", ОписаниеТипа, "", "Комментарий", Ложь);

МассивДобавляемых.Добавить(НовыйРеквизит);

ИзменитьРеквизиты(МассивДобавляемых);

После успешного вызова реквизит доступен как свойство формы: ЭтаФорма.КомментарийДинамический. Попытка добавить реквизит с именем, которое уже существует, вызовет исключение — перед добавлением проверяйте наличие или формируйте уникальные имена.

Создание поля ввода в управляемой форме

Базовый вызов выглядит так: Элементы.Добавить(Имя, Тип, Родитель). Имя должно быть уникальным в пределах формы, тип для поля ввода — Тип("ПолеФормы"), родитель — группа или сама форма. Если родителя не указать, элемент попадёт в корень формы.

// Создание поля ввода, связанного с реквизитом

НовыйЭлемент = Элементы.Добавить("ПолеКомментарий", Тип("ПолеФормы"), Элементы.ГруппаОсновная);

НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;

НовыйЭлемент.ПутьКДанным = "КомментарийДинамический";

НовыйЭлемент.Заголовок = "Комментарий";

НовыйЭлемент.КнопкаОчистки = Истина;

Ключевое свойство — ПутьКДанным. Без корректного пути поле отобразится, но не будет связано с данными: введённое значение никуда не сохранится. Путь указывается строкой относительно данных формы, например "Объект.Наименование" для реквизита объекта или просто имя реквизита формы.

Вид поля определяет поведение: ПолеВвода — универсальный вариант, ПолеНадписи — только отображение, ПолеФлажка — для булевых значений, ПолеПереключателя — для выбора одного значения из списка. Для поля ввода дополнительно настраиваются КнопкаВыбора, КнопкаСпискаВыбора, Маска и другие свойства.

bsl
НовыйЭлемент = Элементы.Добавить("ПолеСогласие", Тип("ПолеФормы"));
НовыйЭлемент.Вид = ВидПоляФормы.ПолеФлажка;
НовыйЭлемент.ПутьКДанным = "СогласиеНаОбработку";
НовыйЭлемент.Заголовок = "Согласен с условиями";

Создание кнопки и команды формы

Кнопка отличается от поля тем, что ей нужна команда. Сначала программно создаётся команда формы через коллекцию Команды, затем сама кнопка, у которой свойство ИмяКоманды указывает на созданную команду.

// Команда

НоваяКоманда = Команды.Добавить("КомандаОбновить");

НоваяКоманда.Действие = "Подключаемый_ОбновитьДанные";

НоваяКоманда.Заголовок = "Обновить";

// Кнопка

НоваяКнопка = Элементы.Добавить("КнопкаОбновить", Тип("КнопкаФормы"), Элементы.ГруппаКнопок);

НоваяКнопка.ИмяКоманды = "КомандаОбновить";

НоваяКнопка.Заголовок = "Обновить";

Свойство Действие команды содержит имя процедуры в модуле формы. Такая процедура должна существовать на момент компиляции модуля — создать обработчик полностью динамически нельзя. Обычно в модуле заранее объявляют универсальную процедуру-обработчик, которая по имени команды определяет, что делать.

&НаКлиенте

Процедура Подключаемый_ОбновитьДанные(Команда)

// Общая логика для всех динамических кнопок

ОбновитьДанныеНаСервере();

КонецПроцедуры

Создание групп и управление иерархией элементов

Группы нужны для компоновки: без них все динамические элементы выстроятся в один столбец в корне формы. Группа создаётся тем же методом Элементы.Добавить с типом Тип("ГруппаФормы") и видом ВидГруппыФормы.ОбычнаяГруппа.

НоваяГруппа = Элементы.Добавить("ГруппаПараметры", Тип("ГруппаФормы"));

НоваяГруппа.Вид = ВидГруппыФормы.ОбычнаяГруппа;

НоваяГруппа.Группировка = ГруппировкаПодчиненныхЭлементовФормы.Горизонтальная;

НоваяГруппа.ОтображатьЗаголовок = Ложь;

Свойство Группировка определяет, как размещаются дочерние элементы: вертикально, горизонтально или с переносом. Для страниц используется вид Страницы и вложенные группы с видом Страница. Добавляя поле, передавайте группу третьим параметром в Элементы.Добавить — так иерархия формируется сразу, без последующего перемещения.

Если элемент нужно вставить перед конкретным соседом, а не в конец группы, используйте метод Элементы.Вставить(Имя, Тип, Родитель, ПередЭлементом). Это важно, когда динамическое поле должно стоять между статическими элементами, созданными в конфигураторе.

Создание элементов в обычных формах

В обычных формах (режим обычного приложения, старые конфигурации на платформе 8.2–8.3) синтаксис отличается. Коллекция называется ЭлементыФормы, а тип элемента задаётся значением перечисления ТипЭлементаФормы, а не объектом Тип.

// Обычная форма: поле ввода

НовоеПоле = ЭлементыФормы.Добавить(Тип("ПолеВвода"), "ПолеКомментарий", Истина);

НовоеПоле.Данные = "Комментарий";

НовоеПоле.Верх = 10;

НовоеПоле.Лево = 100;

НовоеПоле.Ширина = 300;

НовоеПоле.Высота = 19;

Принципиальное отличие — привязка к данным через свойство Данные (имя реквизита строкой) и ручное позиционирование через координаты Верх, Лево, Ширина, Высота. Автоматической компоновки, как в управляемых формах, здесь нет, поэтому координаты приходится рассчитывать самостоятельно.

Для кнопок в обычных формах обработчик назначается через УстановитьДействие("Нажатие", Новый Действие("ИмяПроцедуры")). Механизм команд формы в обычном режиме отсутствует.

Управляемые и обычные формы

Управляемая форма

Элементы.Добавить(Имя, Тип("ПолеФормы"), Родитель), связь через ПутьКДанным, автоматическая компоновка. Рекомендуемый вариант для всех современных конфигураций.

Обычная форма

ЭлементыФормы.Добавить(Тип, Имя, Видимость), связь через Данные, ручные координаты. Только для конфигураций, работающих в режиме обычного приложения.

Проверка результата и типичные ошибки

После внедрения кода откройте форму в режиме предприятия и проверьте: элемент виден, связан с данными (ввод сохраняется в реквизит), кнопки вызывают обработчики, компоновка не «разваливается» при изменении размера окна. Полезно также открыть форму под пользователем с ограниченными правами — доступность реквизитов может отличаться.

Большинство проблем возникает из-за небольшого набора повторяющихся ошибок. Их легко диагностировать по тексту исключения или по поведению формы.

Типичные ошибки
01
Добавление элемента с уже существующим именем — исключение при открытии формы; проверяйте уникальность или используйте префиксы
02
ПутьКДанным указывает на несуществующий реквизит — поле отображается, но не сохраняет значение; сначала вызовите ИзменитьРеквизиты
03
Вызов ИзменитьРеквизиты на клиенте — ошибка выполнения; переносите код в серверный обработчик
04
Процедура из свойства Действие команды не объявлена в модуле — форма не открывается с ошибкой компиляции
05
Элемент добавлен без родителя и потерялся в корне формы — всегда передавайте группу-родителя третьим параметром
Контрольные точки

Как проверить результат

Отображение элемента
Норма

Элемент виден в нужной группе, заголовок корректный

Тревожный признак

Элемент не виден — проверьте родителя и свойство Видимость

Связь с данными
Норма

Введённое значение доступно в реквизите формы

Тревожный признак

Поле очищается или не связано — проверьте ПутьКДанным

Работа кнопки
Норма

Нажатие вызывает процедуру-обработчик

Тревожный признак

Ошибка о ненайденном обработчике — проверьте Действие команды

Ограничения и частые вопросы

Программно созданные элементы существуют только в рамках текущего сеанса работы формы. При повторном открытии код создания выполняется заново — это нормально, но означает, что тяжёлые операции в ПриСозданииНаСервере замедлят каждое открытие. Дополнительные реквизиты формы не сохраняются в базе данных автоматически: если значения нужно хранить, записывайте их в объект, регистр или хранилище настроек самостоятельно.

Ещё одно ограничение — динамическое создание элементов недоступно для некоторых системных частей формы: нельзя программно заменить командную панель табличного документа или изменить состав стандартных команд. Для таких задач используются расширения конфигурации.

Итог

Что важно запомнить

Динамический элемент создаётся в три шага: при необходимости добавьте реквизит через ИзменитьРеквизиты на сервере, создайте элемент через Элементы.Добавить с указанием родителя, свяжите его с данными через ПутьКДанным. Для кнопок дополнительно создайте команду и заранее объявите процедуру-обработчик в модуле формы.

Можно ли создать элемент формы на клиенте?

Нет. Добавление элементов и реквизитов формы выполняется только в серверном контексте, обычно в обработчике ПриСозданииНаСервере. На клиенте можно менять свойства уже существующих элементов: видимость, доступность, заголовок, цвет.

Как удалить программно созданный элемент?

Используйте метод Элементы.Удалить(Элемент) или Элементы.Удалить(Элементы["Имя"]). Учтите, что удалить можно только программно добавленные элементы; элементы, созданные в конфигураторе, удаляются через расширение формы или скрываются установкой Видимость = Ложь.

Как создать таблицу значений на форме программно?

Сначала добавьте реквизит формы типа ТаблицаЗначений и реквизиты-колонки с путём, равным имени таблицы, через ИзменитьРеквизиты. Затем создайте элемент с типом Тип("ТаблицаФормы"), укажите ПутьКДанным на реквизит и добавьте дочерние поля-колонки с путями вида "ИмяТаблицы.ИмяКолонки".

Почему поле видно, но введённые данные пропадают?

Чаще всего не задано или неверно указано свойство ПутьКДанным — поле не связано с реквизитом. Проверьте, что реквизит с таким именем существует в данных формы и что путь записан без опечаток, включая префикс "Объект." для реквизитов основного объекта.

Можно ли добавить элемент на форму другой конфигурации через расширение?

Да. В расширении конфигурации форма заимствуется, и в её модуле доступны те же методы Элементы.Добавить и ИзменитьРеквизиты. Это штатный способ доработки типовых форм без изменения основной конфигурации.

Как задать обработчик изменения для динамического поля?

Через метод УстановитьДействие: НовыйЭлемент.УстановитьДействие("ПриИзменении", "Подключаемый_ПриИзменении"). Процедура с указанным именем должна быть заранее объявлена в модуле формы с директивой &НаКлиенте и параметром Элемент.