Как реализовать выборочное подтверждение регистрации изменений в 1С при обмене данными?

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

В процессе разработки интеграций между различными информационными базами на платформе 1С (например, между 1С:ERP и 1С:Бухгалтерия) программисты часто сталкиваются с ограничением стандартного механизма планов обмена. Стандартный подход работает по принципу «все или ничего»: когда база-источник получает подтверждение о приеме сообщения с определенным номером, она очищает регистрацию изменений для всех объектов, вошедших в этот пакет. Однако на практике часто возникает ситуация, когда часть документов из пакета загрузилась успешно, а один или несколько документов — нет (например, из-за некорректных данных или отсутствия связанных справочников). В таком случае нам необходимо оставить «проблемные» объекты зарегистрированными, чтобы они ушли со следующим сеансом обмена, а для успешных — снять регистрацию.

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

Анализ стандартного механизма планов обмена

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

ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена, НомерПринятогоСообщения);

Этот метод очищает записи в таблице регистрации изменений для указанного узла по всем объектам, чей номер сообщения меньше или равен переданному. Проблема заключается в том, что внутри этой процедуры нет фильтра по конкретным объектам — она оперирует только номерами пакетов. Если мы хотим управлять процессом более тонко, нам придется изменить саму логику взаимодействия баз.

Решение №1: Программная перерегистрация объектов (Custom Ack)

Рассмотрим наиболее гибкий подход, который можно внедрить в уже существующий обмен через файлы (XML/JSON). Идея заключается в том, чтобы в файле-ответе передавать не просто номер сообщения, а детальный список идентификаторов (GUID), которые не удалось загрузить.

Алгоритм реализации:

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

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


// 1. Стандартная очистка по номеру сообщения
ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена, СтруктураОтвета.НомерСообщения);

// 2. Повторная регистрация объектов с ошибками
Для Каждого ТекущийИдентификатор Из СтруктураОтвета.СписокОшибочныхGUID Цикл
    // Находим ссылку на объект по GUID (нужно знать тип объекта или искать перебором)
    СсылкаНаОбъект = НайтиСсылкуПоИдентификатору(ТекущийИдентификатор);
    
    Если Не СсылкаНаОбъект.Пустая() Тогда
        ПланыОбмена.ЗарегистрироватьИзменения(УзелОбмена, СсылкаНаОбъект);
    КонецЕсли;
КонецЦикла;

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

Решение №2: Использование промежуточной очереди (Message Queue)

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

Суть метода:

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

Такой подход гарантирует, что пока объект не будет физически записан в приемнике, запись о необходимости его передачи будет «висеть» в нашей самописной очереди в источнике. Это избавляет от проблем с номерами сообщений, но требует разработки собственной логики формирования пакетов.

Решение №3: Переход на синхронный обмен через HTTP/Web-сервисы

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

При таком подходе база-источник передает данные в приемник и в рамках того же соединения получает ответ о результате загрузки. Если приемник вернул код 200 (ОК), источник выполняет:

ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена, СсылкаНаОбъект);

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

Решение №4: Использование механизмов БСП

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

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

Важные рекомендации при реализации

При внедрении ручного управления регистрацией изменений важно учитывать следующие нюансы:

  1. Защита от зацикливания («Вечная ошибка»): Если документ не грузится из-за критической ошибки в данных, которую никто не исправляет, он будет выгружаться бесконечно. Мы рекомендуем добавить в таблицу регистрации или очередь сообщений поле КоличествоПопытокОтправки. После 5–10 неудачных попыток объект должен попадать в «карантин» и уведомлять администратора.
  2. Производительность: Пообъектная очистка регистрации через УдалитьРегистрациюИзменений(Узел, Объект) работает медленнее, чем массовая очистка по номеру сообщения. На больших базах это может вызвать блокировки таблицы Chng (таблица изменений). Старайтесь группировать объекты при обработке.
  3. Целостность данных: Если за время между неудачной выгрузкой и повторной попыткой объект был изменен в источнике еще раз, стандартный план обмена это обработает корректно (он просто выгрузит актуальное состояние). Если же вы используете свою очередь сообщений (Решение №2), не забывайте обновлять данные в очереди при каждом изменении объекта в базе.

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

← На главную