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

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

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

Анализ типичных ошибок при обращении к элементам и данным

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


// Ошибочный вариант
Элементы.ЗаКаждыйДень.Доступность = (Элементы.ВидВыплаты = Перечисления.ВидыВыплат.ПрочиеВыплаты);

Проанализируем, почему такое условие всегда будет возвращать Ложь:

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

Пошаговое решение задачи

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

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

Пример реализации на сервере

Посмотрим на пример кода серверной реализации. Вынесем логику проверки условий в отдельную процедуру модуля формы:


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

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    УстановитьДоступностьЭлементовНаСервере();
    
КонецПроцедуры

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

&НаКлиенте
Процедура СпособРасчетаПриИзменении(Элемент)
    
    УстановитьДоступностьЭлементовНаСервере();
    
КонецПроцедуры

Оптимизация: реализация логики на стороне клиента

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

Рассмотрим клиентский вариант кода:


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

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

&НаКлиенте
Процедура ВидВыплатыПриИзменении(Элемент)
    
    УстановитьДоступностьЭлементов();
    
КонецПроцедуры

Дополнительные факторы, влияющие на доступность элемента

Если код проверки написан корректно, но поле все равно остается серым или заблокированным, проанализируем сопутствующие настройки формы:

  1. Доступность родительской группы: если элемент помещен внутри группы элементов (или на странице панели), у которой установлено свойство Доступность = Ложь, дочерний элемент унаследует эту блокировку и не станет активным.
  2. Свойство формы «ТолькоПросмотр»: если для всей формы программно или платформенно выставлен режим ЭтаФорма.ТолькоПросмотр = Истина (например, при отсутствии прав на редактирование объекта у текущего пользователя), отдельные элементы редактировать не удастся.
  3. Альтернатива в виде свойства «ТолькоПросмотр» элемента: вместо отключения доступности (Доступность = Ложь), которое делает текст трудночитаемым и запрещает выделение, рекомендуется использовать Элементы.ЗаКаждыйДень.ТолькоПросмотр = Истина. Это сохраняет читаемость данных и возможность их копирования.
← На главную