Обмен данными в 1С 8.3

Курс

Выгрузка данных

Для выгрузки зарегистрированных для узла плана обмена данных в XML файл используется следующий алгоритм:

  1. Создается объект ЗаписьXML
  2. Создается объект ЗаписьСообщенияОбмена
  3. В файл обмена записывается информация об отправителе и получателе
  4. Выполняется выборка зарегистрированных изменений для узла плана обмена
  5. Выборка обходится в цикле и выполняется сериализация объектов в XML
  6. Файл обмена закрывается

ЗаписьСообщенияОбмена

Объект ЗаписьСообщенияОбмена используется для формирования сообщения обмена. Данный объект создается с помощью метода СоздатьЗаписьСообщения:

С помощью метода НачатьЗапись выполняется связь данного объекта с объектом ЗаписьXML и узлом плана обмена, для которого будет формироваться сообщение. ЗаписьXML и узел передаются параметрами:

Вызов данного метода добавляет заголовок сообщения, который выглядит следующим образом:

Сообщение находится в корневом узле Message. У данного узла есть 2 вложенных узла:

  • Header — заголовок сообщения
  • Body — тело сообщения

Заголовок сообщения включает в себя следующую информацию:

  • Имя плана обмена — ExchangePlan
  • Код узла-получателя — To
  • Код узла-отправителя — From
  • Номер текущего сообщения — MessageNo
  • Номер последнего полученного сообщения — ReceivedNo

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

НомерОтправленного и НомерПринятого

При вызове метода НачатьЗапись из узла плана обмена читаются номера сообщений. В тег MessageNo записывается номер отправленного сообщения, увеличенный на единицу.

Сейчас в XML не закрыты теги Message и Body. Для их закрытия нужно вызвать метод ЗакончитьЗапись:

В результате файл обмена примет следующий вид:

Также при вызове метода ЗакончитьЗапись в узел плана обмена в реквизит НомерОтправленного записывается текущий номер сообщения.

Чтобы узел плана обмена не был изменен в период выгрузки, при вызове метода НачатьЗапись на узел устанавливается блокировка. При вызове метода ЗакончитьЗапись она снимается.

Также есть метод ПрерватьЗапись, который позволяет прервать запись сообщения обмена (блокировка тоже будет снята). В этом случае XML файл останется недописанным:

Выборка изменений плана обмена

Для получения выборки зарегистрированных изменений используется метод ВыбратьИзменения. Первым параметром передается узел, для которого получается выборка, вторым — номер сообщения, в котором будет выполнена выгрузка (как правило данный номер берется из объекта ЗаписьСообщенияОбмена). Именно этот номер сообщения будет записан в таблицы регистрации изменений в колонку Номер сообщения (только там где Номер сообщения был равен NULL). Затем выборка обходится в цикле и методом Получить получается зарегистрированный объект:

Третьим параметром можно передать отбор. Это может быть ссылка, массив ссылок, набор записей или объект метаданных:

Пример выгрузки данных

Выгрузка зарегистрированных изменений в XML файл может выглядеть следующим образом:

В результате будет получен следующий XML файл (при условии что было зарегистрировано 2 номенклатуры):

В данном примере в качестве имени файла обмена используется Exchange.xml. На практике удобно формировать имя файла обмена из кодов узлов плана обмена: КодУзлаОтправителя_КодУзлаПолучетеля.xml.

Пример записи только квитанции для одностороннего обмена:

Квитанция:

Загрузка данных

Алгоритм загрузки данных:

  1. Создается объект ЧтениеXML
  2. Создается объект ЧтениеСообщенияОбмена
  3. Из сообщения обмена читается заголовок
  4. Удаляется регистрация изменений
  5. В цикле читается сообщение обмена и выполняется десериализация данных
  6. Файл обмена закрывается

ЧтениеСообщенияОбмена

Объект ЧтениеСообщенияОбмена выполняет чтение сообщения обмена. Чтобы создать данный объект нужно вызвать метод СоздатьЧтениеСообщения:

Для связи с объектом ЧтениеXML нужно вызвать метод НачатьЧтение, передав ему параметром ЧтениеXML:

Метод НачатьЧтение читает из сообщения обмена заголовок сообщения и проверяет его корректность:

  • В узле ExchangePlan должно быть имя плана обмена, который есть в конфигурации, иначе будет получена ошибка «Неизвестный план обмена».
  • В узле To должен быть код узла, который есть в плане обмена, а также данный узел должен указывать на текущую базу. Иначе будет получена ошибка «Неизвестный получатель».
  • В узле MessageNo номер сообщения должен быть больше, чем реквизит НомерПринятого узла обмена, для которого выполняется загрузка данных.

Проверку номера сообщения можно переопределить. Для этого предназначен второй параметр. Можно не выполнять проверку номера сообщения или принимать только сообщения с номером на единицу больше реквизита НомерПринятого:

Если получена ошибка «Номер сообщения не является очередным», значит вторым параметром было указано значение Очередной и номер текущего сообщения больше чем на единицу больше последнего загруженного. Это может использоваться когда важен порядок сообщений и ни одно из них не может быть пропущено.

Если получена ошибка «Номер сообщения меньше или равен номеру ранее принятого сообщения», значит вторым параметром было указано значение Больший (или параметр не был заполнен) и номер загружаемого сообщения меньше или равен номеру последнего полученного сообщения. Это значит, что данное сообщение уже было загружено и нет смысла загружать его повторно. Или сбилась нумерация сообщений.

После загрузки всех данных нужно вызвать метод ЗакончитьЧтение:

После вызова данного метода в реквизит узла НомерПринятого будет записан номер из прочитанного сообщения.

На период чтения данных узел блокируется. Блокировка устанавливается при вызове метода НачатьЧтение и снимается при вызове метода ЗакончитьЧтение.

В любой момент можно прервать чтение сообщения. Для этого нужно вызвать метод ПрерватьЧтение:

В этом случае с узла плана обмена будет снята блокировка, но номер принятого сообщения в узле плана обмена не будет изменен.

Пример загрузки данных

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

Обмен данными с разной структурой

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

Есть 2 решения:

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

Рассмотрим первый вариант:

Запись ничем не отличается от примера выше. При чтении будем проверять тип загружаемого элемента и если это номенклатура, то будем читать вручную:

Здесь используются 2 вспомогательные функции:

Рассмотрим второй вариант. Здесь наоборот, чтение ничем не будет отличаться от типовой десериализации, а при записи для номенклатуры будем вручную формировать XML нужной структуры:

Вспомогательная процедура для записи номенклатуры:

Разрешение коллизий

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

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

Предопределенные элементы при обмене

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

Транзакции при обмене данными

При выгрузке и загрузке данных есть смысл использовать транзакции.

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

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


Подписывайтесь на группу ВКонтакте , где я публикую ссылки на новые статьи с данного сайта, а также интересные материалы с других ресурсов по программированию в 1С
Понравилась статья? Поделиться с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!:

Используя этот сайт, Вы даете согласие на использование cookies. На данном этапе Вы можете отказаться от использования cookies, настроив необходимые параметры в своем браузере.
ok