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

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

В процессе работы с торговыми и учетными системами 1С (такими как «1С:Комплексная автоматизация», «1С:Управление торговлей» или «1С:ERP») часто возникает необходимость ограничить права пользователей на изменение иерархии справочника Номенклатура. Типовой сценарий: рядовым сотрудникам нужно разрешить просмотр товаров и их выбор в документы, но при этом строго запретить случайно или намеренно переносить позиции из одной папки в другую.

Разберем подробнее, какими способами можно решить эту задачу — от настройки типовых прав доступа до реализации программной блокировки через подписку на событие в расширении конфигурации.

Настройка типовых прав доступа

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

В современных типовых конфигурациях выбор элемента в документ доступен даже при наличии прав только на чтение. Для этого достаточно выдать пользователю профиль групп доступа с правами на просмотр номенклатуры (например, типовую роль «Только чтение») и стандартные права на создание документов. Если же сотрудникам все-таки необходимо создавать новые карточки товаров или редактировать их свойства, но запрещено менять их иерархическое расположение, потребуется добавить программный контроль.

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

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

Рассмотри по шагам алгоритм создания такой подписки:

  1. Создадим или откроем существующее расширение конфигурации.
  2. Добавим в расширение новый общий модуль (например, МойОбщийМодульСервер) и установим для него свойство «Сервер».
  3. Добавим подписку на событие, укажем в поле «Источник» тип СправочникОбъект.Номенклатура, в поле «Событие» — ПередЗаписью, а в качестве обработчика укажем процедуру из общего модуля.
  4. В процедуре-обработчике пропишем проверку факта изменения родительской группы и проверку прав текущего пользователя.

Разберем пример программного кода для процедуры-обработчика подписки:


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

КонецПроцедуры

Выясним важные детали работы этого кода:

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

Дополнительные аспекты и ограничения

Рассмотрим дополнительные нюансы, которые следует учитывать при внедрении этой логики:

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

2. Блокировка на уровне интерфейса (Drag-and-Drop): подписка на событие надежно блокирует запись на сервере, однако пользователь все равно может попытаться перетащить элемент мышью в форме списка. Чтобы повысить удобство работы и предотвратить лишние ошибки, на форме списка номенклатуры можно отключить свойство таблицы РазрешитьПеретаскивание или обработать событие ПроверкаПеретаскивания.

3. Почему нельзя использовать только RLS: механизм прав на уровне записей (RLS) в Библиотеке Стандартных Подсистем (БСП) работает по группам доступа номенклатуры, а не по иерархии папок. Кроме того, RLS разграничивает доступ к записи целиком (чтение, изменение, удаление) и не позволяет заблокировать изменение лишь одного конкретного реквизита Родитель. Поэтому использование подписки на событие остается наиболее правильным и универсальным решением.

← На главную