При настройке прав доступа для кладовщиков и операторов склада часто возникает типовая задача: запретить пользователю редактировать и создавать элементы справочника Номенклатура, но оставить возможность создавать новые серии для поступающих товаров. Однако при попытке программной или интерактивной записи серии номенклатуры система выдает ошибку: "У пользователя недостаточно прав на исполнение операции над базой данных".
Рассмотрим причины возникновения этой проблемы, особенности поведения платформы 1С:Предприятие в файловом и клиент-серверном режимах, а также разберем способы обхода ограничения без изменения типовой конфигурации.
Проанализируем архитектуру справочников. Справочник СерииНоменклатуры является подчиненным справочнику Номенклатура (связь по реквизиту Владелец). Когда в системе настроен механизм ограничения доступа на уровне записей (RLS) и для пользователя установлен запрет на изменение номенклатуры, платформа 1С накладывает следующие ограничения:
СерииНоменклатуры, но и на объект-владелец. Если на уровне RLS у пользователя стоит запрет на изменение родительской номенклатуры, запись подчиненной серии платформенно блокируется.УстановитьПривилегированныйРежим(Истина) в коде внешней обработки или формы толстого клиента в клиент-серверном варианте метод не срабатывает. В клиент-серверной базе он выполняется только на стороне сервера или во внешнем соединении, а на клиенте игнорируется платформой без генерации исключения.Разберем типичный алгоритм функции создания серии в обработке заполнения табличной части документа:
Функция СоздатьНовуюСерию(Номенклатура, НомерДокумента, ДатаИзготовления)
СрокГодности = Формат(ДобавитьМесяц(Дата(ДатаИзготовления + " 00:00:00"), СрокХраненияВМесяцах(Номенклатура)), "ДФ=dd.MM.yyyy");
НаименованиеСерии = НомерДокумента + ", " + СрокГодности;
СерияНоменклатуры = ПоискСерии(Номенклатура, НаименованиеСерии);
Если НЕ СерияНоменклатуры = Справочники.СерииНоменклатуры.ПустаяСсылка() Тогда
Возврат СерияНоменклатуры;
КонецЕсли;
НовыйЭлемент = Справочники.СерииНоменклатуры.СоздатьЭлемент();
НовыйЭлемент.Владелец = Номенклатура.Ссылка;
НовыйЭлемент.СерийныйНомер = НомерДокумента;
НовыйЭлемент.СрокГодности = Дата(СрокГодности + " 00:00:00");
НовыйЭлемент.Наименование = НаименованиеСерии;
// В клиентском коде клиент-серверной базы следующий вызов не отключит RLS:
УстановитьПривилегированныйРежим(Истина);
НовыйЭлемент.Записать();
УстановитьПривилегированныйРежим(Ложь);
Возврат НовыйЭлемент.Ссылка;
КонецФункции
В клиент-серверном варианте строчка НовыйЭлемент.Записать() вызовет ошибку RLS, так как УстановитьПривилегированныйРежим(Истина) на клиенте не имеет силы.
Разберем рабочие варианты обхода проблемы при использовании внешних обработок в толстом клиенте конфигураций 1С (например, 1С:УПП или 1С:Комплексная автоматизация 1.1).
Фоновые задания всегда выполняются на стороне сервера в неинтерактивном режиме. Внешняя обработка может инициировать фоновое задание через менеджер ФоновыеЗадания, передав параметры создаваемой серии в экспортную процедуру доступного общего модуля, где запись выполнится с обходом ограничений прав.
Разберем схему реализации:
ФоновыеЗадания.Выполнить(), передавая имя подходящей серверной процедуры и массив параметров.ФоновоеЗадание.ОжидатьЗавершения() и получаем созданную ссылку.Если требуется гарантированно выполнить запись серии из внешней обработки на стороне клиента, можно использовать локальное подключение к текущей информационной базе через COM-соединитель V83.COMConnector от имени специального служебного пользователя с полными правами без ограничений RLS.
Посмотрим на пример реализации:
Функция СоздатьСериюЧерезCOM(ПараметрыСерии, СтрокаПодключения, Пользователь, Пароль)
COMСоединитель = Новый COMОбъект("V83.COMConnector");
Попытка
Соединение = COMСоединитель.Connect(СтрокаПодключения + ";Usr=""" + Пользователь + """;Pwd=""" + Пароль + """;");
Исключение
ВызватьИсключение "Не удалось установить COM-соединение: " + ОписаниеОшибки();
КонецПопытки;
СправочникСерии = Соединение.Справочники.СерииНоменклатуры;
НоваяСерия = СправочникСерии.СоздатьЭлемент();
НоваяСерия.Владелец = Соединение.Справочники.Номенклатура.ПолучитьСсылку(ПараметрыСерии.Номенклатура.УникальныйИдентификатор());
НоваяСерия.Наименование = ПараметрыСерии.Наименование;
НоваяСерия.СерийныйНомер = ПараметрыСерии.СерийныйНомер;
НоваяСерия.СрокГодности = ПараметрыСерии.СрокГодности;
НоваяСерия.Записать();
ГУИДСерии = Соединение.String(НоваяСерия.Ссылка.УникальныйИдентификатор());
Возврат Справочники.СерииНоменклатуры.ПолучитьСсылку(Новый УникальныйИдентификатор(ГУИДСерии));
КонецФункции
Часто жесткий запрет RLS на уровне всей таблицы справочника Номенклатура является избыточным. Для решения задачи разграничения прав в типовых конфигурациях применяются альтернативные настройки:
Дополнительные права пользователей. В нем можно отключить опцию Редактирование цен и номенклатуры в документах или Редактирование справочника Номенклатура интерактивно, не активируя RLS на таблицу базы данных.Интерактивное добавление и Интерактивное изменение для самого справочника. В этом случае программное создание серий с указанием владельца будет проходить без ошибок доступа.