Решение задач 1С:Предприятие 8 на примерах

Элементы формы 1С: программное добавление на управляемую форму

Управляемые формыОпубликовано

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

Задача: добавить элемент на форму без конфигуратора

Управляемые формы 1С строятся из набора элементов, реквизитов и команд, которые обычно задаёт разработчик в конфигураторе. Но бывает, что состав формы нельзя определить заранее: набор полей зависит от настроек пользователя, количество кнопок — от справочника, а доработка типовой формы делается в расширении, где проще не править форму, а дополнить её кодом. Тогда элементы формы 1С создают программно.

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

Из чего состоит управляемая форма

Сначала различим три сущности, с которыми работает код формы:

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

В примерах ниже ГруппаШапка и ГруппаКоманды — условные имена групп, которые уже есть на форме; подставьте свои.

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

Добавление реквизита и поля формы

Реквизиты добавляются пакетом через массив объектов РеквизитФормы. Вызов ИзменитьРеквизиты() перестраивает форму, поэтому его делают один раз, собрав все реквизиты в массив. Конструктор принимает имя, описание типов, путь к родителю (для колонок таблиц), заголовок и признак сохраняемых данных.

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

    // 1. Реквизит формы
    ТипСтрока = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(200));

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

    // 2. Поле формы, связанное с реквизитом
    Поле = Элементы.Добавить("ДопКомментарий", Тип("ПолеФормы"), Элементы.ГруппаШапка);
    Поле.Вид = ВидПоляФормы.ПолеВвода;
    Поле.ПутьКДанным = "ДопКомментарий";
    Поле.Заголовок = "Доп. комментарий";
    Поле.УстановитьДействие("ПриИзменении", "ДопКомментарийПриИзменении");

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

&НаКлиенте
Процедура ДопКомментарийПриИзменении(Элемент)
    // Реакция на ввод значения
КонецПроцедуры

Третий параметр Элементы.Добавить() — родитель: группа формы или другой контейнер. Если его не указать, элемент встанет в корень формы. Чтобы вставить элемент не в конец, а перед существующим, используйте Элементы.Переместить(Элемент, Родитель, ПередЭлементом).

Вид поля определяет перечисление ВидПоляФормы. Самые используемые значения: ПолеВвода, ПолеФлажка, ПолеНадписи, ПолеПереключателя, ПолеКартинки. Для выбора из списка задают РежимВыбораИзСписка = Истина и наполняют СписокВыбора.

Обработчик события подключают методом УстановитьДействие(Событие, ИмяПроцедуры). Процедура должна быть в модуле формы и выполняться на клиенте — отсюда обязательная директива &НаКлиенте. Если директива пропущена или процедура объявлена как серверная, событие не сработает, а платформа сообщит, что обработчик не найден или недоступен.

Группы формы и порядок размещения

Чтобы расположить несколько полей рядом или под общим заголовком, создают группу. Тип элемента — ГруппаФормы, а характер группы задаёт ВидГруппыФормы: ОбычнаяГруппа, ГруппаКнопок, КоманднаяПанель, Страницы, Страница. Расположение вложенных элементов определяет свойство Группировка.

Группа = Элементы.Добавить("ГруппаДоп", Тип("ГруппаФормы"), Элементы.ГруппаШапка);
Группа.Вид = ВидГруппыФормы.ОбычнаяГруппа;
Группа.Группировка = ГруппировкаПодчиненныхЭлементовФормы.Горизонтальная;
Группа.ОтображатьЗаголовок = Ложь;

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

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

Команды и кнопки на форме

Кнопка на форме состоит из двух частей: команды и элемента КнопкаФормы, который показывает команду. Сначала добавляется команда с обработчиком, затем кнопка, у которой в ИмяКоманды указано имя этой команды.

&НаСервере
Процедура ДобавитьКнопку()

    Команда = Команды.Добавить("ДопДействие");
    Команда.Заголовок = "Выполнить";
    Команда.Действие = "ДопДействиеВыполнить";

    Кнопка = Элементы.Добавить("КнопкаДопДействие", Тип("КнопкаФормы"), Элементы.ГруппаКоманды);
    Кнопка.Вид = ВидКнопкиФормы.ОбычнаяКнопка;
    Кнопка.ИмяКоманды = "ДопДействие";

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

&НаКлиенте
Процедура ДопДействиеВыполнить(Команда)
    ПоказатьПредупреждение(, "Команда выполнена");
КонецПроцедуры

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

Динамическая таблица значений и колонки

Если количество полей заранее неизвестно, на форму выводят таблицу, колонки которой создаются в цикле. Для этого добавляют реквизит типа ТаблицаЗначений, затем реквизиты-колонки с указанием родителя, затем таблицу и её поля. О том, как строится сама таблица значений, подробно рассказано в статье Таблица значений в 1С.

&НаСервере
Процедура СоздатьТаблицуНаФорме(ИменаКолонок)

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

    Таблица = Элементы.Добавить("СписокДанных", Тип("ТаблицаФормы"), Элементы);
    Таблица.ПутьКДанным = "СписокДанных";

    Для Каждого ИмяКолонки Из ИменаКолонок Цикл
        Колонка = Элементы.Добавить("СписокДанных" + ИмяКолонки, Тип("ПолеФормы"), Таблица);
        Колонка.Вид = ВидПоляФормы.ПолеВвода;
        Колонка.ПутьКДанным = "СписокДанных." + ИмяКолонки;
    КонецЦикла;

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

Строки в такую таблицу добавляют как в реквизит формы: СписокДанных.Добавить() или присваиванием ЗначениеВРеквизитФормы(), если данные собраны в обычной таблице значений.

Видимость, доступность и «только просмотр»

Для существующих и созданных элементов поведение задаётся обычными свойствами, к которым обращаются через Элементы:

Элементы.ДопКомментарий.Видимость = Ложь;             // скрыть
Элементы.ДопКомментарий.Доступность = Ложь;           // затемнить, нельзя редактировать
Элементы.ДопКомментарий.ТолькоПросмотр = Истина;      // виден, но не редактируется
Элементы.ДопКомментарий.ЦветТекста = WebЦвета.Серый;
Элементы.КнопкаДопДействие.Видимость = ЗначениеПустое(Объект.Контрагент);

Чем отличаются свойства. Видимость убирает элемент с формы целиком. Доступность оставляет элемент на форме, но «выключенным»: значение не изменить, сфокусироваться на нём нельзя. ТолькоПросмотр разрешает копировать значение и выглядит как поле ввода без возможности редактирования. Для видимости элемента формы 1С, которая зависит от данных, свойство задают на сервере при открытии и обновляют в обработчиках изменения, а для оформления строк и ячеек в таблицах лучше использовать условное оформление — оно не требует кода.

Как удалить элементы и реквизиты

Удалить можно только то, что создано программно. Порядок обратный созданию: сначала элементы, потом реквизиты, на которые они ссылались.

&НаСервере
Процедура УдалитьДопЭлементы()

    Элементы.Удалить(Элементы.ДопКомментарий);

    УдаляемыеРеквизиты = Новый Массив;
    УдаляемыеРеквизиты.Добавить("ДопКомментарий");
    ИзменитьРеквизиты(, УдаляемыеРеквизиты);

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

Элементы и реквизиты, созданные в конфигураторе или в расширении, программно не удаляются: для них достаточно скрыть элемент. Если форма принадлежит расширению, действуют те же правила; о самих расширениях рассказано в статье Расширение конфигурации 1С.

Доработка типовой формы кодом

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

&НаСервере
&После("ПриСозданииНаСервере")
Процедура Расш1_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

    Реквизиты = Новый Массив;
    Реквизиты.Добавить(Новый РеквизитФормы("Расш1_Примечание", Новый ОписаниеТипов("Строка")));
    ИзменитьРеквизиты(Реквизиты);

    Поле = Элементы.Добавить("Расш1_Примечание", Тип("ПолеФормы"), Элементы.ГруппаШапка);
    Поле.Вид = ВидПоляФормы.ПолеВвода;
    Поле.ПутьКДанным = "Расш1_Примечание";

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

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

Типичные ошибки

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

Актуальность для новых версий

Методы Элементы.Добавить(), Команды.Добавить() и ИзменитьРеквизиты() есть во всех релизах 8.3 для управляемого приложения. Набор свойств отдельных элементов (например, расширенные возможности оформления и вид групп) расширялся от версии к версии; если какое-то свойство не найдено, проверьте платформу и режим совместимости конфигурации. В обычных формах эти методы не применяются.

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

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

Сначала добавьте реквизит формы через ИзменитьРеквизиты() с массивом РеквизитФормы, затем создайте элемент вызовом Элементы.Добавить(Имя, Тип("ПолеФормы"), Родитель) и задайте ему ПутьКДанным.

Как подключить обработчик к созданному элементу?

Вызовите УстановитьДействие("ПриИзменении", "ИмяПроцедуры") у элемента. Процедура должна быть в модуле формы и иметь директиву &НаКлиенте, иначе событие не сработает.

Чем отличаются Видимость, Доступность и ТолькоПросмотр?

Видимость скрывает элемент, Доступность отключает его и затемняет, ТолькоПросмотр оставляет значение читаемым и копируемым, но запрещает редактирование.

Можно ли удалить элемент, созданный в конфигураторе?

Нет. Элементы.Удалить() и удаление реквизитов через ИзменитьРеквизиты() работают только с тем, что создано программно. Остальное можно скрыть свойством Видимость.

Как открыть форму в управляемом приложении 1С и обработать результат после закрытия

Управляемые формы

Шесть типовых сценариев открытия управляемой формы в 1С: новый объект, создание на основании, существующий документ, форма выбора и получение результата после закрытия через ОписаниеОповещения.

Условное оформление элементов формы программным способом

Управляемые формы

Шесть примеров программного условного оформления в управляемой форме 1С: цвет поля по значению, сравнение двух реквизитов, оформление строк динамического списка и условие по текущей дате.

Как программно установить параметры выбора для формы выбора объекта

Управляемые формы

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

Как запретить редактирование всех элементов формы, кроме некоторых

Управляемые формы

Свойство ТолькоПросмотр блокирует всю форму целиком. Приводим рекурсивную процедуру, которая запрещает редактирование всех элементов управляемой формы, оставляя доступными только нужные.