К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как отловить пометку на удаление в 1С

Как в 1С отловить пометку на удаление: подписки на события, обработчики ПередЗаписью и ПриЗаписи, запросы по помеченным объектам, контроль ссылочной целостности.

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

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

Ниже разобраны рабочие приёмы: код перехвата в модуле объекта и в подписке, запросы для поиска помеченных элементов, журналирование через регистр сведений, а также ограничения и типичные ошибки, из-за которых перехват «не срабатывает».

Как устроена пометка на удаление в механизме платформы

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

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

Перехват в модуле объекта через ПередЗаписью

Самый прямой способ — добавить код в обработчик ПередЗаписью модуля объекта справочника или документа. Проблема в том, что в момент записи объект уже содержит новое значение пометки, а старое нужно получить из базы запросом. Для этого сравнивают ПометкаУдаления текущего объекта с пометкой у ссылки.

Процедура ПередЗаписью(Отказ)

Если ОбменДанными.Загрузка Тогда

Возврат;

КонецЕсли;

Если Не Ссылка.Пустая() Тогда

ПометкаВБазе = Ссылка.ПометкаУдаления;

Если ПометкаВБазе <> ПометкаУдаления Тогда

Если ПометкаУдаления Тогда

// Объект помечают на удаление

ЗаписьЖурналаРегистрации("ПометкаНаУдаление",

УровеньЖурналаРегистрации.Информация, , Ссылка,

"Установлена пометка на удаление");

Иначе

// С пометки снимают

КонецЕсли;

КонецЕсли;

КонецЕсли;

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

Обращение Ссылка.ПометкаУдаления выполняет неявный запрос к базе и возвращает значение, которое хранится там до записи. Это стандартный приём определения факта изменения флага. Для нового объекта (ссылка пустая) сравнение не имеет смысла — пометка у него по определению новая.

Подписка на событие для всех объектов сразу

Если отслеживать пометку нужно по многим видам объектов, редактировать каждый модуль объекта неудобно и опасно для обновления конфигурации. Правильное решение — подписка на событие: в конфигураторе создаётся объект «Подписка на событие» с событием ПередЗаписью или ПриЗаписи, а в источнике перечисляются нужные типы (справочники, документы, планы счетов и т.д.).

Обработчик подписки размещают в общем модуле с признаками «Сервер» и «Вызов сервера». Сигнатура аналогична обработчику объекта — источник передаётся параметром. Внутри используют тот же приём сравнения с Источник.Ссылка.ПометкаУдаления. Такой подход централизует логику: один обработчик обслуживает всю конфигурацию.

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

Если Источник.ОбменДанными.Загрузка Тогда

Возврат;

КонецЕсли;

Если Источник.ЭтоНовый() Тогда

Возврат;

КонецЕсли;

ПометкаВБазе = Источник.Ссылка.ПометкаУдаления;

Если ПометкаВБазе = Источник.ПометкаУдаления Тогда

Возврат; // флаг не менялся

КонецЕсли;

// реакция на изменение пометки

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

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

Запрет и контроль: как не дать пометить объект

Частая задача — не просто отловить пометку, а запретить её по условию: например, нельзя помечать проведённые документы или элементы, на которые есть ссылки. Для этого в обработчике при обнаружении установки пометки проверяют условие и при его нарушении устанавливают Отказ = Истина и выводят сообщение пользователю.

Дополнительно доступ контролируют правами: роль может запрещать интерактивную пометку на удаление для отдельных видов объектов. Это надёжнее кода, потому что право действует независимо от обхода обработчиков через программную запись. Оптимальная схема — сочетание прав (грубый контур) и проверок в подписке (тонкие бизнес-условия).

Маршрут решения

Как выбрать способ контроля

Нужно полностью запретить пометку для группы пользователейНастройте роли: снимите право интерактивной пометки на удаление
Запрет зависит от состояния объекта (проведён, есть ссылки)Используйте подписку ПередЗаписью с установкой Отказ = Истина
Нужно только фиксировать факт пометки для аудитаЗаписывайте событие в журнал регистрации или собственный регистр сведений
Нужно найти уже помеченные объектыИспользуйте запрос с условием по ПометкаУдаления или стандартный отчёт поиска помеченных

Как найти помеченные объекты запросом

Для разового анализа помеченных данных запрос — самый быстрый инструмент. Условие по системному полю работает в любой объектной таблице:

ВЫБРАТЬ

Номенклатура.Ссылка,

Номенклатура.Код,

Номенклатура.Наименование

ИЗ

Справочник.Номенклатура КАК Номенклатура

ГДЕ

Номенклатура.ПометкаУдаления

В типовых конфигурациях есть штатная обработка «Поиск и удаление помеченных объектов» (в разделе администрирования). Она показывает помеченные объекты и места их использования. Для регулярного контроля удобно сделать собственный отчёт на СКД, который группирует помеченные объекты по видам и датам изменения.

Журналирование факта пометки для аудита

Журнал регистрации фиксирует изменение данных, но фильтровать в нём именно установку пометки неудобно. Для аудита лучше писать факт в собственный регистр сведений: дата, пользователь, ссылка, действие (установка/снятие). Записывать такой регистр следует в событии ПриЗаписи или в транзакции записи, чтобы не зафиксировать пометку, которая потом отменена отказом.

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

Типичные ошибки
01
Сравнение ПометкаУдаления с ДополнительныеСвойства вместо чтения значения из базы — старое значение недоступно в объекте, его нужно получать через Ссылку
02
Забытая проверка ОбменДанными.Загрузка — обмены начинают падать или, наоборот, пометки из обмена проходят мимо контроля
03
Установка Отказ = Истина в событии ПриЗаписи — объект уже записан, отказ нужно ставить в ПередЗаписью
04
Попытка перехватить пометку через ОбработкаПроведения или ОбработкаЗаполнения — эти события при пометке не вызываются
05
Запись аудита до завершения транзакции — при откате записи останется ложная запись о пометке

Проверка результата и границы самостоятельной работы

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

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

Контрольные точки

Как проверить результат

Интерактивная пометка в пользовательском режиме
Норма

Обработчик сработал, событие зафиксировано или показан запрет

Тревожный признак

Ничего не происходит — проверьте источник подписки и флаги общего модуля

Работа обменов данными
Норма

Обмен проходит без ошибок

Тревожный признак

Обмен падает — вероятно, нет проверки ОбменДанными.Загрузка

Запрет пометки по условию
Норма

Пользователь видит сообщение, объект остаётся непомеченным

Тревожный признак

Объект помечается несмотря на запрет — Отказ установлен не в том событии

Частые вопросы

Почему подписка на событие не срабатывает при пометке?

Чаще всего не выбран тип объекта в свойстве «Источник» подписки, общий модуль не имеет флагов «Сервер» и «Вызов сервера», либо запись идёт в режиме загрузки обмена данными. Также проверьте, что обработчик подписки объявлен с ключевым словом Экспорт.

Можно ли отловить пометку без изменения конфигурации?

Полноценно — нет. Без доработки доступны только периодический анализ: запросы по полю ПометкаУдаления, штатная обработка поиска помеченных объектов и просмотр журнала регистрации по событиям изменения данных. Реагировать в момент пометки может только код в обработчиках событий.

Как узнать, кто и когда пометил объект на удаление?

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

Срабатывают ли обработчики при снятии пометки?

Да, снятие пометки — та же запись объекта с изменённым флагом, поэтому ПередЗаписью и ПриЗаписи вызываются. В коде различайте направление изменения: если новое значение ПометкаУдаления ложно, а в базе истина — это снятие пометки.

Можно ли запретить пометку только для проведённых документов?

Да. В подписке ПередЗаписью при обнаружении установки пометки проверьте Источник.Проведен, и если документ проведён, установите Отказ = Истина с сообщением пользователю. Учтите, что пометка проведённого документа штатно требует отмены проведения, поэтому дополнительно контролируйте и событие отмены проведения.

Итог

Что важно запомнить

Пометка на удаление — это запись объекта, поэтому перехватывается в ПередЗаписью/ПриЗаписи или подпиской на событие через сравнение со значением в базе. Для запрета используйте Отказ в ПередЗаписью и права, для аудита — свой регистр сведений, для поиска — запросы по полю ПометкаУдаления. Всегда проверяйте ОбменДанными.Загрузка и тестируйте на копии базы.