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