Почему программно созданные элементы формы и события не работают в клиент-серверной базе 1С?

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

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

В чем причина различий между файловым и серверным режимами?

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

Правила назначения обработчиков событий через УстановитьДействие

Проанализируем частые ошибки при динамическом назначении обработчиков событий для элементов формы:

  1. Директива компиляции процедуры-обработчика: Метод УстановитьДействие вызывается на сервере, однако сама процедура, обрабатывающая клиентское событие (например, ИзменениеТекстаРедактирования или ПриИзменении), обязана располагаться в модуле этой же управляемой формы с директивой &НаКлиенте.
  2. Точное совпадение сигнатуры: В клиент-серверном режиме любое несовпадение количества или порядка параметров процедуры приводит к тому, что платформа просто не вызывает обработчик без генерации явного исключения. Для события ИзменениеТекстаРедактирования сигнатура строго определена:
    
    &НаКлиенте
    Процедура Рекв2ИзменениеТекстаРедактирования(Элемент, Текст, СтандартнаяОбработка)
        // Логика обработки
    КонецПроцедуры
    
  3. Ограничение адресации: В управляемых формах в метод УстановитьДействие нельзя передавать вызовы процедур из общих модулей. Передается только строковое имя локальной процедуры формы.

Управление высотой и компоновкой многострочного поля

Если свойство Высота не применяется к полю ввода в интерфейсе «Такси», это связано с работой менеджера автоматической компоновки формы. Выясним, как зафиксировать требуемый размер:

  1. Управление растяжением: Для поля ввода необходимо явно указать параметры растяжения по вертикали, иначе менеджер компоновки может переопределить заданную высоту: Элемент2.РастягиватьПоВертикали = Ложь;
  2. Ограничение минимальной и максимальной высоты: Для жесткой фиксации размера используем свойства МинимальнаяВысота и МаксимальнаяВысота:
    
    Элемент2.МинимальнаяВысота = 4;
    Элемент2.МаксимальнаяВысота = 4;
    
  3. Влияние родительской группы: Если поле помещается в группу с горизонтальной ориентацией, многострочные поля по умолчанию могут сжиматься в одну строку. Убедимся, что родительская группа имеет вертикальную группировку либо корректно настроенное выравнивание.

Корректный пример программного создания реквизита и поля формы

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


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

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

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

    // 3. Назначаем обработчик клиентского события
    Элемент2.УстановитьДействие("ИзменениеТекстаРедактирования", "Рекв2ИзменениеТекстаРедактирования");

    // 4. Заполняем начальное значение реквизита
    ЭтаФорма["Рекв2"] = "тест!";

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

&НаКлиенте
Процедура Рекв2ИзменениеТекстаРедактирования(Элемент, Текст, СтандартнаяОбработка)
    // Обработка ввода текста пользователем
КонецПроцедуры

Обратим внимание: обращение к динамически созданному реквизиту надежнее выполнять через синтаксис доступа по строковому имени ЭтаФорма["Рекв2"], так как на этапе компиляции модуля данного свойства у объекта формы еще не существует.

← На главную