В практике разработчика 1С часто возникает задача передачи данных между двумя информационными базами. Ситуация усложняется, когда передаваемый объект — это не просто массив строк, а полноценная ТаблицаЗначений, содержащая как примитивные типы (строки, числа, даты), так и ссылки на элементы справочников. При этом в базе-приемнике этих элементов может не существовать, и их необходимо создать программно.
В данной статье мы подробно разберем несколько стратегий решения этой задачи: от использования универсальных механизмов платформы до гибкой настройки правил обмена. Мы проанализируем преимущества каждого метода и выясним, как правильно обрабатывать ссылочные данные, чтобы избежать появления "битых" ссылок или объекта "Объект не обнаружен".
Этот способ является одним из самых современных и легковесных. Основная идея заключается в том, что ссылочные данные нельзя передать "как есть", так как ссылка в одной базе не имеет смысла в другой. Однако мы можем передать УникальныйИдентификатор (GUID) этой ссылки.
Рассмотрим алгоритм действий. В базе-источнике нам необходимо обойти таблицу значений и для каждой ссылки получить ее GUID. Посмотрим на пример кода, который подготавливает данные для выгрузки:
// Пример подготовки ТЗ к выгрузке в JSON
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьФайл(ПутьКФайлу);
ЗаписьJSON.ЗаписатьНачалоМассива();
Для Каждого СтрокаТЗ Из ТаблицаДанных Цикл
ЗаписьJSON.ЗаписатьНачалоОбъекта();
// Примитивный тип
ЗаписьJSON.ЗаписатьИмяСвойства("Наименование");
ЗаписьJSON.ЗаписатьЗначение(СтрокаТЗ.Наименование);
// Ссылочный тип - передаем GUID
ЗаписьJSON.ЗаписатьИмяСвойства("Товар_GUID");
ЗаписьJSON.ЗаписатьЗначение(СтрокаТЗ.Товар.УникальныйИдентификатор());
ЗаписьJSON.ЗаписатьКонецОбъекта();
КонецЦикла;
ЗаписьJSON.ЗаписатьКонецМассива();
ЗаписьJSON.Закрыть();
Проанализируем ситуацию на стороне приемника. При чтении JSON мы получаем GUID. Нам нужно проверить, есть ли в текущей базе объект с таким идентификатором. Если его нет — создаем новый и присваиваем ему переданный GUID. Это критически важно для сохранения идентичности данных между базами.
// Пример загрузки в базе-приемнике
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.ОткрытьФайл(ПутьКФайлу);
Данные = ПрочитатьJSON(ЧтениеJSON);
Для Каждого ЭлементДанных Из Данные Цикл
СсылкаНаОбъект = Справочники.Номенклатура.ПолучитьСсылку(Новый УникальныйИдентификатор(ЭлементДанных.Товар_GUID));
// Проверяем, существует ли объект
Если СсылкаНаОбъект.ПолучитьОбъект() = Неопределено Тогда
// Создаем новый, если не нашли
НовыйОбъект = Справочники.Номенклатура.СоздатьЭлемент();
НовыйОбъект.УстановитьСсылкуНового(СсылкаНаОбъект);
НовыйОбъект.Наименование = ЭлементДанных.Наименование;
// Заполняем остальные реквизиты...
НовыйОбъект.Записать();
КонецЕсли;
КонецЦикла;
Если структуры метаданных в базах схожи, можно использовать СериализаторXDTO. Этот метод позволяет выгружать объекты целиком со всеми их реквизитами. Как было отмечено в обсуждении, XML умеет выгружать объект со всеми значениями реквизитов, но требует определенной аккуратности при сопоставлении схем.
Разберем пример использования СериализаторXDTO для выгрузки ссылки:
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ПутьКПапкеОбмена + ИмяФайла + ".xml");
// Используем фабрику XDTO для записи
Сериализатор = Новый СериализаторXDTO(ФабрикаXDTO);
Сериализатор.ЗаписатьXML(ЗаписьXML, СсылкаВыгрузки);
ЗаписьXML.Закрыть();
Важный нюанс: при загрузке через XML в базе-приемнике платформа попытается сопоставить типы. Если в приемнике отсутствуют какие-то реквизиты, которые есть в источнике, может возникнуть ошибка. Поэтому данный метод лучше всего подходит для баз с идентичной или очень близкой структурой (например, обмен между УТ и БП в рамках стандартных узлов).
Проанализировав советы опытных разработчиков, мы видим, что использование конфигурации "Конвертация данных" — это наиболее надежный и гибкий путь. Если в вашей таблице значений много ссылочных полей, и у этих полей есть свои вложенные ссылки (например, в справочнике "Номенклатура" есть ссылка на "ЕдиницыИзмерения"), то ручное описание всех связей в JSON станет трудоемким.
Выясним преимущества КД для данной задачи:
Параметры или как источник данных для выгрузки коллекции) и сопоставить ее с объектом приемника.Неопределено. Платформа берет на себя сопоставление типов.Если метаданные баз различаются значительно, рекомендуем использовать Конвертацию данных 3.0. Она работает через формат EnterpriseData (XDTO), что позволяет базе-источнику вообще "не знать" о структуре приемника, передавая данные в универсальном формате.
Если обе базы находятся в одной локальной сети и платформа позволяет использовать COM-соединение, это может быть самым быстрым способом реализации. Рассмотрим, как это работает программно:
Сначала мы создаем подключение к базе-приемнику, затем передаем данные из ТЗ построчно, вызывая методы поиска и создания объектов непосредственно в контексте второй базы.
// Подключение к базе-приемнику
COMСоединение = Новый COMОбъект("V83.COMConnector");
БазаПриемник = COMСоединение.Connect("Srvr='ServerName';Ref='BaseName';Usr='Login';Pwd='Password';");
Для Каждого СтрокаТЗ Из ИсточникТЗ Цикл
// Поиск объекта в приемнике по GUID из источника
GUIDСтрокой = Строка(СтрокаТЗ.СсылкаНаОбъект.УникальныйИдентификатор());
СсылкаВПриемнике = БазаПриемник.Справочники.Номенклатура.ПолучитьСсылку(БазаПриемник.NewObject("UUID", GUIDСтрокой));
ОбъектВПриемнике = СсылкаВПриемнике.GetObject();
Если ОбъектВПриемнике = Неопределено Тогда
// Если объекта нет, создаем его прямо через COM
НовыйЭлемент = БазаПриемник.Справочники.Номенклатура.CreateItem();
НовыйЭлемент.SetNewObjectRef(СсылкаВПриемнике);
НовыйЭлемент.Description = СтрокаТЗ.Наименование;
НовыйЭлемент.Write();
КонецЕсли;
КонецЦикла;
Важно: помните, что COM-соединение недоступно в некоторых средах (например, при использовании Linux-серверов 1С) и требует установленных идентичных версий платформы для стабильной работы.
Разберем ситуацию, которая часто ставит в тупик новичков: вы передали GUID, создали ссылку в приемнике, но не успели заполнить реквизиты объекта. В интерфейсе пользователя это выглядит как "Объект не обнаружен".
Чтобы избежать этой проблемы, рекомендуем использовать двухэтапный подход:
Для простых задач и небольшого количества типов метаданных оптимальным будет JSON-сериализация с передачей GUID. Если же задача предполагает регулярный обмен сложными структурами данных, то изучение и применение Конвертации данных окупится стократно, так как этот инструмент специально спроектирован для решения проблем сопоставления и создания объектов "на лету".
Рассмотренные методы позволяют гибко подходить к интеграции баз 1С, обеспечивая целостность ссылочных данных и автоматизацию создания необходимых справочников в базе-приемнике.