Как запретить пользователям переносить элементы справочника из группы в группу в 1С 8.3?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Часто в практической работе возникает ситуация, когда пользователи случайно или намеренно переносят элементы справочника (например, номенклатуру или контрагентов) из одной папки в другую. Это приводит к путанице в структуре каталогов и ошибкам в отчетах. Разберем, можно ли ограничить такое действие только настройками прав и какие программные инструменты 1С позволяют надежно заблокировать перемещение элементов.

Почему задачу нельзя решить только типовыми правами (ролями и RLS)?

Платформенный механизм прав доступа и ограничение на уровне записей (RLS) проверяют условия над текущим состоянием данных в момент их чтения или записи. Они не могут сопоставить новое записываемое значение реквизита с его предыдущим состоянием в базе данных. По этой причине запретить изменение только одного реквизита Родитель исключительно с помощью стандартной настройки ролей и профилей групп доступа без написания программного кода невозможно.

Если полностью отключить право изменения справочника, пользователи потеряют возможность редактировать любые реквизиты элемента или создавать новые позиции. Поэтому для гибкого контроля применяются программные методы.

Способ 1. Проверка изменения родителя в событии «ПередЗаписью» (серверный контроль)

Рассмотрим самый надежный способ блокировки, который защищает от переноса при любых действиях пользователя: интерактивном перетаскивании (Drag-and-Drop), использовании команды «Переместить в группу», групповом изменении реквизитов или записи через внешние обработки.

Для реализации проверки создадим подписку на событие ПередЗаписью для нужных справочников или добавим код в модуль объекта справочника. При этом создавать вспомогательные реквизиты не требуется: мы можем напрямую сравнить текущего родителя объекта со значением, которое уже сохранено в базе данных по ссылке Ссылка.Родитель.

Разберем по шагам логику обработчика:

  1. Проверяем, что объект не является новым с помощью метода ЭтоНовый() (для новых элементов родитель устанавливается впервые).
  2. Сравниваем текущее значение реквизита Родитель со значением в базе данных: Ссылка.Родитель.
  3. Проверяем наличие у текущего пользователя специальной роли с помощью функции РольДоступна().
  4. Если родитель был изменен, а прав у пользователя нет, устанавливаем Отказ = Истина и выводим понятное сообщение об ошибке.

Посмотрим на пример реализации в общем модуле для подписки на событие:


Процедура ЗапретПереносаЭлементовПередЗаписью(Источник, Отказ) Экспорт
    
    // Пропускаем проверку для новых объектов и при обмене данными
    Если Источник.ОбменДанными.Загрузка Или Источник.ЭтоНовый() Тогда
        Возврат;
    КонецЕсли;
    
    // Проверяем, изменился ли родитель
    Если Источник.Родитель <> Источник.Ссылка.Родитель Тогда
        
        // Разрешаем операцию только пользователям с полными правами
        Если НЕ РольДоступна("ПолныеПрава") И НЕ РольДоступна("АдминистраторСистемы") Тогда
            Отказ = Истина;
            ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
                "У вас нет прав на перемещение элементов между группами!",
                Источник,
                "Родитель"
            );
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

Способ 2. Интерфейсная защита от случайного перетаскивания (Drag-and-Drop)

Если требуется защитить справочник от случайных действий пользователей мышью в списке, можно ограничить интерактивное перетаскивание на уровне формы списка или формы выбора.

Рассмотрим варианты интерфейсной настройки:

  1. Отключение свойств таблицы: В свойствах элемента формы (таблицы динамического списка) можно снять флаги РазрешитьПеретаскивание и РазрешитьНачалоПеретаскивания.
  2. Перехват событий формы: В обработчиках таблицы ПроверкаПеретаскивания и Перетаскивание можно установить СтандартнаяОбработка = Ложь. Это позволяет программно анализировать роль пользователя и разрешать перетаскивание только администраторам.
  3. Скрытие стандартных команд: В командной панели и контекстном меню таблицы динамического списка можно скрыть стандартную кнопку «Переместить в группу».

Посмотрим на пример обработки события перетаскивания в модуле формы списка:


&НаКлиенте
Процедура СписокПроверкаПеретаскивания(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Поле)
    
    // Блокируем стандартную обработку перетаскивания для обычных пользователей
    Если НЕ РазрешеноПеремещениеСервер() Тогда
        СтандартнаяОбработка = Ложь;
        ПараметрыПеретаскивания.Действие = ДействиеПеретаскивания.Недоступно;
    КонецЕсли;
    
КонецПроцедуры

&НаСервере
Функция РазрешеноПеремещениеСервер()
    Возврат РольДоступна("ПолныеПрава");
КонецФункции

Способ 3. Реализация через расширение конфигурации

Чтобы не снимать типовую конфигурацию с поддержки, проверку перед записью или перехват событий формы рекомендуется реализовывать с помощью механизма расширений конфигурации. Для этого достаточно добавить расширение, подключить к нему нужный справочник и переопределить обработчик ПередЗаписью с аннотацией &Перед или &Вместо.

Аудит и контроль переноса элементов

Если элементы уже были перемещены и требуется выяснить автора изменений, используем встроенные средства аудита:

  1. Подсистема «Версионирование объектов» (БСП): При включенном версионировании справочника можно открыть историю версий объекта и увидеть, какой именно пользователь, когда и из какой папки перенес элемент.
  2. Журнал регистрации: В журнале регистрации по событию «Данные. Изменение» фиксируются факты записи объектов с указанием имени пользователя и времени транзакции.
← На главную