Переход с устаревших редакций конфигураций на новые версии, использующие Библиотеку стандартных подсистем (БСП), часто преподносит неприятные сюрпризы разработчикам и системным администраторам. Типичный пример — обновление конфигурации Бухгалтерия для Украины с редакции 1.2 (на обычных формах) на редакцию 2.0 (на управляемых формах), в то время как источником данных остается сильно доработанная Управление производственным предприятием (УПП) 1.3. Старые, годами проверенные механизмы обмена внезапно перестают работать, выдавая нестыковки форматов и отсутствие необходимых объектов метаданных.
В этой статье мы подробно проанализируем, почему ломается привычный автоматический обмен между УПП и Бухгалтерией 2.0, разберем причины возникновения популярных ошибок конфигурации и рассмотрим надежные практические варианты восстановления бесперебойного автоматического обмена.
---
Для начала выясним, какие именно изменения в архитектуре новой Бухгалтерии 2.0 блокируют работу старых механизмов обмена данными.
В старых конфигурациях (включая Бухгалтерию 1.2) регламентный обмен опирался на экспортно-импортную обработку Обработка.ОбменДаннымиXML. При переходе на управляемый интерфейс и БСП в Бухгалтерии 2.0 эта обработка была полностью удалена из метаданных. Вместо нее подсистема обмена БСП использует общий модуль КонвертацияОбъектовИнформационныхБаз. Попытка старого кода из УПП обратиться по COM-соединению к отсутствующему объекту ОбменДаннымиXML в приемнике закономерно вызывает фатальную ошибку.
Пытаясь настроить обмен через файлы, разработчики часто сталкиваются с отказом системы принимать XML-выгрузку. Механизм БСП при чтении файлов обмена жестко требует наличия специального конверта платформы — XML-сообщения. Структура этого файла должна иметь корневой тег v8msg:Message, а также служебные секции заголовка v8msg:Header (содержащие номера сообщений, код отправителя и получателя) и тело сообщения v8msg:Body. Стандартный XML-файл, генерируемый обработкой УниверсальныйОбменДаннымиXML, содержит корневой тег ФайлОбмена без служебных конвертов БСП, что и вызывает отказ парсера.
В ранних версиях Бухгалтерии для Украины 2.0 поддержка универсального формата EnterpriseData либо полностью отсутствует, либо находится в зачаточном состоянии. Попытки развернуть обмен через современные механизмы ED не увенчаются успехом, так как конфигурация попросту не содержит необходимых общих модулей (например, МенеджерОбменаЧерезУниверсальныйФормат) и схем формата.
В старых конфигурациях сопоставление объектов фиксировалось в регистре сведений СоответствиеОбъектовДляОбмена. В новых базах на БСП этот регистр заменен на СоответствиеОбъектовИнформационныхБаз. Если правила конвертации данных (КД 2.1) не обучены работать с новым регистром БСП, при каждом сеансе обмена система будет дублировать данные или записывать их некорректно. Кроме того, при выгрузке транзакциями (порциями) дочерние элементы справочников могут загружаться раньше своих родителей, что напрочь разрушает иерархию (например, в справочниках "Номенклатура" или "Контрагенты").
---
Рассмотрим первый практический метод, предложенный сообществом. Он позволяет сохранить регистрацию изменений и автоматизировать процесс без изменения кода в Бухгалтерии 2.0. Суть метода заключается в программной инициализации обработки УниверсальныйОбменДаннымиXML на стороне источника и приемника, а также ручной очистке регистрации изменений после подтверждения успешной транзакции.
Для корректной работы обработки УниверсальныйОбменДаннымиXML с планами обмена (чтобы регистрировать изменения и выгружать только новое) нам необходимо программно передать ей узел обмена. Выполним это следующим образом:
Шаг 1. Перенесем процедуру установки узла обмена из модуля формы обработки УниверсальныйОбменДаннымиXML в общий модуль УПП (доступный на сервере) или непосредственно в наш скрипт выгрузки:
Процедура УстановитьУзелОбменаУСтрокДерева(СтрокиДерева, Знач УзелОбмена) Экспорт
Для Каждого СтрокаДерева Из СтрокиДерева Цикл
СтрокаДерева.УзелОбменаДляРегистрацииИзменений = УзелОбмена;
УстановитьУзелОбменаУСтрокДерева(СтрокаДерева.Строки, УзелОбмена);
КонецЦикла;
КонецПроцедуры
Шаг 2. Разработаем процедуру выгрузки на стороне УПП, которая создаст СОМ-соединение с Бухгалтерией 2.0, загрузит правила, выполнит выгрузку-загрузку данных и корректно очистит регистрацию объектов:
Процедура ВыполнитьРегламентныйОбмен() Экспорт
// 1. Инициализируем COM-соединение с Бухгалтерией 2.0
ПараметрыПодключения = "Srvr=""Server1C"";Ref=""Accounting_2_0"";Usr=""ExchangeUser"";Pwd=""Password"";";
COMConnector = Новый COMОбъект("V83.COMConnector");
Попытка
БазаПриемник = COMConnector.Connect(ПараметрыПодключения);
Исключение
ЗаписатьЛогСобытий("Ошибка подключения к Бухгалтерии: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
// 2. Инициализируем обработку выгрузки в УПП (Источник)
ОбработкаВыгрузки = Обработки.УниверсальныйОбменДаннымиXML.Создать();
ОбработкаВыгрузки.ИмяФайлаПравилКонвертации = "C:\Exchange\Rules_UPP_to_BUH.xml";
ОбработкаВыгрузки.РежимОбмена = "Выгрузка";
ОбработкаВыгрузки.ЗагрузитьПравилаОбмена();
// Передаем узел обмена в таблицу правил для отслеживания изменений
ВыбранныйУзел = ПланыОбмена.УдаленныйОбменУПП_Бух.НайтиПоКоду("БП");
УстановитьУзелОбменаУСтрокДерева(ОбработкаВыгрузки.ТаблицаПравилКонвертации.Строки, ВыбранныйУзел);
// Блокируем автоматическое снятие регистрации изменений встроенными средствами
ОбработкаВыгрузки.ТипУдаленияРегистрацииИзмененийДляУзловОбменаПослеВыгрузки = 0;
// Записываем выгружаемые объекты во вспомогательный Регистр Сведений для последующего квитирования
// (например, "РегистрВыгруженныхОбъектов") перед началом фактического экспорта.
ТаблицаИзменений = ПланыОбмена.ВыбратьИзменения(ВыбранныйУзел, 1);
Пока ТаблицаИзменений.Следующий() Цикл
ЗаписатьВВспомогательныйРегистр(ТаблицаИзменений.Выборка.Ссылка, ВыбранныйУзел);
КонецЦикла;
// Выполняем выгрузку во временный файл
ВременныйФайлОбмена = "C:\Exchange\temp_transfer.xml";
ОбработкаВыгрузки.ИмяФайлаОбмена = ВременныйФайлОбмена;
ОбработкаВыгрузки.ВыгрузитьДанные();
// 3. Инициализируем обработку загрузки в Бухгалтерии через COM-соединение
ОбработкаЗагрузки = БазаПриемник.Обработки.УниверсальныйОбменДаннымиXML.Создать();
ОбработкаЗагрузки.ИмяФайлаОбмена = ВременныйФайлОбмена;
ОбработкаЗагрузки.РежимОбмена = "Загрузка";
Попытка
ОбработкаЗагрузки.ВыполнитьЗагрузку();
УспешнаяЗагрузка = Истина;
Исключение
УспешнаяЗагрузка = Ложь;
ЗаписатьЛогСобытий("Ошибка загрузки данных в приемник: " + ОписаниеОшибки());
КонецПопытки;
// 4. Квитирование (снятие регистрации изменений при успешном завершении)
Если УспешнаяЗагрузка Тогда
ОчиститьРегистрациюИзмененийПоРегистру(ВыбранныйУзел);
КонецЕсли;
КонецПроцедуры
Использование вспомогательного регистра сведений гарантирует, что мы удалим регистрацию изменений только для тех объектов, которые действительно были отправлены в этом сеансе обмена, исключая потерю данных, измененных пользователями во время самого процесса выгрузки.
---
Если прямое COM-соединение использовать нежелательно (например, базы находятся на разных серверах или в закрытых сетях), мы можем организовать полностью изолированный файловый обмен. Чтобы обойти требование БСП к заголовкам XML-конвертов, мы откажемся от стандартной синхронизации БСП и настроим работу через планировщик задач 1С (Регламентные задания).
Проанализируем пошаговый алгоритм настройки такой схемы:
\\FileServer\1C_Exchange\).
Пишем процедуру, которая выгружает изменения через обработку УниверсальныйОбменДаннымиXML в файл data_export.xml. По окончании выгрузки процедура создает в каталоге пустой маркерный файл ready_to_load.txt.
Каждые 10-15 минут Бухгалтерия проверяет наличие файла-маркера ready_to_load.txt. Если файл найден, Бухгалтерия запускает внутренний экземпляр обработки УниверсальныйОбменДаннымиXML в режиме загрузки и читает данные из data_export.xml.
После успешной загрузки Бухгалтерия удаляет файл ready_to_load.txt, удаляет файл данных data_export.xml и создает файл-подтверждение exchange_confirmed.txt. УПП, обнаружив этот файл при следующем запуске, программно очищает регистрацию изменений для отправленных ранее объектов и удаляет файл-подтверждение.
Этот подход полностью избавляет нас от необходимости дорабатывать модули конфигурации Бухгалтерии 2.0, оставляя ее на полной поддержке. Все интеграционные скрипты могут находиться во внешних обработках, запускаемых стандартными регламентными заданиями.
---
Рассмотрим, как решить проблемы с дублированием данных, сбитыми GUID и нарушением иерархии справочников. Для этого нам потребуется открыть наши правила обмена в конфигурации 1С:Конвертация данных 2.1 и внести важные изменения.
Когда при загрузке дочерние элементы записываются в корень, это означает, что родительская группа еще не была создана на момент записи элемента. Решим это через настройки ПКО (Правила конвертации объектов):
Номенклатура или Контрагенты).Родитель.Это заставит выгрузчик сначала полностью обработать и записать структуру родительской группы, и только затем приступать к записи дочернего элемента. При загрузке элемент гарантированно найдет свою группу-родителя.
Чтобы избежать появления дублей при последующих обменах, нам необходимо научить правила обмена делать записи в новый регистр БСП СоответствиеОбъектовИнформационныхБаз. Для этого в ПКО ключевых справочников добавим следующий код в обработчик события «После загрузки»:
// Проверим, является ли объект новым, или сопоставим его принудительно
Если Объект.ЭтоНовый() Или Параметры.ЗаписыватьСоответствиеБСП Тогда
СсылкаПриемника = Объект.Ссылка;
УникальныйИдентификаторИсточника = ПараметрыОбъекта["УИДИсточника"];
ИмяПланаОбмена = "УдаленныйОбменУПП_Бух";
УзелОбмена = ПланыОбмена[ИмяПланаОбмена].НайтиПоКоду("УПП");
Если ЗначениеЗаполнено(УзелОбмена) И ЗначениеЗаполнено(УникальныйИдентификаторИсточника) Тогда
МенеджерЗаписи = РегистрыСведений.СоответствиеОбъектовИнформационныхБаз.СоздатьМенеджерЗаписи();
МенеджерЗаписи.УзелИнформационнойБазы = УзелОбмена;
МенеджерЗаписи.СобственнаяСсылка = СсылкаПриемника;
МенеджерЗаписи.УникальныйИдентификаторИсточника = УникальныйИдентификаторИсточника;
МенеджерЗаписи.ТипИсточника = "СправочникСсылка." + Объект.Метаданные().Имя;
МенеджерЗаписи.ТипПриемника = "СправочникСсылка." + Объект.Метаданные().Имя;
МенеджерЗаписи.Записать();
КонецЕсли;
КонецЕсли;
Для корректной работы этого обработчика не забудем передавать уникальный идентификатор (GUID) источника в качестве параметра при выгрузке. Сделать это можно в ПКО в событии «Перед выгрузкой»:
ПараметрыВыгрузки.Вставить("УИДИсточника", Строка(Источник.УникальныйИдентификатор()));
---
Мы проанализировали основные технические сложности, возникающие при автоматизации обмена данными между УПП 1.3 и обновленной Бухгалтерией для Украины 2.0. Подводя итоги, дадим несколько важных рекомендаций:
Используя предложенные методики и фрагменты кода, вы сможете быстро восстановить автоматический регламентный обмен и гарантировать абсолютную идентичность данных в обеих информационных базах.