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

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




