Как в 1С отследить установку пометки на удаление и выполнить проверки перед записью?

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

При разработке прикладных решений в платформе 1С часто возникает задача: выполнить проверку ссылочной целостности или бизнес-логики в момент, когда пользователь пытается пометить элемент справочника на удаление (например, единицу измерения из формы элемента номенклатуры), и при необходимости отменить операцию или предупредить пользователя. Разберем особенности работы событий платформы и выясним, как правильно реализовать такой контроль.

В чем разница между удалением и установкой пометки на удаление

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

  1. Физическое удаление: Обработчик ПередУдалением в модуле объекта срабатывает исключительно при непосредственном удалении записи из базы данных (например, при выполнении регламентной обработки «Удаление помеченных объектов» или непосредственном удалении программным методом). При интерактивной работе пользователя в форме этот обработчик не вызывается.
  2. Пометка на удаление: Установка пометки на удаление представляет собой обычную операцию модификации и сохранения объекта в информационной базе, при которой системный реквизит ПометкаУдаления принимает значение Истина.

Также важно учитывать поведение механизма валидации: при интерактивной установке пометки на удаление стандартный обработчик ОбработкаПроверкиЗаполнения платформой намеренно пропускается. Поэтому любые контроли возможности пометки объекта должны быть встроены в события записи.

Основное решение: обработчик события ПередЗаписью в модуле объекта

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

Для этого в модуле объекта справочника (или в подписке на соответствующее событие) используем обработчик ПередЗаписью:


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

КонецПроцедуры

Посмотрим на логику условия подробнее:

  1. ПометкаУдаления — возвращает значение реквизита текущего модифицируемого объекта в памяти (которое стало равным Истина).
  2. Ссылка.ПометкаУдаления — считывает значение реквизита непосредственно из базы данных на момент до фиксации изменений (где значение еще равно Ложь).
  3. Если оба условия выполняются, значит, пользователь нажал кнопку пометки и подтвердил действие, а объект находится в процессе записи.

Реализация через подписку на события

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

  1. В дереве метаданных конфигурации перейдем в ветку Общие → Подписки на события.
  2. Создадим новую подписку с именем, например, КонтрольПометкиУдаленияСправочниковПередЗаписью.
  3. В поле Источник укажем необходимый справочник (например, СправочникОбъект.ЕдиницыИзмерения).
  4. В поле Событие выберем ПередЗаписью.
  5. В назначенном общем серверном модуле разместим процедуру проверки:

Процедура КонтрольПометкиУдаленияСправочниковПередЗаписью(Источник, Отказ) Экспорт

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

КонецПроцедуры

Альтернативный вариант: переопределение команды в форме

Если требуется выдать пользователю интерактивное предупреждение с вопросом или выполнить проверку еще до начала транзакции записи, стандартную команду командной панели формы или таблицы заменяют собственной командой формы.

Разберем по шагам создание собственной команды:

  1. В свойствах таблицы формы для стандартной команды «Установить пометку удаления» отключаем видимость или автозаполнение.
  2. Создаем пользовательскую команду формы КомандаУстановитьПометку.
  3. В обработчике команды на клиенте вызываем асинхронный диалог подтверждения, после чего вызываем серверный метод:

&НаКлиенте
Процедура КомандаУстановитьПометку(Команда)
    
    ТекущиеДанные = Элементы.Список.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    Оповещение = Новый ОписаниеОповещения("ПослеПодтвержденияПометки", ЭтотОбъект, ТекущиеДанные.Ссылка);
    ПоказатьВопрос(Оповещение, "Установить пометку на удаление для выбранного элемента?", РежимДиалогаВопрос.ДаНет);

КонецПроцедуры

&НаКлиенте
Процедура ПослеПодтвержденияПометки(Результат, СсылкаНаЭлемент) Экспорт

    Если Результат = КодВозвратаДиалога.Да Тогда
        УстановитьПометкуНаСервере(СсылкаНаЭлемент);
    КонецЕсли;

КонецПроцедуры

&НаСервере
Процедура УстановитьПометкуНаСервере(СсылкаНаЭлемент)

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

КонецПроцедуры

Таким образом, наиболее надежным и универсальным местом для контроля и валидации бизнес-правил остается событие ПередЗаписью, где сопоставление ПометкаУдаления и Ссылка.ПометкаУдаления гарантирует корректный перехват изменения состояния элемента как при интерактивных действиях, так и при программных вызовах.

← На главную