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