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