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

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

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

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

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

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

Важно понимать ограничение: изменять состав реквизитов можно только на сервере и только до того, как форма начала отображаться пользователю. Оптимальное место — обработчик ПриСозданииНаСервере. Попытка вызвать ИзменитьРеквизиты() на клиенте приведёт к ошибке выполнения.

Как работает метод ИзменитьРеквизиты

Метод ИзменитьРеквизиты(Добавляемые, Удаляемые) принимает два массива объектов типа ОписаниеРеквизитаФормы. Первый массив — реквизиты для добавления, второй — для удаления. Оба параметра необязательны: если нужно только добавить, второй массив можно не передавать.

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

bsl
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	ДобавляемыеРеквизиты = Новый Массив;
	ОписаниеТипа = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(150));
	ДобавляемыеРеквизиты.Добавить(Новый ОписаниеРеквизитаФормы("КомментарийДинамический", ОписаниеТипа, , "Комментарий"));
	ИзменитьРеквизиты(ДобавляемыеРеквизиты);
КонецПроцедуры

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

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

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

Связь с данными задаётся через свойство ПутьКДанным, куда записывается имя реквизита строкой. Для поля ввода дополнительно устанавливают Вид = ВидПоляФормы.ПолеВвода. Без корректного ПутьКДанным элемент отобразится, но не будет связан с реквизитом и выдаст ошибку при открытии формы.

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

Имя элемента может совпадать с именем реквизита — платформа это допускает, и такая практика упрощает сопровождение кода. Если элементов много, стоит формировать имена по шаблону с префиксом, чтобы не пересечься с существующими элементами формы.

Добавление колонки в таблицу значений на форме

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

Порядок действий для колонки таблицы
  1. 1
    Создайте описание реквизита-колонки, указав в параметре Путь имя таблицы значений
  2. 2
    Вызовите ИзменитьРеквизиты с массивом добавляемых колонок
  3. 3
    Добавьте элемент формы типа ПолеФормы с родителем — элементом таблицы
  4. 4
    Установите ПутьКДанным в формате ИмяТаблицы.ИмяКолонки
  5. 5
    Проверьте отображение, заполнив таблицу тестовыми данными

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

Условия и ограничения программного изменения формы

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

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

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

Типичные ошибки и как их избежать

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

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

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

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

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

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

Состав реквизитов формы
Норма

ПолучитьРеквизиты() возвращает новый реквизит в списке

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

Реквизита нет — проверьте, что массив описаний не пуст и вызов на сервере

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

Поле видно в нужной группе и доступно для ввода

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

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

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

Введённое значение читается из ЭтаФорма.ИмяРеквизита

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

Ошибка «Поле не найдено» — опечатка в ПутьКДанным

При отладке удобно временно добавить в конец ПриСозданииНаСервере цикл по ПолучитьРеквизиты() с выводом имён — это сразу покажет, создался ли реквизит и с каким именем. После отладки такой код удаляют, чтобы не засорять журнал.

Когда программное добавление не нужно

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

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

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

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

Компромиссный вариант — добавить в конфигураторе реквизит-таблицу значений с универсальными колонками (например, «ИмяПоля», «Значение») и заполнять её динамически. Это убирает необходимость в ИзменитьРеквизиты() и упрощает форму, хотя визуально менее гибко.

Итог

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

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

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

Можно ли программно удалить реквизит формы?

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

Почему форма выдаёт ошибку «Поле не найдено» после добавления элемента?

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

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

Да, в ОписаниеТипов перечислите нужные типы через запятую в строке, например «СправочникСсылка.Номенклатура,СправочникСсылка.Контрагенты». Платформа корректно отобразит поле ввода с выбором типа. Учтите, что квалификаторы (длина строки, точность числа) задаются отдельными объектами квалификаторов.

Сохраняются ли значения динамических реквизитов при закрытии формы?

Нет, значения живут только в рамках текущего экземпляра формы. Если данные нужно сохранить, запишите их в базу (в объект, регистр сведений или хранилище настроек) в обработчике записи или при закрытии, а при следующем открытии прочитайте и заполните заново.

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

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