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