Почему при удалении помеченных документов «Платежное поручение» регистрируется ссылка «Объект не найден» и как это исправить?

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

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

Разберем механизм работы платформы при удалении

Для начала проанализируем, как платформа 1С:Предприятие 8 обрабатывает события обмена данными. Существует два принципиально разных состояния объекта, которые должны быть переданы в базу-приемник:

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

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

Выясним причину избирательной регистрации

Если вы заметили, что «Объект не найден» появляется только у определенных типов метаданных (например, у платежных поручений), значит, настройки синхронизации для них отличаются от остальных. Рассмотрим три основные причины:

  1. Свойство «Авторегистрация»: Это самый вероятный кандидат. Откроем конфигуратор, найдем используемый ПланОбмена, перейдем на вкладку «Состав» и найдем Документ.ПлатежноеПоручение. Если в колонке «Авторегистрация» стоит значение «Разрешить», то любое физическое удаление будет автоматически фиксироваться платформой. Если у других документов стоит «Запретить», то их удаление не регистрируется автоматически, а управляется программно.
  2. Подписки на события: Проанализируем наличие в конфигурации подписок на события ПередУдалением или ПриУдалении. Часто разработчики создают универсальные механизмы регистрации, но в правилах или условиях подписки могут быть исключения для конкретных типов документов.
  3. Библиотека стандартных подсистем (БСП): Если конфигурация построена на БСП, механизм синхронизации использует «Правила регистрации объектов». Возможно, для платежных поручений в этих правилах не прописан фильтр, игнорирующий физическое удаление.

Решение 1: Программная очистка регистрации после удаления

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


// Пример очистки регистрации для конкретного типа документа
Процедура ОчиститьБитыеСсылкиВПланеОбмена(УзелСсылка)
    
    ТекстЗапроса = 
    "ВЫБРАТЬ
    |	ТИзменения.Ссылка КАК Ссылка,
    |	ТИзменения.Узел КАК Узел
    |ИЗ
    |	Документ.ПлатежноеПоручение.Изменения КАК ТИзменения
    |		ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПлатежноеПоручение КАК Т
    |		ПО ТИзменения.Ссылка = Т.Ссылка
    |ГДЕ
    |	Т.Ссылка ЕСТЬ NULL
    |	И ТИзменения.Узел = &Узел";
    
    Запрос = Новый Запрос(ТекстЗапроса);
    Запрос.УстановитьПараметр("Узел", УзелСсылка);
    
    Результат = Запрос.Выполнить();
    Выборка = Результат.Выбрать();
    
    МассивНаУдаление = Новый Массив;
    Пока Выборка.Следующий() Цикл
        МассивНаУдаление.Добавить(Выборка.Ссылка);
    КонецЦикла;
    
    Если МассивНаУдаление.Количество() > 0 Тогда
        ПланыОбмена.УдалитьРегистрациюИзменений(УзелСсылка, МассивНаУдаление);
    КонецЕсли;
    
КонецПроцедуры

Этот метод эффективен, когда нужно точечно исправить ситуацию. Мы используем левое соединение таблицы изменений с основной таблицей документа. Если в основной таблице запись отсутствует (ЕСТЬ NULL), значит, это то самое «Удаление объекта», которое мы хотим убрать.

Решение 2: Глобальное отключение авторегистрации удалений

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

  1. В конфигураторе найдем нужный ПланОбмена.
  2. В составе для документа ПлатежноеПоручение установим Авторегистрация = Запретить.
  3. Добавим (или отредактируем существующую) подписку на событие ПриЗаписи для этого документа.
  4. В коде подписки пропишем регистрацию только в том случае, если объект не находится в процессе удаления.

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


Процедура ПриЗаписиПлатежногоПорученияРегистрация(Источник, Отказ) Экспорт
    
    // Регистрируем изменения только если это не физическое удаление
    // (Хотя ПриЗаписи и так не срабатывает при удалении, 
    // это важно для понимания логики разделения событий)
    
    Узлы = ПланыОбмена.ВашПланОбмена.Выбрать(); // Здесь должна быть логика подбора узлов
    Пока Узлы.Следующий() Цикл
        // Проверяем условия выгрузки...
        ПланыОбмена.ЗарегистрироватьИзменения(Узлы.Ссылка, Источник);
    КонецЦикла;
    
КонецПроцедуры

Как найти виновника через отладку

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

Пошаговый план отладки:

Резюме

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

← На главную