Как программно управлять видимостью полей на управляемой форме 1С 8.3

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

При разработке в системе 1С:Предприятие 8.3 на управляемых формах (особенно в крупных конфигурациях, таких как ERP 2.4 или КА 2.0) часто возникает задача динамического изменения интерфейса без прямого вмешательства в типовые формы. Один из распространенных сценариев — программное добавление поля ввода и управление его видимостью в зависимости от значения другого реквизита. Рассмотрим, почему стандартные подходы могут не работать и как правильно реализовать эту логику.

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

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

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

Решение 1: Прямое управление свойством Видимость

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

Рассмотрим пример кода, который добавляет поле и сразу устанавливает его видимость в зависимости от значения другого реквизита:


Процедура ПриСозданииНаСервере(Форма, Отказ, СтандартнаяОбработка) Экспорт

    // Проверяем контекст нужной формы
    Если Форма.ИмяФормы = "Документ.ЗаданиеНаПеревозку.Форма.ФормаДокумента" Тогда
        
        // 1. Программное создание элемента
        ИмяЭлемента = "рар_Договор";
        Родитель = Форма.Элементы.ГруппаПраво;
        НовыйЭлемент = Форма.Элементы.Вставить(ИмяЭлемента, Тип("ПолеФормы"), Родитель);
        НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
        НовыйЭлемент.ПутьКДанным = "Объект.Договор";
        
        // 2. Установка начальной видимости
        // Предположим, поле должно быть видно, только если исполнителем является Перевозчик
        НужныйТип = Перечисления.ТипыИсполнителейЗаданийНаПеревозку.Перевозчик;
        НовыйЭлемент.Видимость = (Форма.Объект.ЗаданиеВыполняет = НужныйТип);
        
    КонецЕсли;

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

Этот код отлично сработает при открытии документа, но как только пользователь изменит значение в поле ЗаданиеВыполняет, наше новое поле рар_Договор не исчезнет и не появится автоматически. Для этого нам нужна динамика.

Решение 2: Обеспечение динамической видимости через события

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

Здесь есть два пути:

  1. Использование расширений: Это наиболее правильный метод для ERP. Мы создаем расширение, находим нужную форму и добавляем в её модуль процедуру-обработчик для поля ЗаданиеВыполняет (используя аннотацию &НаКлиенте и &После).
  2. Программная установка действия: Если по каким-то причинам расширение использовать нельзя, можно попробовать назначить обработчик программно через УстановитьДействие, но сам метод-обработчик все равно обязан физически существовать в модуле формы или быть добавлен туда через механизм расширений.

Пример кода в расширении модуля формы:


&НаКлиенте
Процедура рар_ЗаданиеВыполняетПриИзмененииПосле(Элемент)
    
    // Вызываем серверный код для обновления интерфейса
    рар_ОбновитьВидимостьПолейНаСервере();
    
КонецПроцедуры

&НаСервере
Процедура рар_ОбновитьВидимостьПолейНаСервере()
    
    ЭлементДоговор = Элементы.Найти("рар_Договор");
    Если ЭлементДоговор <> Неопределено Тогда
        НужныйТип = ПредопределенноеЗначение("Перечисление.ТипыИсполнителейЗаданийНаПеревозку.Перевозчик");
        ЭлементДоговор.Видимость = (Объект.ЗаданиеВыполняет = НужныйТип);
    КонецЕсли;
    
КонецПроцедуры

Почему элемент может быть «не виден» в отладчике

Разберем ситуацию, когда при просмотре коллекции Элементы в отладчике вы не находите свой созданный объект. Это часто происходит по двум причинам:

Использование функциональных опций

Если видимость поля зависит не от данных конкретного документа, а от настроек системы (например, «Вести учет по договорам»), то вместо написания кода лучше использовать Функциональные опции. Вы можете связать программно созданный элемент с функциональной опцией через свойство ИмяФункциональнойОпции. Платформа сама скроет поле, если опция выключена.

Резюме для разработчика

Подведем итоги нашего исследования:

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

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

← На главную