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