Программирование в 1С

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

Коротко

Чтобы программно добавить реквизит формы в 1С, вызовите метод формы ИзменитьРеквизиты(ДобавляемыеРеквизиты, УдаляемыеРеквизиты). В первый параметр передаётся массив объектов РеквизитФормы, которые создаются конструктором Новый РеквизитФормы(Имя, Новый ОписаниеТипов(...)). Делать это можно только на сервере и, как правило, в обработчике ПриСозданииНаСервере.

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

Как программно добавить реквизит формы: ИзменитьРеквизиты

Состав реквизитов управляемой формы меняется единственным методом — ИзменитьРеквизиты(). Он принимает массив добавляемых реквизитов и (необязательно) массив имён удаляемых. Вызов доступен только на сервере:

&НаСервере
Процедура ДобавитьРеквизитФормыНаСервере()
    ДобавляемыеРеквизиты = Новый Массив;
    ДобавляемыеРеквизиты.Добавить(
        Новый РеквизитФормы("Комментарий", Новый ОписаниеТипов("Строка"), , "Комментарий"));

    // Тяжёлая операция — вызываем один раз, когда массив полностью собран
    ИзменитьРеквизиты(ДобавляемыеРеквизиты);
КонецПроцедуры
ИзменитьРеквизиты
ДобавляемыеРеквизитымассив объектов РеквизитФормы
УдаляемыеРеквизитымассив имён ранее добавленных реквизитов
не возвращает значение

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

Конструктор РеквизитФормы: имя, тип, путь, заголовок

Каждый добавляемый реквизит формы описывается конструктором Новый РеквизитФормы(...). Обязательны только имя и тип (через ОписаниеТипов), остальные параметры необязательны:

Реквизит = Новый РеквизитФормы(
    "СуммаСкидки",                                 // Имя — без точек
    Новый ОписаниеТипов("Число", , , Новый КвалификаторыЧисла(15, 2)),
    ,                                              // Путь — для реквизита верхнего уровня пустой
    "Сумма скидки");                               // Заголовок

ДобавляемыеРеквизиты = Новый Массив;
ДобавляемыеРеквизиты.Добавить(Реквизит);
ИзменитьРеквизиты(ДобавляемыеРеквизиты);
Новый РеквизитФормы
Имяимя реквизита без точек и пути
ТипОписаниеТипов значения реквизита
Путьпуть-владелец, например "Объект.Товары"
Заголовокподпись в интерфейсе
СохраняемыеДанныепризнак сохранения значения
РеквизитФормы

Параметр Имя задаётся без точек — это имя самого реквизита. Если нужно добавить реквизит внутрь табличной части, путь к владельцу указывают в параметре Путь (например, "Объект.Товары"), а не в имени. Тип всегда описывается через Новый ОписаниеТипов(...) — как для примитивов, так и для ссылочных типов вида "СправочникСсылка.Контрагенты".

Как программно разместить реквизит на форме: Элементы.Добавить

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

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // 1. Описываем и добавляем реквизит формы
    ДобавляемыеРеквизиты = Новый Массив;
    ДобавляемыеРеквизиты.Добавить(
        Новый РеквизитФормы("Комментарий", Новый ОписаниеТипов("Строка"), , "Комментарий"));
    ИзменитьРеквизиты(ДобавляемыеРеквизиты);

    // 2. Размещаем элемент и привязываем его к реквизиту
    НовоеПоле = Элементы.Добавить("Комментарий", Тип("ПолеФормы"));
    НовоеПоле.Вид        = ВидПоляФормы.ПолеВвода;
    НовоеПоле.ПутьКДанным = "Комментарий";
КонецПроцедуры

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

// Разместить поле внутри существующей группы
НовоеПоле = Элементы.Добавить("Комментарий", Тип("ПолеФормы"), Элементы.ГруппаДопсведения);
НовоеПоле.ПутьКДанным = "Комментарий";

Реквизит формы или реквизит объекта: в чём разница

Прежде чем добавлять реквизит, определитесь, что именно вам нужно — их часто путают:

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

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

Частые ошибки при добавлении реквизита формы

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

Частые вопросы о программном добавлении реквизита формы в 1С

Где можно программно добавить реквизит формы?

Только на сервере и, как правило, в обработчике ПриСозданииНаСервере — до отображения формы. Метод ИзменитьРеквизиты() недоступен на клиенте, а вызов после открытия формы приведёт к ошибке.

Почему добавленный реквизит не виден на форме?

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

Чем реквизит формы отличается от реквизита объекта?

Реквизит формы существует только в открытой форме, не хранится в базе и добавляется программно. Реквизит объекта — часть конфигурации, хранится в базе и создаётся в конфигураторе с изменением конфигурации.