Как ограничить выбор организации и склада в документе 1С УПП 1.3 без глобального RLS

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

При настройке прав доступа в конфигурации «Управление производственным предприятием 1.3» разработчики нередко сталкиваются с задачей: необходимо, чтобы при оформлении конкретного документа (например, ЗаказПокупателя) пользователь мог выбирать только определенные организации или склады, но при этом сохранялся общий доступ к остальным документам и справочникам. Попытка настроить ограничение на уровне записей (RLS) непосредственно на реквизит документа или форму выбора приводит к трудностям. Разберем по шагам, почему механизм RLS не подходит для точечной фильтрации выбора в одной форме и как корректно решить эту задачу программными средствами обычных форм.

Архитектурные особенности RLS и почему ограничение реквизита не работает

Проанализируем принцип работы механизма RLS (Record-Level Security) в платформе 1С:

  1. Ограничение на уровне таблиц базы данных: RLS накладывает условия на чтение, добавление, изменение или удаление строк во всей таблице (документа или справочника), а не управляет списком выбора в конкретном экранном поле.
  2. Глобальный характер прав: если ограничить доступ к справочнику Организации через RLS, пользователь перестанет видеть запрещенные организации во всей системе. В существующих документах, отчетах и регистрах вместо наименования организации платформа будет отображать <Объект не найден>, что нарушит корректное проведение документов и построение аналитики.
  3. Ограничение полей: если настроить RLS на чтение отдельного реквизита документа, платформа при чтении вернет значение NULL, что приведет к системным ошибкам при проведении и контроле заполнения.

Таким образом, если цель состоит в том, чтобы урезать доступный перечень организаций исключительно в момент интерактивного ввода в документе ЗаказПокупателя, механизм RLS использовать нельзя. Эту задачу необходимо решать на уровне интерфейса формы в сочетании с проверкой в модуле объекта.

Способ 1. Программное открытие формы выбора с установкой отбора

Рассмотрим основной способ ограничения выбора в обычных формах. Для этого переопределим стандартное поведение поля ввода при нажатии на кнопку выбора.

Откроем форму документа, перейдем в свойства элемента управления (поля ввода) Организация и назначим обработчик для события НачалоВыбора. В процедуре отключим стандартную обработку и откроем форму выбора справочника с наложенным программным отбором:


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

Обратите внимание: передача параметра Элемент в метод ПолучитьФормуВыбора назначает поле ввода владельцем формы. Благодаря этому при двойном клике по строке в открывшемся списке выбранное значение автоматически подставится в реквизит документа.

Способ 2. Использование режима выбора из выпадающего списка

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

  1. В свойствах элемента управления на форме включим флажки КнопкаСписка и РежимВыбораИзСписка.
  2. В обработчике события ПриОткрытии формы документа программно заполним свойство СписокВыбора элемента управления.

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

Защита от некорректного ввода и поиск элементов

Выясним частые ошибки, которые возникают при реализации подобной логики:

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

Обязательная проверка на уровне модуля объекта

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


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

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

← На главную