При обновлении платформы до версии 8.3.10 или при отключении режима совместимости разработчики часто сталкиваются с ошибкой времени выполнения: Право Добавление неприменимо к РегистрСведений... при вызове стандартной функции ПравоДоступа(). Разберем по шагам, почему прежний код перестал работать и как правильно адаптировать алгоритмы проверки прав под актуальные требования платформы 1С:Предприятие.
Проанализируем, как работал метод ПравоДоступа() в более ранних версиях и что изменилось:
Добавление для регистра сведений), платформа не генерировала ошибку, а неявно возвращала значение Ложь.Режим совместимости с версией 8.3.9 или более ранней. Как только режим совместимости отключается или повышается до 8.3.10+, начинает действовать строгий контроль.Выясним причину ошибки с точки зрения структуры метаданных. У объектных сущностей (таких как справочники, документы, планы видов характеристик) данные представлены ссылочными объектами, поэтому для них существуют отдельные атомарные права Добавление (Insert) и Удаление (Delete).
У необъектных сущностей, к которым относятся регистры сведений, регистры накопления, регистры бухгалтерии и регистры расчета, таких прав нет. Для регистров сведений платформой определен следующий набор базовых прав:
Чтение (Read) — право на чтение записей регистра.Изменение (Update) — право на любую модификацию данных: добавление новых записей, редактирование существующих или очистку наборов записей.Просмотр (View) — право на интерактивный просмотр данных в интерфейсе.Редактирование (Edit) — право на интерактивное изменение данных через формы.Таким образом, право Добавление к регистру сведений применить невозможно в принципе — любые операции записи регулируются исключительно правом Изменение.
Рассмотрим способы адаптации программного кода в зависимости от решаемой задачи.
Посмотрим на пример правильной проверки возможности записи данных в регистр сведений. Вместо несуществующего права Добавление следует проверять право Изменение:
// Неправильно для 8.3.10+:
// Результат = ПравоДоступа("Добавление", Метаданные.РегистрыСведений.УчетнаяПолитика);
// Правильно:
Результат = ПравоДоступа("Изменение", Метаданные.РегистрыСведений.УчетнаяПолитика);
Если алгоритм выполняет обход коллекции различных объектов метаданных (например, в универсальных обработках переноса данных или подсистемах аудита), необходимо предварительно проверять тип объекта и запрашивать соответствующее право:
Если Метаданные.Справочники.Содержит(ОбъектМетаданных)
Или Метаданные.Документы.Содержит(ОбъектМетаданных) Тогда
ЕстьДоступ = ПравоДоступа("Добавление", ОбъектМетаданных);
ИначеЕсли Метаданные.РегистрыСведений.Содержит(ОбъектМетаданных)
Или Метаданные.РегистрыНакопления.Содержит(ОбъектМетаданных) Тогда
ЕстьДоступ = ПравоДоступа("Изменение", ОбъектМетаданных);
Иначе
ЕстьДоступ = Ложь;
КонецЕсли;
В универсальных сервисных механизмах, где полный список проверяемых прав динамический, допустимо перехватывать исключение неприменимости права:
Попытка
ЕстьДоступ = ПравоДоступа(ИмяПрава, ОбъектМетаданных);
Исключение
// Право неприменимо к объекту метаданных
ЕстьДоступ = Ложь;
КонецПопытки;
Однако рекомендуется отдавать предпочтение явной проверке типов метаданных, так как это делает код более прозрачным и исключает сокрытие других непредвиденных ошибок платформы.