Как исправить ошибку УстановитьПометкуУдаления при обмене данными в 1С?

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При выполнении регулярного обмена данными между конфигурациями (например, между 1С:Управление торговлей 10.3 и 1С:Бухгалтерия предприятия 2.0) пользователи нередко сталкиваются со сбоем процесса загрузки. В окне сообщений появляется диагностический отчет следующего содержания: Ошибка в обработчике события ПриПолученииИнформацииОбУдалении (конвертация), после чего следует описание: Ошибка при вызове метода контекста (УстановитьПометкуУдаления): Не удалось записать "Основной договор (Договоры контрагентов)"!. Процесс синхронизации аварийно прерывается, и новые документы перестают поступать в базу-приемник.

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

Причины возникновения ошибки

Проанализируем механику работы планов обмена на базе универсального механизма обмена данными в формате XML. Когда в информационной базе-источнике пользователь помечает на удаление или физически удаляет элемент справочника, план обмена регистрирует это событие. В итоговый файл выгрузки помещается специальный служебный узел УдалениеОбъекта, содержащий тип метаданных и уникальный идентификатор (GUID) удаленной сущности.

В процессе загрузки в базе-приемнике типовая обработка Обработка.ОбменДаннымиXML считывает узел удаления и находит соответствующий элемент по его GUID. Далее платформа пытается выполнить программное действие через метод УстановитьПометкуУдаления(). Сбой записи при этом вызывается несколькими факторами:

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

Способ 1. Очистка регистрации изменений через типовую обработку

Самый быстрый способ вернуть обмен в рабочее состояние без правок программного кода — отменить регистрацию сбойных элементов в базе-источнике с помощью обработки Регистрация изменений для обмена.

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

  1. Открываем базу, из которой производится выгрузка данных (в которой исходно производились манипуляции с договорами).
  2. Запускаем обработку Регистрация изменений для обмена (в обычном приложении она доступна через меню Операции - Обработки либо как внешняя обработка).
  3. В поле выбора узла указываем соответствующий узел плана обмена, по которому настроена синхронизация.
  4. В дереве объектов находим ветку Справочники, раскрываем ее и переходим к объекту Договоры контрагентов.
  5. Нажимаем кнопку показа зарегистрированных изменений. Внимательно просматриваем список: если в перечне присутствуют строки с наименованием Объект не найден или элементы, помеченные на удаление, выделяем их и нажимаем Отменить регистрацию.
  6. Аналогичным образом проверяем документы (например, Реализация товаров и услуг). Если в узле зарегистрированы старые документы, попадающие под дату запрета изменения в базе-приемнике, снимаем их с регистрации, чтобы обмен не пытался перезаписать закрытый период.
  7. Повторно запускаем процедуру выгрузки и загрузки данных.

Способ 2. Точная локализация сбойного договора по файлу обмена и GUID

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

В тексте ошибки система выводит количество успешно обработанных данных, например: Было загружено: 1 911. Посмотрим, как использовать эту информацию:

  1. Открываем выгруженный файл обмена с расширением .xml в текстовом редакторе (например, Notepad++).
  2. Поскольку ошибка произошла сразу после загрузки 1911 объектов, выполняем поиск по тексту НПП="1911" или НПП="1912".
  3. Изучаем блок XML, следующий непосредственно за найденным номером. Так как сбой произошел в обработчике ПриПолученииИнформацииОбУдалении, ищем тег УдалениеОбъекта. Внутри этого тега будет указан уникальный идентификатор:

<УдалениеОбъекта>
    <Ссылка>
        <ДоговорыКонтрагентов>
            <УникальныйИдентификатор>a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d</УникальныйИдентификатор>
        </ДоговорыКонтрагентов>
    </Ссылка>
</УдалениеОбъекта>

Теперь выясним, к какому контрагенту относится данный договор в базе-приемнике. Для этого воспользуемся внешней обработкой с произвольным алгоритмом или консолью запросов в режиме «1С:Предприятие»:


Идентификатор = Новый УникальныйИдентификатор("a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d");
СсылкаНаДоговор = Справочники.ДоговорыКонтрагентов.ПолучитьСсылку(Идентификатор);

Если СсылкаНаДоговор.Пустая() Тогда
    Сообщить("Договор с таким GUID в базе не существует.");
Иначе
    ДоговорОбъект = СсылкаНаДоговор.ПолучитьОбъект();
    Сообщить("Найден договор: " + Строка(ДоговорОбъект));
    Сообщить("Владелец (контрагент): " + Строка(ДоговорОбъект.Владелец));
КонецЕсли;

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

Способ 3. Программная очистка очереди удалений в узле обмена

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


ВыбранныйУзел = ПланыОбмена.ОбменУправлениеТорговлейБухгалтерияПредприятия.НайтиПоКоду("БП");

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

Этот метод позволяет полностью сохранить к выгрузке все измененные справочники и проведенные документы, исключив только служебные команды на удаление, вызывающие критическую ошибку.

Способ 4. Проверка обработчиков событий модуля справочника

Если конфигурация базы-приемника находится на поддержке с возможностью изменения, проверим модуль объекта справочника ДоговорыКонтрагентов и зарегистрированные подписки на события. При программной установке пометки удаления обязательно должна работать проверка признака загрузки данных.

Откроем конфигуратор, найдем модуль объекта справочника ДоговорыКонтрагентов и проверим процедуры ПередЗаписью и ПриЗаписи. В самом начале процедур должен присутствовать следующий блок кода:


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

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

Аналогично проверим общие подписки на события, привязанные к источнику СправочникОбъект.ДоговорыКонтрагентов. Если в подписке отсутствует проверка свойства Источник.ОбменДанными.Загрузка, вызов метода УстановитьПометкуУдаления() будет неизбежно прерываться исключением при несоблюдении любого второстепенного бизнес-правила.

Способ 5. Безопасная обработка удаления в правилах конвертации (КД 2.0)

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


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

// Отменяем стандартное платформенное действие, так как обработка выполнена вручную
Отказ = Истина;

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

← На главную