Как обойти проверку на уникальность кода узла (префикса) в планах обмена 1С

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

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

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

Почему 1С блокирует создание узлов с одинаковыми кодами?

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

Кроме того, префикс базы (который обычно совпадает с кодом узла) участвует в формировании номеров документов и кодов справочников. Дублирование префиксов в одной центральной базе может привести к коллизиям — ситуации, когда два разных документа из разных баз получат одинаковые номера.

Способ №1: Создание дублирующего плана обмена

Рассмотрим первый вариант обхода, предложенный в сообществе. Если стандартный план обмена СинхронизацияДанныхЧерезУниверсальныйФормат уже содержит узел с кодом ХА, платформа не даст создать второй такой же. Однако ограничение уникальности действует только в рамках одного конкретного плана обмена.

Пошаговый алгоритм действий:

  1. Откроем конфигуратор и найдем используемый план обмена.
  2. Создадим новый план обмена, который будет полной копией существующего (или наследовать его логику).
  3. В новом плане обмена мы сможем создать узел с кодом ХА, так как в этом пространстве имен данный код еще не занят.

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

Способ №2: Использование невидимых символов в коде

Разберем более простой, но «хитрый» способ. Платформа проверяет строковую уникальность. Для нее строки "БП" и "БП " (с неразрывным пробелом в конце) — это разные значения.

Выясним, как это реализовать:

Риски: Будьте осторожны, так как функции СокрЛП() или ТримП() в программном коде могут обрезать этот пробел, что снова приведет к конфликтам при поиске узла. Также это может повлиять на имена файлов выгрузки, если код узла используется в формировании пути.

Способ №3: Программная подмена префикса в XML-пакетах

Проанализируем самый профессиональный и безопасный подход. Мы оставляем коды узлов уникальными (например, БП1, БП2, БП3), чтобы платформа была «довольна». Но при этом мы модифицируем сами данные в момент обмена, чтобы целевая база воспринимала их как данные от префикса БП.

Для этого нам понадобится расширение конфигурации. Нам нужно вмешаться в процесс формирования сообщения обмена. Рассмотрим пример кода, который можно внедрить в процедуру перед отправкой данных:


// В модуле менеджера или через расширение в общем модуле ОбменДаннымиСервер
Процедура ПередОтправкойДанных(УзелИнформационнойБазы, ОтправкаДанных)
    
    // Проверяем, что это наш "особенный" узел
    Если УзелИнформационнойБазы.Код = "БП1" Тогда
        // Логика подмены кода отправителя в заголовке сообщения
        // Здесь мы можем программно изменить текст XML, заменив БП1 на БП
    КонецЕсли;

КонецПроцедуры

Разберем по шагам, что нужно сделать в рамках этого метода:

  1. Создаем узлы с уникальными кодами (БП1, БП2 и т.д.).
  2. В настройках синхронизации в регистре сведений ОбщиеНастройкиУзловИнформационныхБаз оставляем возможность сопоставления.
  3. Используем событие ПриОтправкеДанных (в правилах конвертации или через подписки на события), чтобы в XML-файле в поле КодОтправителя всегда записывалось значение БП.
  4. На стороне приемника используем событие ПриПриемеДанных, чтобы выполнить обратное преобразование: если файл пришел от БП, но мы знаем (по GUID или другим признакам), что это БП1, мы подставляем нужный узел плана обмена.

Способ №4: Использование расширения для подавления исключения БСП

Как мы видели в первом сообщении темы, ошибка часто генерируется программно в модуле менеджера Обработка.ПомощникСозданияОбменаДанными. Посмотрим на код, который вызывает прерывание:


Иначе
    ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
        НСтр("ru = 'Значение префикса программы ""%1"" не уникально (""%2"")...'"), 
        НастройкиПодключения.НаименованиеВторойБазы, КодНовогоУзла);
КонецЕсли;

Чтобы обойти эту проверку, создадим расширение и воспользуемся аннотацией &Вместо для метода, производящего проверку. Рассмотрим пример реализации:


&Вместо("ПроверитьУникальностьПрефикса")
Процедура Расш_ПроверитьУникальностьПрефикса(Параметры)
    // Просто оставляем тело процедуры пустым или пишем свою логику.
    // Это позволит помощнику пройти этап проверки.
    Возврат; 
КонецПроцедуры

Внимание: Подавление проверки в помощнике — это только половина дела. При вызове НовыйУзел.Записать() сама платформа 1С может выбросить ошибку, если в свойствах Плана Обмена в Конфигураторе стоит флажок «Уникальность кода». В типовых конфигурациях этот флаг обычно включен. Изменить его в расширении невозможно, поэтому данный метод сработает только в паре со Способом №2 (невидимые символы).

Резюме и рекомендации

Мы проанализировали ситуацию и выяснили, что требование уникальности префиксов — это фундаментальный механизм обеспечения целостности данных в 1С. Однако в сложных распределенных системах его приходится обходить.

Наш совет: наиболее стабильным решением является использование уникальных кодов узлов в базе (БП_ФИЛИАЛ1, БП_ФИЛИАЛ2) с последующей настройкой префиксации документов. В современных конфигурациях на базе БСП префикс номера документа можно хранить отдельно от кода узла плана обмена. Это позволит вам иметь уникальные узлы для синхронизации, но при этом сохранять привычную нумерацию документов с префиксом БП в обеих базах.

Если же это невозможно, используйте Способ №3 (программная подмена в XML) как наиболее гибкий и не нарушающий логику работы платформы.

← На главную