При разработке интеграций и обменов данными перед программистом 1С часто встает задача: как быстро и корректно преобразовать объект информационной базы (например, справочник ФизическиеЛица или документ РеализацияТоваровУслуг) в строку JSON. Платформа предоставляет несколько инструментов для этого, но при их использовании новички часто сталкиваются с ошибками вроде "Обнаружены несовместимые типы" или получают пустой JSON, содержащий только уникальный идентификатор.
В этой статье мы подробно рассмотрим, почему не получается записать объект напрямую, разберем работу с XDTO-сериализатором и научимся создавать универсальные механизмы упаковки данных через структуры и метаданные.
Проанализируем типичную ситуацию. Программист пытается передать ссылку на объект напрямую в метод ЗаписатьJSON. Платформа 1С выдает ошибку, так как этот метод "из коробки" умеет работать только с примитивными типами (строка, число, булево, дата) и универсальными коллекциями (массив, структура, соответствие). Ссылочные типы (СправочникСсылка, ДокументСсылка), а также сами объекты (СправочникОбъект) не могут быть автоматически преобразованы в JSON без дополнительных инструкций.
Рассмотрим основной способ решения этой задачи, который встроен в платформу.
Это самый быстрый способ "упаковать" объект со всеми его реквизитами и табличными частями. Секрет успеха заключается в правильной передаче данных методу. Если вы передадите ссылку (СправочникСсылка), в 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-скрипт), используйте Неявное.
Иногда сериализатор XDTO тянет слишком много лишней системной информации (версию данных, предопределенные признаки и т.д.). Если нам нужен строгий контроль над составом полей, мы выберем путь преобразования объекта в Структуру. Рассмотрим, как это сделать правильно.
Для начала создадим функцию-посредник, которая будет подготавливать данные. Основная сложность здесь — ссылочные типы внутри реквизитов. Их нужно превращать в строку или структуру с базовой информацией.
Функция ОбъектВСтруктуру(ДанныеОбъекта)
Результат = Новый Структура;
МетаданныеОбъекта = ДанныеОбъекта.Метаданные();
// 1. Обрабатываем основные реквизиты
Для Каждого Реквизит Из МетаданныеОбъекта.Реквизиты Цикл
Имя = Реквизит.Имя;
Значение = ДанныеОбъекта[Имя];
// Проверяем тип значения
Если Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Значение)) Тогда
// Для ссылок берем ГУИД или наименование
Результат.Вставить(Имя, Строка(Значение.УникальныйИдентификатор()));
ИначеЕсли ТипЗнч(Значение) = Тип("Дата") Тогда
Результат.Вставить(Имя, Формат(Значение, "ДФ=yyyy-MM-ddTHH:mm:ss"));
Иначе
Результат.Вставить(Имя, Значение);
КонецЕсли;
КонецЦикла;
// 2. Не забываем про стандартные реквизиты (Код, Наименование)
Результат.Вставить("Наименование", ДанныеОбъекта.Наименование);
Результат.Вставить("Код", ДанныеОбъекта.Код);
Возврат Результат;
КонецФункции
Теперь эту структуру можно легко записать стандартным методом ЗаписатьJSON(ЗаписьJSON, МояСтруктура). Этот подход позволяет гибко настраивать выгрузку: например, добавлять только нужные поля или сразу искать значения в связанных справочниках.
Выясним причину, по которой ЗаписатьJSON не принимает табличные части напрямую. Табличная часть — это сложный объект коллекции, который JSON не понимает. Чтобы передать ТЧ, её нужно превратить в Массив, состоящий из Структур (где каждая структура — это строка таблицы).
Проанализируем пример кода для обхода табличных частей:
Функция ПолучитьДанныеТабличнойЧасти(Объект, ИмяТЧ)
МассивСтрок = Новый Массив;
Для Каждого СтрокаТЧ Из Объект[ИмяТЧ] Цикл
СтруктураСтроки = Новый Структура;
Для Каждого Колонка Из Объект.Метаданные().ТабличныеЧасти[ИмяТЧ].Реквизиты Цикл
СтруктураСтроки.Вставить(Колонка.Имя, СтрокаТЧ[Колонка.Имя]);
КонецЦикла;
МассивСтрок.Добавить(СтруктураСтроки);
КонецЦикла;
Возврат МассивСтрок;
КонецФункции
Рассмотрим подробнее, как ведут себя различные типы данных 1С при упаковке в JSON, чтобы избежать ошибок на стороне получателя:
Строка(ЗначениеПеречисления).Base64Строка(Хранилище.Получить()).Истина/Ложь в true/false, здесь дополнительные действия не требуются.Мы проанализировали ситуацию и выяснили, что выбор метода зависит от вашей конечной цели:
СериализаторXDTO с передачей Объекта.Структуру и Массив. Это гарантирует, что сторонние системы смогут прочитать ваши данные без специфических 1С-тегов.ПолучитьОбъект()) требует прав на чтение и изменение, в то время как чтение данных через ссылку более "легкое" для системы.Надеемся, эти примеры помогут вам эффективно настроить экспорт данных в формат JSON и избежать распространенных ошибок типизации!