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

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

Как программно добавить элемент на форму в 1С

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

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

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

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

Где и когда можно добавлять элементы программно

Добавление элементов доступно только в управляемых формах и только на сервере. Типичные точки входа: обработчик ПриСозданииНаСервере, серверная процедура, вызванная из команды формы, либо обработчик ПриПовторномОткрытии в редких сценариях. В обычных формах (толстый клиент, режим обычного приложения) применяется другой механизм — коллекция ЭлементыФормы, но этот режим давно не используется в современных конфигурациях.

Программное добавление оправдано, когда состав элементов зависит от данных: например, по каждому виду номенклатуры нужно вывести своё поле, или набор кнопок формируется из настроек пользователя. Если структура формы известна заранее, правильнее создать элементы в конфигураторе — это проще в сопровождении и не замедляет открытие формы.

Шаг 1. Создание реквизита формы

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

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

// Добавляем строковый реквизит "КомментарийДинамический"

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

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

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

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

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

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

Шаг 2. Добавление элемента на форму

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

Для поля ввода обязательно задайте вид через свойство Вид (например, ВидПоляФормы.ПолеВвода) и привязку к данным через ПутьКДанным. Без привязки поле отобразится пустым и не будет сохранять введённое значение.

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

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

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

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

Порядок элементов внутри родителя управляется методом Элементы.Переместить(Элемент, Родитель, ПередЭлементом). Это полезно, когда новый элемент нужно вставить не в конец, а в конкретную позицию — например, перед кнопкой «Записать».

Порядок действий
  1. 1
    В серверном контексте сформируйте массив реквизитов и вызовите ИзменитьРеквизиты()
  2. 2
    Добавьте элемент методом Элементы.Добавить() с указанием типа и родителя
  3. 3
    Задайте Вид, ПутьКДанным, Заголовок и другие свойства элемента
  4. 4
    При необходимости создайте команду и привяжите её к кнопке
  5. 5
    Откройте форму и проверьте отображение, ввод данных и работу обработчиков

Добавление групп, кнопок и команд

Группа как контейнер

Группы создаются тем же методом с типом Тип("ГруппаФормы") и видом ВидГруппыФормы.ОбычнаяГруппа. Группа нужна, чтобы управлять размещением нескольких динамических элементов: горизонтальной или вертикальной группировкой, отображением заголовка, поведением при сворачивании. Свойство Группировка принимает значения ГруппировкаПодчиненныхЭлементовФормы.Горизонтальная или Вертикальная.

Кнопка с командой

Кнопка без команды не выполняет никаких действий. Сначала создаётся команда методом Команды.Добавить(Имя), ей назначается свойство Действие — строка с именем обработчика в модуле формы. Затем добавляется элемент типа КнопкаФормы, которому присваивается ИмяКоманды.

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

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

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

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

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

Обработчик Подключаемый_ОбновитьДанные должен существовать в модуле формы как экспортная процедура или функция с директивой &НаКлиенте. Если обработчик отсутствует или имя указано с ошибкой, при нажатии кнопки возникнет ошибка «Процедура или функция с указанным именем не определена».

Добавление таблицы и колонок

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

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

Добавляемые.Добавить(Новый РеквизитФормы("ТоварыДинамические", Новый ОписаниеТипов("ТаблицаЗначений"), "", "Товары", Ложь));

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

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

ТаблицаЭлемент = Элементы.Добавить("ТоварыДинамические", Тип("ТаблицаФормы"));

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

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

Колонка.Вид = ВидПоляФормы.ПолеВвода;

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

Обратите внимание на путь к данным колонки: он строится через точку — имя таблицы, затем имя реквизита колонки. Ошибка в пути — самая частая причина пустых колонок и ошибок «Поле не найдено».

bsl
НовыйЭлемент = Элементы.Добавить("Поле1", Тип("ПолеФормы"));
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.ПутьКДанным = "Реквизит1";

Ограничения и типичные ошибки

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

Распространённая ошибка — попытка добавить элемент на клиенте. Платформа выдаст сообщение о недоступности метода. Вторая частая проблема — дублирование имён: если процедура добавления вызывается дважды (например, при обновлении данных формы), повторный вызов Элементы.Добавить() с тем же именем вызовет исключение. Решение — проверять существование через Элементы.Найти(Имя) и при необходимости удалять старый элемент методом Элементы.Удалить().

Третья группа ошибок связана с производительностью: многократные вызовы ИзменитьРеквизиты() в цикле заметно замедляют открытие формы. Всегда собирайте все реквизиты в один массив и вызывайте метод один раз.

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

Проверка результата

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

Для отладки полезно временно выводить в сообщение результат Элементы.Найти(Имя) после добавления: если возвращается Неопределено, элемент не создан, и нужно искать ошибку в имени или контексте выполнения.

Контрольные точки

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

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

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

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

Элемент отсутствует или попал в корень формы

Привязка к данным
Норма

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

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

Поле очищается или недоступно для ввода

Повторное открытие формы
Норма

Элементы создаются заново без ошибок

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

Исключение о дублировании имени

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

Обработчик выполняется, ошибок нет

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

Ошибка «процедура не определена»

Итог

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

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

Частые вопросы

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

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

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

Чаще всего не создан реквизит формы или в свойстве ПутьКДанным указано имя, которого нет среди реквизитов. Проверьте, что ИзменитьРеквизиты() отработал до добавления элемента, а путь к данным совпадает с именем реквизита символ в символ.

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

Методом Элементы.Удалить(Элемент) или Элементы.Удалить(Элементы.Найти("Имя")). Реквизиты формы удаляются через ИзменитьРеквизиты() — имена удаляемых реквизитов передаются во втором массиве параметров.

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

Технически элемент добавить можно, но колонки динамического списка должны быть привязаны к полям запроса списка. Добавить колонку для произвольного вычисляемого значения таким способом не получится — для этого меняется текст запроса динамического списка и настройки его полей.

Работает ли этот подход в мобильном клиенте?

Механизм Элементы.Добавить() поддерживается, но набор доступных видов элементов и свойств в мобильной платформе ограничен. Перед использованием проверяйте в синтакс-помощнике доступность конкретного свойства для мобильного клиента.

Чем программное добавление лучше изменения формы в конфигураторе?

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