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