Возможно ли создать управляемую форму в 1С полностью программно?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Ограничения платформы и базовый подход

Сразу ответим на главный вопрос: создать форму абсолютно «с нуля» в оперативной памяти (включая генерацию ее программного модуля) платформенными средствами 1С невозможно. Платформа 1С:Предприятие имеет жесткую структуру метаданных, и модуль формы из встроенного языка программно менять нельзя.

Однако мы можем максимально приблизиться к этому результату. Рассмотрим подробнее рабочий метод: мы берем за основу заранее созданную пустую форму (например, общую форму в конфигурации или форму из расширения) и полностью наполняем ее программно. В принципе, можно также получить любую существующую форму, программно удалить все ее элементы, добавить нужные и отобразить пользователю.

Строгая последовательность создания интерфейса

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

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

Посмотрим на пример базового кода для реализации этого подхода:


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

// Применяем реквизиты к форме
ИзменитьРеквизиты(МассивРеквизитов);

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

Назначение обработчиков событий для динамических элементов

Разберем по шагам одну из самых больших сложностей — обработку событий. Если мы создали элемент программно, как заставить его реагировать на действия пользователя? Для этого в 1С существует метод УстановитьДействие().

С его помощью мы можем программно привязать событие к элементу. Например:


НовыйЭлемент.УстановитьДействие("ПриИзменении", "Подключаемый_ПриИзменении");

Важное ограничение: Сама процедура-обработчик (в нашем примере Подключаемый_ПриИзменении) уже должна физически существовать в модуле формы. Сгенерировать текст процедуры «на лету» и заставить платформу его выполнить нельзя.

Поэтому на практике разработчики используют универсальные процедуры-маршрутизаторы. Мы создаем в модуле пустой формы одну универсальную процедуру, которая принимает вызов от любого динамического элемента, а затем перенаправляет его в клиентский общий модуль. Посмотрим на пример такой маршрутизации:


// В модуле формы
&НаКлиенте
Процедура Подключаемый_ПриИзменении(Элемент)
    // Передаем контекст в общий модуль
    МойОбщийМодульКлиент.ОбработатьИзменениеЭлемента(ЭтаФорма, Элемент);
КонецПроцедуры

// В общем модуле "МойОбщийМодульКлиент"
&НаКлиенте
Процедура ОбработатьИзменениеЭлемента(Форма, Элемент) Экспорт
    Если Элемент.Имя = "ДинамическоеПоле" Тогда
        // Логика обработки
    ИначеЕсли Элемент.Имя = "ДругоеПоле" Тогда
        // Иная логика
    КонецЕсли;
КонецПроцедуры

Производительность и целесообразность подхода

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

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

Основное и самое оправданное применение программного создания элементов — это доработка типовых конфигураций через расширения. Добавление реквизитов и элементов кодом (вместо визуального изменения типовой формы) исключает конфликты при обновлениях и позволяет использовать внешние программы для трехстороннего сравнения кода.

← На главную