Как в 1С разрешить выбор любого склада в документе перемещения при включенном RLS?

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

При настройке прав доступа в 1С:Предприятие часто возникает классическая дилемма: пользователю необходимо ограничить видимость остатков и документов только "его" складом, но при этом оставить возможность создавать документы Перемещение товаров, где в качестве склада-получателя может выступать любой склад компании. Если стандартный механизм RLS (Record Level Security) настроен на справочник Склады, то при попытке выбрать склад-получатель пользователь просто не увидит другие склады в списке, а в существующих документах вместо названий будет отображаться надпись "Объект не найден".

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

Причина возникновения проблемы: RLS на уровне справочника

Когда мы устанавливаем ограничение на чтение справочника Склады, платформа 1С фильтрует записи на уровне SQL-запроса. Если условие RLS не выполняется для конкретной записи, то для системы этой записи "не существует" для текущего пользователя. Это влечет за собой две основные проблемы:

  1. Невозможность выбора: В форме выбора склада или в выпадающем списке пользователь видит только разрешенные элементы.
  2. Разрыв ссылочной целостности в интерфейсе: Если документ был создан другим пользователем и в нем указан "запрещенный" склад, текущий пользователь увидит "Объект не найден", хотя ссылка в базе данных физически существует.

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

Способ 1. Перенос ограничений со справочника на регистры (Рекомендуемый)

Проанализируем стратегию настройки прав. В большинстве случаев бизнес-задача звучит так: "Пользователь не должен видеть остатки на чужих складах". Это не означает, что он не должен знать о существовании самого склада как элемента справочника.

Самый правильный и технологичный способ в типовых конфигурациях (ERP, КА, УТ) — это снять ограничение RLS со справочника Склады и перенести его на регистры накопления (например, Товары на складах, Выручка и себестоимость продаж) и документы.

Как это реализовать по шагам:

  1. В профиле групп доступа найдите роль, отвечающую за чтение складов.
  2. Убедитесь, что для справочника Склады право Чтение предоставлено без ограничений (поле RLS пустое или содержит ГДЕ ИСТИНА).
  3. Настройте RLS на регистры накопления, в которых хранятся остатки. В условии укажите ограничение по складу.
  4. Результат: пользователь сможет выбирать любой склад в документе перемещения (так как справочник доступен), но в отчетах по остаткам он увидит цифры только по своим складам.

Способ 2. Использование расширений и привилегированного режима

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

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

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


&НаКлиенте
Процедура Расш_СкладПолучательНачалоВыбораПосле(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    // Отменяем стандартное открытие формы выбора
    СтандартнаяОбработка = Ложь;
    
    // Параметры для открытия нашей формы
    ПараметрыВыбора = Новый Структура;
    ПараметрыВыбора.Вставить("РежимВыбора", Истина);
    
    // Открываем форму выбора склада, игнорируя текущий RLS
    ОткрытьФорму("Справочник.Склады.ФормаВыбора", ПараметрыВыбора, Элемент);
КонецПроцедуры

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

Способ 3. Создание роли "Чтение складов без ограничений"

В платформе 1С 8.3 права доступа суммируются по принципу ИЛИ. Если у пользователя есть две роли: одна запрещает чтение складов (RLS), а вторая разрешает чтение всех складов (без RLS), то в итоге пользователю будет разрешено чтение всех складов.

Посмотрим на алгоритм действий:

  1. Создайте в расширении (или в основной конфигурации) новую роль, назовите ее ЧтениеСкладовБезОграничений.
  2. В этой роли для справочника Склады установите право Чтение (Read) и Просмотр (View).
  3. Важно: не добавляйте в эту роль никаких условий RLS.
  4. Назначьте эту роль нужному пользователю через профиль групп доступа.

Важный нюанс: Этот способ сделает все склады видимыми во всех документах и списках. Если ваша задача — разрешить выбор только в перемещении, этот метод может быть избыточным.

Способ 4. Обработка получения данных выбора

Для того чтобы пользователь мог вводить название склада в поле ввода и система находила его (автоподбор), можно использовать механизм ОбработкаПолученияДанныхВыбора в модуле менеджера справочника Склады. Это позволяет переопределить стандартный поиск 1С.

Рассмотрим пример кода в модуле менеджера:


Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)
    
    // Если нам нужно обойти RLS только в конкретных случаях
    Если Параметры.Свойство("ОбойтиRLS") И Параметры.ОбойтиRLS Тогда
        СтандартнаяОбработка = Ложь;
        УстановитьПривилегированныйРежим(Истина);
        
        // Выполняем запрос к справочнику без учета прав
        Запрос = Новый Запрос;
        Запрос.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ Ссылка, Наименование ИЗ Справочник.Склады ГДЕ Наименование ПОДОБНО &Текст";
        Запрос.УстановитьПараметр("Текст", Параметры.СтрокаПоиска + "%");
        
        // Формируем таблицу результатов
        ДанныеВыбора = Новый СписокЗначений;
        Выборка = Запрос.Выполнить().Выбрать();
        Пока Выборка.Следующий() Цикл
            ДанныеВыбора.Добавить(Выборка.Ссылка, Выборка.Наименование);
        КонецЦикла;
    КонецЕсли;
    
КонецПроцедуры

Как избежать надписи "Объект не найден"?

Проанализируем ситуацию: даже если вы позволили пользователю выбрать склад с помощью кода, после записи документа он может увидеть "Объект не найден" в поле склада-получателя. Это происходит потому, что право Просмотр (View) все еще ограничено RLS.

Чтобы название склада отображалось корректно, у пользователя обязательно должно быть право Чтение (Read) на этот объект. Если вы используете жесткий RLS на чтение, 1С физически не может получить представление объекта из базы.

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

Резюме и рекомендации

Подводя итог, выберем оптимальный путь решения проблемы в зависимости от ситуации:

  1. Если вы работаете в типовой конфигурации (ERP, КА, УТ), лучше всего перенести RLS на регистры. Это штатное поведение системы, которое не ломает логику программы и не требует написания сложного кода.
  2. Если требуется точечное решение только для одного документа, используйте расширение формы с переопределением события НачалоВыбора и программным открытием формы в привилегированном режиме.
  3. Всегда проверяйте, чтобы у пользователя было право на базовое Чтение справочника, иначе вы неизбежно столкнетесь с проблемой "Объект не найден".

Выбор конкретного метода зависит от требований безопасности вашей организации, но с точки зрения архитектуры 1С, первый способ является наиболее предпочтительным и "чистым".

← На главную