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