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