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

Программист 1С v8.3 (Управляемые формы)
← На главную

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

Способ 1. Использование обработчика события «ПередУдалением»

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

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


Процедура ПередУдалением(Отказ)
    
    // Если удаление вызвано регламентным заданием или интерактивно, 
    // мы можем установить безусловный запрет
    Отказ = Истина;
    
    // Опционально: можно вывести сообщение в журнал регистрации, 
    // чтобы администратор понимал, почему объект остался в базе
    ЗаписьЖурналаРегистрации("Удаление объектов", УровеньЖурналаРегистрации.Предупреждение, , , 
        "Попытка удаления документа " + ЭтотОбъект.Ссылка + " заблокирована программно.");
        
КонецПроцедуры

Важный нюанс: использование этого метода заставит стандартную обработку «Удаление помеченных объектов» спотыкаться на каждом таком документе. В логах выполнения регламентного задания будут появляться ошибки о невозможности удаления, что может затруднить мониторинг состояния системы. Поэтому перейдем к более изящным решениям.

Способ 2. Подписка на событие (Архитектурно правильный подход)

Чтобы не вносить изменения в модуль самого документа (особенно если конфигурация находится на поддержке), мы можем использовать Подписку на события. Это позволит нам централизованно управлять логикой запрета удаления для одного или нескольких типов документов.

Выполним следующие шаги:

  1. Создадим в конфигураторе новый объект ПодпискаНаСобытие.
  2. В поле «Источник» выберем ДокументОбъект.ИмяНужногоДокумента.
  3. В поле «Событие» выберем ПередУдалением.
  4. В обработчике подписки пропишем логику отказа:

Процедура ЗапретитьУдалениеОпределенныхДокументовПередУдалением(Источник, Отказ) Экспорт
    // Источник — это сам объект документа
    // Устанавливаем отказ для всех документов этого типа
    Отказ = Истина;
КонецПроцедуры

Преимущество этого метода в том, что код вынесен в отдельный общий модуль, что упрощает обновление основной конфигурации.

Способ 3. Модификация обработки через расширение (для БСП)

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

Рассмотрим ситуацию: нам нужно модифицировать процедуру УдалитьПомеченныеОбъектыИзРегламентногоЗадания. Лучше всего это сделать через расширение с использованием аннотации &Вместо или &ИзменениеИКонтроля.

Посмотрим на пример логики в модуле менеджера или объекта обработки (в зависимости от версии БСП):


&Вместо("УдалитьПомеченныеОбъекты")
Процедура Расш_УдалитьПомеченныеОбъекты(ПараметрыУдаления)
    // Перед вызовом основного алгоритма можно изменить настройки поиска помеченных объектов.
    // В БСП часто используется компоновка данных или массив типов.
    // Нам нужно программно исключить наш тип документа из коллекции типов, 
    // подлежащих анализу.
    
    // Пример упрощенной логики:
    ТипыДляУдаления = ПараметрыУдаления.МассивТипов;
    Индекс = ТипыДляУдаления.Найти(Тип("ДокументСсылка.НужныйДокумент"));
    Если Индекс <> Неопределено Тогда
        ТипыДляУдаления.Удалить(Индекс);
    КонецЕсли;
    
    // Вызываем оригинальный метод с уже отфильтрованным списком типов
    ПродолжитьВызов(ПараметрыУдаления);
КонецПроцедуры

Способ 4. Ограничение прав доступа (RLS)

Выясним, можно ли решить задачу без программирования. Если регламентное задание выполняется под пользователем с ограниченными правами, мы можем просто убрать право Удаление (Delete) и Интерактивное удаление (InteractiveDelete) для конкретного документа в соответствующей роли.

Однако помните: регламентные задания в 1С чаще всего выполняются в привилегированном режиме или под пользователем с полными правами. В этом случае ограничения ролей игнорируются. Чтобы этот метод сработал, необходимо:

  1. Создать специального пользователя (например, «РоботУдаления»).
  2. Настроить для него роль, где запрещено удаление нужного документа.
  3. В настройках регламентного задания указать запуск именно от имени этого пользователя.

Способ 5. Изменение бизнес-логики (Рекомендуемый метод)

Проанализируем ситуацию с точки зрения методологии. Использование пометки на удаление для хранения данных — это плохая практика («Anti-pattern»). Если документ помечен на удаление, система считает его «мусором», подлежащим уничтожению.

Рассмотрим альтернативный, более профессиональный подход:

  1. Добавим в документ дополнительный реквизит СтатусДокумента (тип: Перечисление) со значениями Активный и Архив (Не удалять).
  2. Вместо установки пометки на удаление пользователь будет переводить документ в статус «Архив».
  3. Настроим формы списков и отчеты так, чтобы они по умолчанию скрывали документы в статусе «Архив».

Результат: документы не мешают в повседневной работе, они физически защищены от регламентного удаления, и вам не нужно писать сложные «костыли» в коде ядра системы.

Резюме

Выбор метода зависит от ваших возможностей по изменению конфигурации:

← На главную