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

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

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

Как программно добавить реквизит и поле на управляемую форму 1С: код для Добавить() и ИзменитьРеквизиты, примеры, ошибки и проверка результата.

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

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

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

Как устроено программное изменение формы

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

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

Полный пример: добавляем поле ввода на форму

Ниже минимальный рабочий код, который добавляет строковое поле «Комментарий» на форму произвольного объекта или обработки. Код размещается в модуле формы.

&НаСервере

Процедура ДобавитьПолеНаСервере()

// 1. Описываем новый реквизит формы

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

ОписаниеТипа = Новый ОписаниеТипов("Строка", ,

Новый КвалификаторыСтроки(150));

НовыйРеквизит = Новый РеквизитФормы(

"ПолеКомментарий", // имя реквизита

ОписаниеТипа, // тип

"", // путь (пусто — реквизит верхнего уровня)

"Комментарий", // заголовок

Ложь); // не сохраняемые данные

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

// 2. Применяем изменение состава реквизитов

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

// 3. Добавляем элемент формы и связываем с реквизитом

НовыйЭлемент = Элементы.Добавить("ПолеКомментарий",

Тип("ПолеФормы"));

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

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

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

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

После выполнения процедуры на форме появится редактируемое поле. Значение доступно в коде как ЭтаФорма.ПолеКомментарий или просто ПолеКомментарий внутри модуля формы.

Порядок действий
  1. 1
    Создайте описание типа через Новый ОписаниеТипов
  2. 2
    Сформируйте массив с Новый РеквизитФормы
  3. 3
    Вызовите ИзменитьРеквизиты на сервере
  4. 4
    Добавьте элемент через Элементы.Добавить
  5. 5
    Задайте элементу Вид и ПутьКДанным
  6. 6
    Проверьте форму в режиме предприятия

Как разместить поле в нужной группе и позиции

Метод Элементы.Добавить() принимает третьим параметром родителя — группу формы. Если родитель не указан, элемент попадёт в корень формы, что часто ломает задуманную компоновку. Чтобы положить поле в конкретную группу, передайте её так:

НовыйЭлемент = Элементы.Добавить("ПолеКомментарий",

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

Четвёртым параметром можно передать элемент, перед которым нужно вставить новое поле. Это удобно, когда порядок полей важен: например, новое поле должно стоять сразу после поля «Дата». Если такого элемента нет, платформа выдаст ошибку, поэтому перед вставкой на конкретную позицию проверяйте существование якорного элемента через Элементы.Найти().

Учтите, что группа-родитель должна существовать на форме к моменту выполнения кода. Если форма создаётся полностью программно, сначала добавьте группу с типом ГруппаФормы и видом ВидГруппыФормы.ОбычнаяГруппа, а уже в неё помещайте поля.

Добавление полей других типов

Флажок и поле даты

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

Поле со ссылкой на справочник

Чтобы пользователь мог выбирать значение из справочника, задайте составной или ссылочный тип:

МассивТипов = Новый Массив;

МассивТипов.Добавить(Тип("СправочникСсылка.Номенклатура"));

ОписаниеТипа = Новый ОписаниеТипов(МассивТипов);

После связывания с таким реквизитом поле ввода автоматически получит кнопку выбора и будет открывать форму списка соответствующего справочника. Дополнительная настройка кнопок выбора обычно не требуется.

Декоративная надпись

Если нужно просто показать текст без редактирования, добавьте элемент с видом ВидПоляФормы.ПолеНадписи. Для него реквизит можно не создавать, если текст статичен — достаточно задать Заголовок. Для изменяемого текста реквизит всё равно нужен.

Сравнение подходов

Реквизит + элемент программно

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

Дополнительные реквизиты (БСП)

Поля добавляются пользователем без доработки кода в типовых конфигурациях на базе БСП. Минус: меньше гибкости по размещению.

Изменение формы в конфигураторе

Просто и надёжно для постоянных полей. Минус: требует обновления конфигурации и усложняет поддержку типовых.

Когда выполнять код и как он живёт во времени

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

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

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

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

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

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

Если Элементы.Найти("ПолеКомментарий") <> Неопределено Тогда

Возврат; // поле уже добавлено

КонецЕсли;

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

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

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

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

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

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

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

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

Поле видно в нужной группе с заданным заголовком

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

Поля нет или оно в корне формы — проверьте родителя и вызов процедуры

Редактирование
Норма

Значение вводится и читается из кода формы

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

Поле недоступно или не хранит ввод — не создан реквизит

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

Форма открывается без ошибок, поле появляется снова

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

Ошибка дубля реквизита — добавьте проверку существования

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

Можно ли программно добавить поле на обычную (неуправляемую) форму?

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

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

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

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

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

Почему добавленное поле не сохраняет значение после записи документа?

Программно добавленный реквизит формы не связан с данными объекта в базе. Чтобы значение сохранялось, в обработчике ПередЗаписью или ПриЗаписи переносите его в реальный реквизит объекта, дополнительное свойство или регистр сведений.

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

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

Итог

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

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