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