Как упаковать справочник или документ 1С в JSON: разбираем проверенные способы

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

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

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

Почему стандартная ЗаписатьJSON выдает ошибку?

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

Рассмотрим основной способ решения этой задачи, который встроен в платформу.

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

Это самый быстрый способ "упаковать" объект со всеми его реквизитами и табличными частями. Секрет успеха заключается в правильной передаче данных методу. Если вы передадите ссылку (СправочникСсылка), в JSON попадет только UUID. Чтобы получить все данные, необходимо передать именно Объект.

Разберем реализацию этого метода по шагам:


// Предположим, у нас есть ссылка на физическое лицо
ИсточникСсылка = Справочники.ФизическиеЛица.НайтиПоКоду("001");

// Обязательно получаем объект, чтобы получить доступ к его данным
ИсточникОбъект = ИсточникСсылка.ПолучитьОбъект();

ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();

// Используем глобальный объект СериализаторXDTO
// Параметр НазначениеТипаXML.Неявное позволяет сделать JSON чище (без технических полей #type)
СериализаторXDTO.ЗаписатьJSON(ЗаписьJSON, ИсточникОбъект, НазначениеТипаXML.Неявное);

СтрокаJSON = ЗаписьJSON.Закрыть();
Сообщить(СтрокаJSON);

Важный нюанс: при использовании НазначениеТипаXML.Явное 1С добавит в JSON техническое поле "#type". Это полезно, если вы планируете читать этот JSON обратно в другой базе 1С. Если же данные уходят во внешнюю систему (сайт на PHP, Python-скрипт), используйте Неявное.

Способ 2: Преобразование в структуру (универсальный подход)

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

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


Функция ОбъектВСтруктуру(ДанныеОбъекта)
    
    Результат = Новый Структура;
    МетаданныеОбъекта = ДанныеОбъекта.Метаданные();
    
    // 1. Обрабатываем основные реквизиты
    Для Каждого Реквизит Из МетаданныеОбъекта.Реквизиты Цикл
        Имя = Реквизит.Имя;
        Значение = ДанныеОбъекта[Имя];
        
        // Проверяем тип значения
        Если Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Значение)) Тогда
            // Для ссылок берем ГУИД или наименование
            Результат.Вставить(Имя, Строка(Значение.УникальныйИдентификатор()));
        ИначеЕсли ТипЗнч(Значение) = Тип("Дата") Тогда
            Результат.Вставить(Имя, Формат(Значение, "ДФ=yyyy-MM-ddTHH:mm:ss"));
        Иначе
            Результат.Вставить(Имя, Значение);
        КонецЕсли;
    КонецЦикла;
    
    // 2. Не забываем про стандартные реквизиты (Код, Наименование)
    Результат.Вставить("Наименование", ДанныеОбъекта.Наименование);
    Результат.Вставить("Код", ДанныеОбъекта.Код);
    
    Возврат Результат;
    
КонецФункции

Теперь эту структуру можно легко записать стандартным методом ЗаписатьJSON(ЗаписьJSON, МояСтруктура). Этот подход позволяет гибко настраивать выгрузку: например, добавлять только нужные поля или сразу искать значения в связанных справочниках.

Обработка табличных частей

Выясним причину, по которой ЗаписатьJSON не принимает табличные части напрямую. Табличная часть — это сложный объект коллекции, который JSON не понимает. Чтобы передать ТЧ, её нужно превратить в Массив, состоящий из Структур (где каждая структура — это строка таблицы).

Проанализируем пример кода для обхода табличных частей:


Функция ПолучитьДанныеТабличнойЧасти(Объект, ИмяТЧ)
    МассивСтрок = Новый Массив;
    Для Каждого СтрокаТЧ Из Объект[ИмяТЧ] Цикл
        СтруктураСтроки = Новый Структура;
        Для Каждого Колонка Из Объект.Метаданные().ТабличныеЧасти[ИмяТЧ].Реквизиты Цикл
            СтруктураСтроки.Вставить(Колонка.Имя, СтрокаТЧ[Колонка.Имя]);
        КонецЦикла;
        МассивСтрок.Добавить(СтруктураСтроки);
    КонецЦикла;
    Возврат МассивСтрок;
КонецФункции

Специфические типы данных в JSON

Рассмотрим подробнее, как ведут себя различные типы данных 1С при упаковке в JSON, чтобы избежать ошибок на стороне получателя:

  1. Дата: 1С по умолчанию использует формат ISO 8601. Если получатель ожидает другой формат, преобразуйте дату в строку заранее.
  2. Перечисления: Ссылка на перечисление при сериализации может превратиться в GUID или системное имя. Чтобы передать "человеческое" название, используйте Строка(ЗначениеПеречисления).
  3. Хранилище значения: Бинарные данные (картинки, файлы) нельзя передать напрямую. Их необходимо конвертировать в строку Base64 методом Base64Строка(Хранилище.Получить()).
  4. Булево: Платформа корректно транслирует Истина/Ложь в true/false, здесь дополнительные действия не требуются.

Итоги и рекомендации

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

Надеемся, эти примеры помогут вам эффективно настроить экспорт данных в формат JSON и избежать распространенных ошибок типизации!

← На главную