Как запретить непосредственное удаление документа (Shift + Delete) в 1С?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

В процессе разработки и сопровождения систем на базе платформы 1С часто возникает задача ограничить возможности пользователя по удалению данных. Стандартная процедура ПередЗаписью в модуле объекта отлично справляется с задачей, когда мы хотим запретить установку пометки на удаление, но она оказывается совершенно бесполезной против сочетания клавиш Shift + Delete. В этой статье мы подробно разберем, почему это происходит, и проанализируем эффективные способы защиты базы данных от физического удаления объектов.

Разберем причину: почему ПередЗаписью не помогает?

Для начала проанализируем механику работы платформы 1С. Когда пользователь устанавливает или снимает пометку удаления, происходит изменение состояния объекта и его последующая запись. В этот момент вызывается обработчик ПередЗаписью, где проверка ЭтотОбъект.ПометкаУдаления = Истина позволяет выставить Отказ = Истина и остановить процесс.

Однако непосредственное удаление (Shift + Delete) — это физическое удаление записи из таблицы базы данных. Этот процесс не является операцией записи. Платформа просто уничтожает запись, минуя все проверки, связанные с сохранением объекта. Именно поэтому код, написанный в ПередЗаписью, игнорируется.

Решение 1: Использование обработчика ПередУдалением

Самый простой программный способ перехватить попытку физического удаления — использовать специализированное событие в модуле объекта. Рассмотрим, как это реализовать. Нам необходимо открыть модуль нужного документа и добавить в него процедуру ПередУдалением(Отказ).

Посмотрим на пример кода, который блокирует удаление для всех пользователей без исключения:


Процедура ПередУдалением(Отказ)
    // Сообщаем пользователю о причине отказа
    Сообщить("В данной системе непосредственное удаление объектов запрещено программно!");
    // Устанавливаем флаг отказа
    Отказ = Истина;
КонецПроцедуры

Этот обработчик вызывается платформой непосредственно перед тем, как объект будет стерт из базы. Установка параметра Отказ в значение Истина прерывает транзакцию удаления.

Решение 2: Тонкая настройка прав через роли (Метаданные)

Рассмотрим более профессиональный подход, который не требует написания кода в каждом документе. В конфигураторе 1С права на удаление разделены на несколько категорий. Проанализируем их подробнее:

  1. Удаление (Delete) — право на физическое удаление объекта программным способом или через специальные обработки.
  2. Интерактивное удаление (Interactive Delete) — право на удаление объекта пользователем вручную (то самое сочетание Shift + Delete).
  3. Интерактивная пометка удаления — право помечать объект на удаление (клавиша Del).

Рекомендация: В большинстве типовых конфигураций 1С (таких как БП 3.0, УТ 11 или ERP) право "Интерактивное удаление" снято для всех ролей, кроме полных прав (и часто даже для них). Это стандарт безопасности, предотвращающий появление "битых ссылок". Для автоматического поиска таких разрешений по конфигурации подойдёт алгоритм проверки прав на интерактивное удаление объектов.

Чтобы настроить это, выполним следующие шаги:

  1. Зайдем в конфигуратор, откроем дерево метаданных.
  2. Перейдем в ветку Общие -> Роли.
  3. Выберем нужную роль и найдем в списке объектов наш документ.
  4. В правой части окна снимем галочку с пункта "Интерактивное удаление".

Решение 3: Ограничение удаления для конкретных пользователей

Иногда возникает ситуация, когда "СуперАдмину" удалять можно, а "другу директора" с правами администратора — нельзя. В этом случае мы можем комбинировать программный метод с проверкой прав или имени пользователя. Выясним, как это реализовать в коде.

Рассмотрим пример проверки по имени пользователя (хотя это считается "плохим тоном" в разработке, иногда это единственный быстрый выход):


Процедура ПередУдалением(Отказ)
    ТекущийПользовательСистемы = ПользователиИнформационнойБазы.ТекущийПользователь();
    
    Если ТекущийПользовательСистемы.Имя = "ТупойДругДиректора" Тогда
        Сообщение = Новый СообщениеПользователю();
        Сообщение.Текст = "Вам запрещено непосредственное удаление. Пользуйтесь пометкой на удаление.";
        Сообщение.Сообщить();
        Отказ = Истина;
    КонецЕсли;
КонецПроцедуры

Более правильный метод — проверка доступности роли. Рассмотрим его:


Процедура ПередУдалением(Отказ)
    // Если пользователю НЕ доступна роль ПолныеПрава, запрещаем физическое удаление
    Если НЕ РольДоступна("ПолныеПрава") Тогда
        Отказ = Истина;
        Сообщить("У вас недостаточно прав для физического удаления объекта. Обратитесь к системному администратору.");
    КонецЕсли;
КонецПроцедуры

Решение 4: Глобальный запрет через подписки на события

Если документов в базе много, прописывать код в каждом модуле трудозатратно. Разберем, как сделать универсальный механизм. Для этого используются Подписки на события.

  1. Создадим в дереве метаданных (раздел Общие) новую Подписку на событие.
  2. В поле Источник выберем типы документов, которые хотим защитить (можно выбрать сразу все документы).
  3. В поле Событие выберем ПередУдалением.
  4. В поле Обработчик создадим процедуру в общем модуле.

Посмотрим, как будет выглядеть процедура в общем модуле:


Процедура ЗапретНепосредственногоУдаленияПередУдалением(Источник, Отказ) Экспорт
    // Источник — это сам объект (документ), который пытаются удалить
    Если НЕ РольДоступна("РазрешитьФизическоеУдаление") Тогда
        Отказ = Истина;
        ТекстСообщения = СтрШаблон("Удаление объекта %1 запрещено!", Источник);
        ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения);
    КонецЕсли;
КонецПроцедуры

Почему непосредственное удаление — это опасно?

Проанализируем последствия использования Shift + Delete. В 1С объекты связаны друг с другом через ссылки. Например, на документ "Заказ" могут ссылаться документы "Реализация", записи в регистрах накопления и бухгалтерии.

Что происходит при обычном удалении (через пометку):
Система запускает обработку "Удаление помеченных объектов", которая проверяет все связи. Если на документ есть хотя бы одна ссылка, он не будет удален физически, пока не будут удалены или перепривязаны зависимые объекты. Это сохраняет целостность базы.

Что происходит при Shift + Delete:
Объект исчезает мгновенно. Все ссылки на него в других документах и регистрах превращаются в строку <Объект не найден> (84:b7001c1d...). Это приводит к следующим проблемам:

Именно поэтому, даже если вы админ, всегда используйте пометку на удаление и штатный механизм контроля ссылочной целостности. А для "особо активных" пользователей лучше всего просто отключить право "Интерактивное удаление" в их ролях. Для анализа ролей и профилей, открывающих доступ к объекту метаданных, можно использовать обработку для быстрой проверки прав доступа.

← На главную