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