Как заполнить справочник 1С из JSON-файла при помощи соответствия или сериализации

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

Перенос данных между идентичными или разнородными базами 1С через формат JSON — это стандартная задача, которая, на первый взгляд, кажется простой. Однако при реализации часто возникают сложности с восстановлением типов данных, обработкой ссылок (справочников, перечислений) и производительностью. В этой статье мы разберем несколько подходов: от использования базового объекта Соответствие до мощного механизма сериализации XDTO (поможет набор инструментов разработчика для отладки кода 1С).

Вариант 1: Чтение JSON в Соответствие и ручное заполнение реквизитов

Самый простой способ — прочитать данные в объект Соответствие (или Структура). Этот метод подходит, если структура JSON-файла проста и не содержит вложенных ссылочных типов, которые нужно превращать обратно в объекты базы данных. Для решения этой задачи есть универсальный ETL-инструмент для загрузки данных в 1С.

Разберем базовый алгоритм чтения:


// 1. Создаем объект ЧтениеJSON
ЧтениеJSON = Новый ЧтениеJSON;

// 2. Указываем путь к файлу
ЧтениеJSON.ОткрытьФайл("C:\Exchange\nomenclature.json");

// 3. Читаем данные в соответствие. 
// Второй параметр "Истина" указывает на то, что JSON будет прочитан именно в Соответствие.
Данные = ПрочитатьJSON(ЧтениеJSON, Истина);

// 4. Закрываем поток чтения
ЧтениеJSON.Закрыть();

После получения переменной Данные, мы можем попытаться заполнить справочник — для этого подойдёт загрузка и обновление справочника номенклатуры для 1С. Рассмотрим ситуацию, когда у нас уже есть созданный объект справочника Номенклатура:


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

Важное ограничение: метод ЗаполнитьЗначенияСвойств() сработает корректно только для простых типов (строки, числа, булево). Если в JSON записана ссылка на другой справочник (например, ВидНоменклатуры), то в Данные она попадет как обычная строка (например, ГУИД или наименование). 1С не сможет автоматически сопоставить строку с объектом базы данных.

Вариант 2: Восстановление ссылочных типов по идентификатору

Если нам необходимо передать ссылки, проанализируем ситуацию подробнее. Для идентичных баз лучшим решением будет синхронизация по Уникальному Идентификатору (UUID). В этом поможет обработка автоматической загрузки данных из JSON. В этом случае в JSON нужно выгружать строковое представление ГУИДа.

Рассмотрим, как правильно восстановить ссылку при загрузке:


// Предположим, в JSON есть поле "Ref_Key" с ГУИДом объекта
ИдентификаторСтрокой = Данные.Получить("Ref_Key");
Если ЗначениеЗаполнено(ИдентификаторСтрокой) Тогда
    СсылкаНаОбъект = Справочники.Номенклатура.ПолучитьСсылку(Новый УникальныйИдентификатор(ИдентификаторСтрокой));
    
    // Проверим, существует ли такой объект в базе
    ОбъектСправочника = СсылкаНаОбъект.ПолучитьОбъект();
    Если ОбъектСправочника = Неопределено Тогда
        ОбъектСправочника = Справочники.Номенклатура.СоздатьЭлемент();
        ОбъектСправочника.УстановитьСсылкуНового(СсылкаНаОбъект);
    КонецЕсли;
    
    // Заполняем остальные реквизиты, включая ссылочные
    // Для ссылочных реквизитов (например, ВидНоменклатуры) нужно делать аналогичный поиск
    ИдВида = Данные.Получить("ВидНоменклатуры_Ид");
    ОбъектСправочника.ВидНоменклатуры = Справочники.ВидыНоменклатуры.ПолучитьСсылку(Новый УникальныйИдентификатор(ИдВида));
    
    ОбъектСправочника.Наименование = Данные.Получить("Наименование");
    ОбъектСправочника.Записать();
КонецЕсли;

Вариант 3: Использование Сериализатора XDTO

Как отмечалось в обсуждении, для профессионального обмена данными между базами 1С лучше всего подходит СериализаторXDTO — есть готовый инструмент создания REST API для обмена данными через JSON. Этот механизм автоматически преобразует объекты 1С (со всеми ссылками и табличными частями) в JSON и обратно, сохраняя информацию о типах данных.

Выясним, как работает загрузка через сериализатор. При таком подходе нам не нужно использовать ЗаполнитьЗначенияСвойств(), так как система сама воссоздаст объект нужного типа.


ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.ОткрытьФайл("C:\Exchange\data.json");

// Используем СериализаторXDTO для чтения
Пока ЧтениеJSON.Прочитать() Цикл
    // Предполагаем, что в файле массив объектов
    Если ЧтениеJSON.ТипТекущегоЗначения = ТипЗначенияJSON.НачалоОбъекта Тогда
        // Десериализация сразу в объект справочника
        ДанныеОбъекта = СериализаторXDTO.ПрочитатьJSON(ЧтениеJSON);
        
        Если ТипЗнч(ДанныеОбъекта) = Тип("СправочникОбъект.Номенклатура") Тогда
            // Объект уже заполнен, включая табличные части и ссылки
            // Можно установить ОбменДанными.Загрузка = Истина, чтобы отключить проверки
            ДанныеОбъекта.ОбменДанными.Загрузка = Истина;
            ДанныеОбъекта.Записать();
        КонецЕсли;
    КонецЕсли;
КонецЦикла;

ЧтениеJSON.Закрыть();

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

Особенности и тонкие моменты загрузки

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

  1. Потоковое чтение: Если в справочнике десятки тысяч элементов, не читайте весь файл в память методом ПрочитатьJSON(ЧтениеJSON, Истина). Это вызовет перегрузку оперативной памяти. Используйте цикл Пока ЧтениеJSON.Прочитать(), как показано в примере с XDTO.
  2. Иерархия и порядок записи: При загрузке иерархических справочников может возникнуть ситуация, когда у элемента уже указан Родитель, но сам родитель еще не создан в базе. Рекомендуем выполнять загрузку в два прохода: сначала создавать все элементы без указания родителей, а вторым проходом проставлять связи.
  3. Табличные части: При использовании Соответствия помните, что табличные части — это массивы структур. Их нужно обходить в цикле, предварительно очищая ТЧ объекта методом Объект.ИмяТЧ.Очистить(), а затем добавляя строки методом Добавить().
  4. Проверка изменений: Перед вызовом метода Записать() полезно сравнить данные из JSON с текущими данными объекта. Если изменений нет, запись лучше пропустить — это существенно ускорит процесс и уменьшит размер журнала регистрации.

Подводя итог, можно сказать: если ваша задача — разовый перенос пары реквизитов, используйте Соответствие. Если же вы строите полноценную систему обмена между базами — выбирайте Сериализатор XDTO, так как он минимизирует ручной код и автоматически обрабатывает сложные типы данных 1С.

← На главную