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