Как реализовать обновление данных в XML-обмене при изменении документа в 1С

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

При реализации механизмов обмена данными через XML-файлы часто возникает ситуация, когда документ, уже выгруженный во внешнюю систему, подвергается корректировке в исходной базе. Если просто перезаписывать файл на FTP, можно столкнуться с потерей данных или рассинхронизацией. В рамках данной статьи мы проанализируем, как правильно организовать процесс обновления данных, разберем архитектурные подходы и выберем наиболее надежные инструменты платформы 1С.

Использование планов обмена для регистрации изменений

Рассмотрим стандартный и наиболее профессиональный подход к решению задачи — использование объекта метаданных ПланыОбмена. Вместо того чтобы пытаться реализовать логику отслеживания изменений вручную через подписки на события и сложные условия, мы доверим эту работу платформе. Механизм планов обмена позволяет регистрировать изменения конкретных объектов для конкретных узлов (получателей).

Проанализируем преимущества этого метода:

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

Для реализации регистрации изменений в коде модуля объекта или в подписке на событие ПриЗаписи нам потребуется следующий код:


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

Гарантия целостности данных и транзакции

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

Чтобы избежать этой ситуации, мы рекомендуем использовать следующий алгоритм:

  1. В процедуре ПередЗаписью или ПриЗаписи устанавливаем флаг необходимости выгрузки в ДополнительныеСвойства объекта.
  2. В процедуре ПослеЗаписи проверяем этот флаг и инициируем выгрузку, но только если транзакция завершена успешно.
  3. Идеальный вариант — использование Регламентных заданий. Регламентное задание раз в минуту или по расписанию проверяет зарегистрированные изменения в плане обмена и выполняет выгрузку вне контекста работы пользователя.

Посмотрим на пример использования дополнительных свойств:


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

Процедура ПослеЗаписи(ПараметрыЗаписи)
    Если ЭтотОбъект.ДополнительныеСвойства.Свойство("ТребуетсяВыгрузкаXML") Тогда
        // Здесь можно вызвать фоновое задание, чтобы не заставлять пользователя ждать
        // ответа от FTP-сервера
        ФоновыеЗадания.Выполнить("ИнтеграцияМенеджер.ВыгрузитьДокументНаFTP", Новый Структура("Ссылка", Ссылка));
    КонецЕсли;
КонецПроцедуры

Версионность и стратегия именования файлов на FTP

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

Рассмотрим две стратегии именования:

  1. Использование временных меток: Формат имени Document_GUID_YYYYMMDDHHMMSS.xml. В этом случае каждый файл уникален. Принимающая база должна обрабатывать файлы в хронологическом порядке. Если для одного GUID найдено несколько файлов, обрабатывается самый свежий, а остальные помечаются как устаревшие.
  2. Атрибут статуса внутри XML: Добавим в структуру XML узел <Status>. При первичной выгрузке статус будет New, при последующих — Edited. Это позволит принимающей логике понять, что нужно не создавать новый документ, а обновить существующий.

Пример формирования имени файла с версией:


Функция СформироватьИмяФайла(ДокументСсылка) Экспорт
    ИмяФайла = "Realization_" + Строка(ДокументСсылка.УникальныйИдентификатор()) + 
               "_" + Формат(ТекущаяДата(), "ДФ=yyyyMMddHHmmss") + ".xml";
    Возврат ИмяФайла;
КонецФункции

Технология выгрузки через промежуточные файлы

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

Разберем по шагам правильный алгоритм работы с FTP:

  1. Записываем данные во временный файл на локальном диске.
  2. Подключаемся к FTP через FTPСоединение.
  3. Загружаем файл с расширением .tmp.
  4. После завершения загрузки вызываем метод Переместить (Rename) на FTP-сервере, меняя расширение с .tmp на .xml.

Этот метод исключает коллизии при чтении файлов сторонними системами.

Обработка коллизий и конфликтов при взвешивании

Посмотрим на ситуацию, когда в одной базе меняются реквизиты (контрагент, дата), а из другой базы приходит результат взвешивания. Если просто "затирать" документ данными из файла, можно потерять актуальную информацию.

Рекомендуем внедрить разделение ответственности за поля. При загрузке XML в базу с результатом взвешивания, система должна обновлять только строго определенные реквизиты (например, "ВесНетто", "ВесТары"), не затрагивая "Организацию" или "Склад", если они управляются в основной базе. Также полезно добавить проверку даты модификации: если документ в базе изменен позже, чем был сформирован XML-файл, загрузку следует пропустить или вывести предупреждение оператору.

Альтернатива: Переход на онлайн-обмен (Веб-сервисы)

Проанализируем предложение из сообщения №5 форума. Обмен через файлы — это асинхронный процесс с задержками. Если бизнес-процесс требует мгновенной реакции (например, весы должны сразу получить данные реализации), стоит рассмотреть HTTP-сервисы или Web-сервисы.

В этом случае при записи документа в Базе А происходит прямой вызов метода в Базе Б. Если База Б успешно приняла данные, она тут же возвращает результат. Это избавляет от необходимости мониторить папки на FTP и решает проблему актуальности данных в режиме реального времени. Статусы в таком случае становятся не нужны, так как обмен происходит синхронно в рамках одного вызова.

Важно: Выбор между файловым обменом и веб-сервисами зависит от стабильности интернет-канала и требований к скорости обмена. Для высоконагруженных систем с весовым оборудованием синхронный обмен через HTTP-сервисы является приоритетным.

← На главную