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

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

При обмене данными между различными базами 1С часто возникает проблема передачи ссылок на объекты. Например, если мы выгружаем документ "Приходная накладная" в XML и передаем его в другую базу, ссылки на номенклатуру, склад или подразделение, которые хранятся в исходной базе, могут оказаться "незначимыми" для базы-приемника. Это происходит потому, что в разных базах одни и те же сущности (например, "Стулья" или "Основной склад") могут иметь разные внутренние идентификаторы (ссылки), или вовсе отсутствовать в принимающей системе. Рассмотрим подробно, как мы можем решить эту распространенную задачу и организовать перенос объектов 1С.

Поиск и сопоставление объектов: Общий подход

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

Для успешного сопоставления нам доступны несколько ключевых методов:

  1. Поиск по уникальному идентификатору (GUID/UUID): Это наиболее надежный способ, так как GUID является глобально уникальным и, как правило, не меняется в течение жизненного цикла объекта.
  2. Поиск по комбинации реквизитов: Если GUID объекта отсутствует или не совпадает (например, объекты были созданы независимо в разных базах), мы можем использовать комбинацию уникальных полей, таких как наименование, код, артикул, ИНН (для контрагентов) и других атрибутов, которые однозначно идентифицируют объект.

Использование универсальных идентификаторов (GUID/UUID)

Каждый объект в системе 1С:Предприятие 8 обладает внутренним уникальным идентификатором, который мы часто называем GUID (Globally Unique Identifier) или UUID (Universally Unique Identifier). Этот идентификатор является строковым представлением 16-байтового числа и гарантирует уникальность объекта в масштабах всей системы и даже за ее пределами. GUID остается неизменным для объекта на протяжении всего его существования.

Принцип работы: Когда мы выгружаем данные в XML, вместе с другими реквизитами объекта мы передаем и его GUID. При загрузке в другую базу 1С система в первую очередь попытается найти соответствующий объект именно по этому GUID. Если объект с таким GUID найден, то ссылка на него в принимающем документе будет установлена корректно. Это наиболее прямой и эффективный способ сопоставления.

Механизм Регистра сведений "Публичные идентификаторы синхронизируемых объектов" (РПИ)

В реальных сценариях обмена данными объекты в разных базах могут иметь разные GUID, даже если по сути они представляют собой одну и ту же сущность (например, "Товар А" был создан независимо в двух базах). Для решения этой проблемы в 1С используется специальный Регистр сведений "Публичные идентификаторы синхронизируемых объектов" (РПИ).

Как работает: Этот регистр хранит информацию о соответствии объектов между различными узлами обмена. Когда мы получаем данные из другой базы, система пытается сопоставить объекты. Если объект найден по другим признакам (например, по наименованию и артикулу), но имеет другой GUID, в РПИ создается запись, связывающая GUID объекта-источника с GUID объекта-приемника. Это позволяет поддерживать ссылочную целостность и корректно идентифицировать объекты, которые "живут" в разных базах под разными внутренними идентификаторами. Записи в РПИ автоматически создаются и обновляются при получении и отправке данных в рамках настроенных механизмов обмена.

Развитые механизмы сопоставления в "1С:Конвертации Данных" (КД2/КД3)

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

1. Правила конвертации объектов (ПКО)

В КД2/КД3 основной единицей настройки являются Правила конвертации объектов (ПКО). Для каждого типа объекта, который мы хотим передавать (например, "Номенклатура", "Склады", "Контрагенты"), мы создаем отдельное ПКО. В ПКО мы определяем, как объект из базы-источника должен быть преобразован в объект базы-приемника. Здесь же настраиваются и правила поиска:

  1. Мы указываем, что сначала нужно попытаться найти объект-приемник по ИдентификаторуОбъектаИсточника (то есть по GUID). Это первичный и наиболее приоритетный метод.
  2. Если поиск по GUID не дал результата (например, объект с таким GUID отсутствует в базе-приемнике), мы переходим к следующим шагам.

2. Поля поиска

Если поиск по GUID не увенчался успехом, мы можем задать поля поиска. Это реквизиты объекта, которые в совокупности должны уникально идентифицировать объект. Для разных типов объектов мы выбираем разные комбинации полей:

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

3. Обработчики событий

"Конвертация данных" предоставляет мощный механизм обработчиков событий, который позволяет нам реализовать сложную программную логику сопоставления, трансформации данных и создания недостающих объектов. Это особенно полезно в ситуациях, когда простые правила поиска по GUID или комбинации полей недостаточны.

Основные обработчики, которые мы используем для решения нашей задачи:

Рассмотрим пример кода для обработчика ПослеЗагрузки в ПКО для номенклатуры, где мы можем реализовать более сложную логику поиска, если объект не был найден стандартными способами:


// В обработчике "ПослеЗагрузки" для ПКО "Номенклатура"
// ОбъектПриемник - это объект, который был найден или создан в базе-приемнике.
// Если ОбъектПриемник не заполнен (т.е. объект не был найден или создан),
// мы можем попробовать найти его по нестандартным правилам.

Если ОбъектПриемник.Пустая() Тогда
    // Объект не найден по стандартным правилам (GUID, поля поиска).
    // Попробуем найти по Наименованию и ДополнительномуРеквизиту (если такой есть в источнике)
    
    // Получаем исходный объект из базы-источника
    ИсходныйОбъект = Источник; // Переменная Источник доступна в обработчиках
    
    Если Не ИсходныйОбъект.Пустая() Тогда
        ПоискПоНаименованию = ИсходныйОбъект.Наименование;
        ПоискПоАртикулу = ИсходныйОбъект.Артикул;

        Запрос = Новый Запрос;
        Запрос.Текст = 
        "ВЫБРАТЬ ПЕРВЫЕ 1
        |    Номенклатура.Ссылка
        |ИЗ
        |    Справочник.Номенклатура КАК Номенклатура
        |ГДЕ
        |    Номенклатура.Наименование = &Наименование
        |    И Номенклатура.Артикул = &Артикул";
        
        Запрос.УстановитьПараметр("Наименование", ПоискПоНаименованию);
        Запрос.УстановитьПараметр("Артикул", ПоискПоАртикулу);
        
        РезультатЗапроса = Запрос.Выполнить().Выбрать();
        
        Если РезультатЗапроса.Следующий() Тогда
            // Объект найден по нестандартной логике
            ОбъектПриемник = РезультатЗапроса.Ссылка;
            
            // Важно: установить найденную ссылку в параметры обмена,
            // чтобы система использовала ее для дальнейших ссылок
            ВыгрузитьПоПравилу(ОбъектПриемник, ОбъектПриемник);
        Иначе
            // Объект не найден, создаем новый
            НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
            НовыйЭлемент.Наименование = ПоискПоНаименованию;
            НовыйЭлемент.Артикул = ПоискПоАртикулу;
            // Заполнить другие необходимые реквизиты
            
            Попытка
                НовыйЭлемент.Записать();
                ОбъектПриемник = НовыйЭлемент.Ссылка;
                // Также выгружаем по правилу для использования дальше
                ВыгрузитьПоПравилу(ОбъектПриемник, ОбъектПриемник);
            Исключение
                Сообщить("Не удалось создать номенклатуру: " + ОписаниеОшибки());
            КонецПопытки;
        КонецЕсли;
    КонецЕсли;
КонецЕсли;

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

4. Параметры

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

Дополнительные подходы и механизмы

1. Префиксация объектов при синхронизации

Для предотвращения конфликтов при создании новых элементов в разных базах, особенно в децентрализованных системах, мы часто используем префиксацию объектов. Каждый узел обмена (база) получает уникальный префикс (например, "Б01-" для первой базы, "Б02-" для второй). Этот префикс добавляется к кодам создаваемых объектов (документов, элементов справочников). Например, "Б01-000001" и "Б02-000001". Это позволяет различать объекты, созданные в разных базах, до их окончательного сопоставления. После сопоставления по GUID или другим признакам префиксы могут быть удалены или сохранены как часть идентификации.

2. Использование внешних обработок для сопоставления данных

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

3. Распределенные информационные базы (РИБ)

Если мы говорим об обмене данными между идентичными конфигурациями 1С (то есть, это одна и та же конфигурация, развернутая на нескольких узлах), то Распределенные информационные базы (РИБ) являются типовым и наиболее эффективным механизмом. РИБ обеспечивают автоматическую синхронизацию изменений данных и конфигурации между узлами, основываясь на внутренних механизмах платформы, которые включают идентификацию объектов по GUID. В этом случае нам не нужно разрабатывать сложные правила сопоставления, так как платформа берет это на себя. Однако для обмена с разными конфигурациями или внешними системами РИБ не подходят.

4. Контроль записи объектов при обмене (ОбменДанными.Загрузка)

При загрузке данных через механизмы обмена, особенно в "Конвертации данных", нам часто требуется отключить стандартные проверки, которые выполняются при интерактивной записи объектов пользователем. Это необходимо для того, чтобы избежать ошибок, связанных с бизнес-логикой, которая может быть неактуальна или избыточна при массовой загрузке данных. Для этого мы используем специальный атрибут объекта ОбменДанными.Загрузка.

Когда мы устанавливаем свойство ОбменДанными.Загрузка = Истина для объекта перед его записью, система 1С понимает, что запись происходит в рамках обмена данными. Это приводит к следующим эффектам:

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


// Предположим, мы создаем новый элемент номенклатуры в обработчике "ПослеЗагрузки"
// или в другом месте при программном создании объектов в рамках обмена.

НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовыйЭлемент.Наименование = "Стул офисный";
// ... заполняем другие реквизиты ...

// Устанавливаем флаг загрузки данных
НовыйЭлемент.ОбменДанными.Загрузка = Истина;

Попытка
    НовыйЭлемент.Записать();
    Сообщить("Объект успешно записан при загрузке.");
Исключение
    Сообщить("Ошибка записи объекта при загрузке: " + ОписаниеОшибки());
КонецПопытки;

Использование этого флага позволяет нам более гибко управлять процессом загрузки и избежать ненужных ошибок, которые могут возникнуть из-за несоответствия данных или специфики бизнес-логики.

5. Архитектурные решения

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

Таким образом, решение проблемы "незначимых" ссылок при обмене данными между базами 1С включает в себя комбинацию из использования уникальных идентификаторов объектов, настройки правил сопоставления в "Конвертации Данных" (по GUID и/или дополнительным полям), применения механизмов префиксации, а в сложных случаях – программной обработки с использованием обработчиков событий и вспомогательных регистров. Выбор конкретного подхода зависит от сложности задачи, объема данных и требований к обмену.

← На главную