Как программно изменить влияние функциональной опции на реквизит формы или обойти его?

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

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

Анализ проблемы: почему нельзя просто «отвязать» реквизит?

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

Посмотрим на основные сложности, с которыми мы сталкиваемся:

  1. Логическое «И»: Если реквизит привязан к нескольким ФО (например, из основной конфигурации и из расширения), система отобразит его только тогда, когда все привязанные опции примут значение «Истина».
  2. Ограничения расширений: В расширении нельзя «удалить» объект из состава существующей функциональной опции. Можно только добавить новые объекты в состав.
  3. Кэширование: Значения функциональных опций кэшируются платформой для повышения производительности, что затрудняет их мгновенное изменение «на лету» для всех пользователей.

Метод 1. Использование параметров функциональных опций формы

Если функциональная опция в конфигурации является параметризуемой (то есть ее значение зависит от какого-либо объекта, например, Организации или Склада), мы можем переопределить ее значение для конкретного экземпляра формы.

Рассмотрим, как это реализовать. В модуле формы мы используем метод УстановитьПараметрыФункциональныхОпцийФормы. Проанализируем пример кода:


&НаСервере
Процедура УстановитьСвоиПараметрыФО()
    ПараметрыФО = Новый Структура;
    // Ключ — это имя объекта метаданных "Параметр функциональной опции"
    // Значение — конкретная ссылка, для которой ФО должна быть включена
    ПараметрыФО.Вставить("Организация", Справочники.Организации.ПустаяСсылка());
    
    ЭтаФорма.УстановитьПараметрыФункциональныхОпцийФормы(ПараметрыФО);
КонецПроцедуры

Важное ограничение: Этот метод работает только для ФО, у которых в свойстве «Параметры» указан соответствующий объект метаданных. Если ФО привязана к простой константе типа «Булево», данный метод не поможет «обмануть» систему.

Метод 2. Создание дублирующего реквизита в расширении

Это самый надежный способ, когда нам нужно показать поле, скрытое системной ФО в типовой конфигурации, а метод с параметрами недоступен. Поскольку мы не можем «отвязать» оригинальный реквизит, мы создадим свой собственный, который не будет зависеть от ФО.

Разберем алгоритм по шагам:

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

Проанализируем пример реализации синхронизации в модуле формы расширения:


&НаСервере
&После("ПриЧтенииНаСервере")
Процедура мт_ПриЧтенииНаСервереПосле(ТекущийОбъект)
    // Копируем значение из скрытого реквизита объекта в наш видимый реквизит формы
    ЭтаФорма.мт_Гражданство = Объект.Гражданство;
КонецПроцедуры

&НаСервере
&Перед("ПередЗаписьюНаСервере")
Процедура мт_ПередЗаписьюНаСервереПеред(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    // Перед записью возвращаем измененное пользователем значение в объект
    ТекущийОбъект.Гражданство = ЭтаФорма.мт_Гражданство;
КонецПроцедуры

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

Метод 3. Временное изменение значения константы (Вредный совет)

Иногда встречается предложение временно менять значение константы, от которой зависит ФО, в процедуре ПриСозданииНаСервере и возвращать её обратно в ПриЗакрытии.

Мы настоятельно не рекомендуем этот метод по следующим причинам:

Метод 4. Программное управление видимостью вместо ФО

Если вы проектируете свою функциональность и сомневаетесь, использовать ли ФО для реквизитов формы, рассмотрите альтернативу — Условное оформление или программное управление свойством Видимость элементов формы.

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

Пример управления через Условное Оформление:


ЭлементОформления = УсловноеОформление.Элементы.Добавить();
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("Видимость", Истина);

ПолеОформления = ЭлементОформления.Поля.Элементы.Добавить();
ПолеОформления.Поле = Новый ПолеКомпоновкиДанных("РеквизитОбъекта");

ЭлементОтбора = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.НужноеУсловие");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = Истина;

Подведение итогов

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

← На главную