При разработке в системе 1С:Предприятие 8.3 на управляемых формах (особенно в крупных конфигурациях, таких как ERP 2.4 или КА 2.0) часто возникает задача динамического изменения интерфейса без прямого вмешательства в типовые формы. Один из распространенных сценариев — программное добавление поля ввода и управление его видимостью в зависимости от значения другого реквизита. Рассмотрим, почему стандартные подходы могут не работать и как правильно реализовать эту логику.
Многие разработчики пытаются использовать механизм УсловноеОформление формы для управления видимостью. Логика кажется верной: мы добавляем элемент оформления, указываем поле, задаем отбор и устанавливаем параметр Видимость в значение Ложь или Истина. Однако на практике для одиночных полей шапки (не в табличных частях) этот механизм часто не дает ожидаемого результата.
Проанализируем ситуацию: Условное оформление управляемой формы полноценно работает с видимостью и доступностью только для элементов, находящихся внутри коллекций (строки динамических списков или табличных частей). Для обычных полей ввода, расположенных непосредственно на форме (в «шапке»), платформа игнорирует настройки видимости из коллекции УсловноеОформление. Это не ошибка в коде, а архитектурная особенность платформы 1С.
Самый надежный способ управлять отображением элемента — прямое изменение свойства Видимость (Visibility). Поскольку элемент создается программно в общем модуле (например, в процедуре ПриСозданииНаСервере), нам нужно инициализировать его состояние при открытии формы.
Рассмотрим пример кода, который добавляет поле и сразу устанавливает его видимость в зависимости от значения другого реквизита:
Процедура ПриСозданииНаСервере(Форма, Отказ, СтандартнаяОбработка) Экспорт
// Проверяем контекст нужной формы
Если Форма.ИмяФормы = "Документ.ЗаданиеНаПеревозку.Форма.ФормаДокумента" Тогда
// 1. Программное создание элемента
ИмяЭлемента = "рар_Договор";
Родитель = Форма.Элементы.ГруппаПраво;
НовыйЭлемент = Форма.Элементы.Вставить(ИмяЭлемента, Тип("ПолеФормы"), Родитель);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.ПутьКДанным = "Объект.Договор";
// 2. Установка начальной видимости
// Предположим, поле должно быть видно, только если исполнителем является Перевозчик
НужныйТип = Перечисления.ТипыИсполнителейЗаданийНаПеревозку.Перевозчик;
НовыйЭлемент.Видимость = (Форма.Объект.ЗаданиеВыполняет = НужныйТип);
КонецЕсли;
КонецПроцедуры
Этот код отлично сработает при открытии документа, но как только пользователь изменит значение в поле ЗаданиеВыполняет, наше новое поле рар_Договор не исчезнет и не появится автоматически. Для этого нам нужна динамика.
Чтобы форма реагировала на действия пользователя «на лету», необходимо перехватить событие изменения влияющего реквизита. Выясним причину, по которой это сложно сделать в общем модуле: общий модуль выполняется на сервере, а событие ПриИзменении должно иметь клиентский обработчик в модуле формы.
Здесь есть два пути:
ЗаданиеВыполняет (используя аннотацию &НаКлиенте и &После).УстановитьДействие, но сам метод-обработчик все равно обязан физически существовать в модуле формы или быть добавлен туда через механизм расширений.Пример кода в расширении модуля формы:
&НаКлиенте
Процедура рар_ЗаданиеВыполняетПриИзмененииПосле(Элемент)
// Вызываем серверный код для обновления интерфейса
рар_ОбновитьВидимостьПолейНаСервере();
КонецПроцедуры
&НаСервере
Процедура рар_ОбновитьВидимостьПолейНаСервере()
ЭлементДоговор = Элементы.Найти("рар_Договор");
Если ЭлементДоговор <> Неопределено Тогда
НужныйТип = ПредопределенноеЗначение("Перечисление.ТипыИсполнителейЗаданийНаПеревозку.Перевозчик");
ЭлементДоговор.Видимость = (Объект.ЗаданиеВыполняет = НужныйТип);
КонецЕсли;
КонецПроцедуры
Разберем ситуацию, когда при просмотре коллекции Элементы в отладчике вы не находите свой созданный объект. Это часто происходит по двум причинам:
Форма.Элементы, но визуально в дереве переменных он находится «глубже». Всегда используйте метод Найти(), чтобы убедиться в существовании объекта.ПриСозданииНаСервере до вызова Вставить), его там еще не будет.Если видимость поля зависит не от данных конкретного документа, а от настроек системы (например, «Вести учет по договорам»), то вместо написания кода лучше использовать Функциональные опции. Вы можете связать программно созданный элемент с функциональной опцией через свойство ИмяФункциональнойОпции. Платформа сама скроет поле, если опция выключена.
Подведем итоги нашего исследования:
Видимость созданного элемента формы.Элементы.Найти("Имя"), чтобы избежать критических ошибок при обращении через точку.Соблюдение этих правил позволит вам создавать гибкие и надежные интерфейсы в 1С 8.3, сохраняя при этом чистоту кода и типовую конфигурацию без изменений (при использовании расширений).