Перенос данных между идентичными или разнородными базами 1С через формат JSON — это стандартная задача, которая, на первый взгляд, кажется простой. Однако при реализации часто возникают сложности с восстановлением типов данных, обработкой ссылок (справочников, перечислений) и производительностью. В этой статье мы разберем несколько подходов: от использования базового объекта Соответствие до мощного механизма сериализации XDTO (поможет набор инструментов разработчика для отладки кода 1С).
Самый простой способ — прочитать данные в объект Соответствие (или Структура). Этот метод подходит, если структура JSON-файла проста и не содержит вложенных ссылочных типов, которые нужно превращать обратно в объекты базы данных. Для решения этой задачи есть универсальный ETL-инструмент для загрузки данных в 1С.
Разберем базовый алгоритм чтения:
// 1. Создаем объект ЧтениеJSON
ЧтениеJSON = Новый ЧтениеJSON;
// 2. Указываем путь к файлу
ЧтениеJSON.ОткрытьФайл("C:\Exchange\nomenclature.json");
// 3. Читаем данные в соответствие.
// Второй параметр "Истина" указывает на то, что JSON будет прочитан именно в Соответствие.
Данные = ПрочитатьJSON(ЧтениеJSON, Истина);
// 4. Закрываем поток чтения
ЧтениеJSON.Закрыть();
После получения переменной Данные, мы можем попытаться заполнить справочник — для этого подойдёт загрузка и обновление справочника номенклатуры для 1С. Рассмотрим ситуацию, когда у нас уже есть созданный объект справочника Номенклатура:
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
// Попытка прямого заполнения
ЗаполнитьЗначенияСвойств(НовыйЭлемент, Данные);
НовыйЭлемент.Записать();
Важное ограничение: метод ЗаполнитьЗначенияСвойств() сработает корректно только для простых типов (строки, числа, булево). Если в JSON записана ссылка на другой справочник (например, ВидНоменклатуры), то в Данные она попадет как обычная строка (например, ГУИД или наименование). 1С не сможет автоматически сопоставить строку с объектом базы данных.
Если нам необходимо передать ссылки, проанализируем ситуацию подробнее. Для идентичных баз лучшим решением будет синхронизация по Уникальному Идентификатору (UUID). В этом поможет обработка автоматической загрузки данных из JSON. В этом случае в JSON нужно выгружать строковое представление ГУИДа.
Рассмотрим, как правильно восстановить ссылку при загрузке:
// Предположим, в JSON есть поле "Ref_Key" с ГУИДом объекта
ИдентификаторСтрокой = Данные.Получить("Ref_Key");
Если ЗначениеЗаполнено(ИдентификаторСтрокой) Тогда
СсылкаНаОбъект = Справочники.Номенклатура.ПолучитьСсылку(Новый УникальныйИдентификатор(ИдентификаторСтрокой));
// Проверим, существует ли такой объект в базе
ОбъектСправочника = СсылкаНаОбъект.ПолучитьОбъект();
Если ОбъектСправочника = Неопределено Тогда
ОбъектСправочника = Справочники.Номенклатура.СоздатьЭлемент();
ОбъектСправочника.УстановитьСсылкуНового(СсылкаНаОбъект);
КонецЕсли;
// Заполняем остальные реквизиты, включая ссылочные
// Для ссылочных реквизитов (например, ВидНоменклатуры) нужно делать аналогичный поиск
ИдВида = Данные.Получить("ВидНоменклатуры_Ид");
ОбъектСправочника.ВидНоменклатуры = Справочники.ВидыНоменклатуры.ПолучитьСсылку(Новый УникальныйИдентификатор(ИдВида));
ОбъектСправочника.Наименование = Данные.Получить("Наименование");
ОбъектСправочника.Записать();
КонецЕсли;
Как отмечалось в обсуждении, для профессионального обмена данными между базами 1С лучше всего подходит СериализаторXDTO — есть готовый инструмент создания REST API для обмена данными через JSON. Этот механизм автоматически преобразует объекты 1С (со всеми ссылками и табличными частями) в JSON и обратно, сохраняя информацию о типах данных.
Выясним, как работает загрузка через сериализатор. При таком подходе нам не нужно использовать ЗаполнитьЗначенияСвойств(), так как система сама воссоздаст объект нужного типа.
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.ОткрытьФайл("C:\Exchange\data.json");
// Используем СериализаторXDTO для чтения
Пока ЧтениеJSON.Прочитать() Цикл
// Предполагаем, что в файле массив объектов
Если ЧтениеJSON.ТипТекущегоЗначения = ТипЗначенияJSON.НачалоОбъекта Тогда
// Десериализация сразу в объект справочника
ДанныеОбъекта = СериализаторXDTO.ПрочитатьJSON(ЧтениеJSON);
Если ТипЗнч(ДанныеОбъекта) = Тип("СправочникОбъект.Номенклатура") Тогда
// Объект уже заполнен, включая табличные части и ссылки
// Можно установить ОбменДанными.Загрузка = Истина, чтобы отключить проверки
ДанныеОбъекта.ОбменДанными.Загрузка = Истина;
ДанныеОбъекта.Записать();
КонецЕсли;
КонецЕсли;
КонецЦикла;
ЧтениеJSON.Закрыть();
Преимущество: этот метод "из коробки" поддерживает иерархию, владельцев и табличные части, если при выгрузке использовался метод ЗаписатьДанныеJSON с явным указанием типов.
Проанализируем дополнительные аспекты, которые помогут избежать ошибок при больших объемах данных:
ПрочитатьJSON(ЧтениеJSON, Истина). Это вызовет перегрузку оперативной памяти. Используйте цикл Пока ЧтениеJSON.Прочитать(), как показано в примере с XDTO.Родитель, но сам родитель еще не создан в базе. Рекомендуем выполнять загрузку в два прохода: сначала создавать все элементы без указания родителей, а вторым проходом проставлять связи.Соответствия помните, что табличные части — это массивы структур. Их нужно обходить в цикле, предварительно очищая ТЧ объекта методом Объект.ИмяТЧ.Очистить(), а затем добавляя строки методом Добавить().Записать() полезно сравнить данные из JSON с текущими данными объекта. Если изменений нет, запись лучше пропустить — это существенно ускорит процесс и уменьшит размер журнала регистрации.Подводя итог, можно сказать: если ваша задача — разовый перенос пары реквизитов, используйте Соответствие. Если же вы строите полноценную систему обмена между базами — выбирайте Сериализатор XDTO, так как он минимизирует ручной код и автоматически обрабатывает сложные типы данных 1С.