При организации обмена данными между конфигурациями «1С:Управление производственным предприятием» (УПП 1.3) разработчики часто сталкиваются со сложными архитектурными задачами. Одна из классических ситуаций — необходимость настроить раздельный обмен из одной многофирменной базы-источника в одну базу-приемник, разграничив потоки данных по конкретным организациям.
В процессе реализации такой схемы возникают две критические технические проблемы:
В этой статье мы подробно, шаг за шагом, разберем причины возникновения этих проблем и рассмотрим профессиональные способы их решения.
---
Выясним причину первой проблемы. В платформе «1С:Предприятие 8» для любого плана обмена в конкретной информационной базе может существовать только один предопределенный узел. В коде конфигурации он доступен через метод ПланыОбмена.ИмяПлана.ЭтотУзел(). Этот узел олицетворяет саму текущую базу.
Когда вы пытаетесь настроить два разных узла в источнике (например, код 002 для Организации 1 и код 003 для Организации 2), база-источник (код 001) генерирует файлы с именами Message_001_002.zip и Message_001_003.zip. Чтобы база-приемник успешно считала эти файлы стандартным механизмом, код ее предопределенного узла («ЭтотУзел») должен совпадать с кодом получателя в имени файла. Но узел в приемнике один, и его код не может быть одновременно и 002, и 003.
Рассмотрим три способа решения этой проблемы.
Поскольку база-приемник у нас одна, наиболее архитектурно правильным решением будет создание **одного** узла обмена (например, с кодом 002) как на стороне источника, так и на стороне приемника. Различающуюся логику для организаций мы перенесем непосредственно в правила конвертации данных (КД 2.1).
Для этого выполним следующие действия:
002.Если вам жизненно важно иметь абсолютно независимые каналы передачи данных, разные расписания и раздельные файлы обмена, можно пойти путем создания нового плана обмена в конфигураторе:
ОбменУППУПП).ОбменУППУПП_Орг2.Важное примечание: данный способ требует изменения метаданных. При последующих обновлениях конфигурации вам придется вручную отслеживать изменения в составе типового плана обмена и переносить их в свой добавленный план обмена.
Если вы хотите сохранить именно два узла в рамках одного плана обмена в источнике, но не хотите менять метаданные планов обмена, можно переписать логику формирования имени файла обмена в модулях выгрузки и загрузки:
002 и 003), а код предопределенного узла («Этот узел») устанавливаем равным 001 (код источника).Message_002_001.zip и Message_003_001.zip, где получателем выступает база 001.ПроцедурыОбменаДанными или аналогичный в УПП), чтобы имя файла формировалось динамически на основе кода узла-отправителя и узла-получателя, обходя стандартные жесткие ограничения платформы.---
Проанализируем вторую, более коварную проблему. Допустим, к обмену зарегистрировано 4 документа: 2 по Организации 1 и 2 по Организации 2. Мы запускаем выгрузку для Организации 1. В правилах конвертации (ПКО) у нас написан код проверки ИНН организации, и для документов Организации 2 срабатывает Отказ = Истина.
В файл выгрузки попадают только 2 документа. Однако после того как база-приемник присылает подтверждение приема (файл-ответ), в источнике **удаляется регистрация всех 4 документов**! Почему так происходит?
Это стандартное поведение платформы «1С:Предприятие 8». Процесс обмена выглядит так:
ПланыОбмена.ВыбратьИзменения(Узел, НомерСообщения). Все зарегистрированные на данный момент объекты на этом узле привязываются к номеру отправляемого сообщения (например, №10).Отказ = Истина, просто игнорируются и не записываются в XML-файл.ПланыОбмена.УдалитьРегистрациюИзменений(Узел, 10). Платформа удаляет из таблицы регистрации изменений все записи, которые были ассоциированы с сообщением №10, независимо от того, попали они физически в XML-файл или были отсечены правилами конвертации.Золотое правило разработки обменов в 1С: Фильтрация данных никогда не должна происходить «на лету» в правилах конвертации (ПКО/ПВД) через отказ от выгрузки, если эти объекты зарегистрированы на узле. Фильтрация должна осуществляться строго на этапе регистрации изменений!
Рассмотрим, как правильно решить эту проблему.
В конфигурации «Конвертация данных 2.1» помимо правил конвертации объектов (ПКО) создаются так называемые **Правила регистрации объектов (ПРО)**. Это наиболее гибкий и правильный инструмент:
Организация.002, а документы по Организации 2 — только на узле 003.При таком подходе документы Организации 2 физически никогда не будут зарегистрированы на узле Организации 1. Соответственно, они не попадут в выборку изменений для этого узла и их регистрация не пострадает при получении подтверждения.
Если вы не используете механизм ПРО, можно отключить автоматическую регистрацию документов и управлять ею программно через код:
Авторегистрация со значения Разрешить на Запретить.ПриЗаписи для этих документов.
Процедура ПередЗаписьюДокументаРегистрацияПриЗаписи(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
// Проверяем, что документ записывается не в процессе обмена (чтобы избежать зацикливания)
Если Источник.ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
// Определяем узлы обмена
УзелОрг1 = ПланыОбмена.ОбменУППУПП.НайтиПоКоду("002");
УзелОрг2 = ПланыОбмена.ОбменУППУПП.НайтиПоКоду("003");
// Выполняем выборочную регистрацию в зависимости от организации
Если Источник.Организация = Справочники.Организации.НайтиПоРеквизиту("ИНН", "7701000001") Тогда
Если ЗначениеЗаполнено(УзелОрг1) Тогда
ПланыОбмена.ЗарегистрироватьИзменения(УзелОрг1, Источник.Ссылка);
КонецЕсли;
ИначеЕсли Источник.Организация = Справочники.Организации.НайтиПоРеквизиту("ИНН", "7702000002") Тогда
Если ЗначениеЗаполнено(УзелОрг2) Тогда
ПланыОбмена.ЗарегистрироватьИзменения(УзелОрг2, Источник.Ссылка);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Этот способ гарантирует идеальную чистоту таблиц регистрации изменений. На узле Организации 1 будут находиться только изменения по Организации 1.
Рассмотрим ситуацию, когда архитектуру обмена менять уже поздно, обмен работает, и вам нужно быстро решить проблему «слета» регистрации «здесь и сейчас», не прибегая к изменению метаданных или написанию правил регистрации.
Мы можем принудительно вернуть регистрацию объекту в тот момент, когда правила конвертации принимают решение отказаться от его выгрузки. Для этого в правилах конвертации (например, в обработчике ПКО ПослеВыгрузкиОбъекта или в обработчиках выгрузки ПВД) при срабатывании условия отказа мы пишем следующий код:
// Если мы приняли решение не выгружать данный объект для этого узла
Если Объект.Организация <> Параметры.НужнаяОрганизация Тогда
Отказ = Истина;
// Принудительно регистрируем объект обратно на этот же узел.
// Объект зарегистрируется без привязки к текущему номеру сообщения
// и останется в базе после подтверждения приема текущего пакета.
ПланыОбмена.ЗарегистрироватьИзменения(ПараметрыПроцедуры.УзелДляВыгрузки, Объект.Ссылка);
КонецЕсли;
Важное предупреждение о производительности: этот метод имеет существенный минус. Объект при каждом обмене будет попадать в выборку изменений, считываться из базы данных, тратить процессорное время на обработку в КД, отбрасываться и заново регистрироваться. При больших объемах данных это приведет к лавинообразному снижению скорости обмена. Используйте его только в крайних случаях и для небольших справочников. Для документов всегда используйте Способ 2.1 или Способ 2.2.
---
Мы подробно проанализировали особенности работы планов обмена в «1С:Предприятие 8». При планировании архитектуры обмена данными помните:
Отказ = Истина для объектов, зарегистрированных на узле, без повторной их регистрации. Правильный путь — разграничение регистрации изменений на этапе записи объектов в базу данных с помощью подписок или правил регистрации (ПРО).