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