При разработке интеграций в системе 1С:Предприятие 8.3 программисты часто сталкиваются с задачей выгрузки данных во внешние системы через формат JSON — для этого есть готовое решение для автоматической выгрузки данных из 1С через REST API и JSON. Стандартный метод ЗаписатьJSON отлично справляется с простыми типами (строки, числа, булево), но мгновенно выдает ошибку, если в структуре попадается ТаблицаЗначений, СправочникСсылка или NULL. Разберем подробно, как обойти эти ограничения и какими инструментами лучше воспользоваться в зависимости от ваших целей.
Формат JSON (JavaScript Object Notation) по своей природе очень прост. Он поддерживает ограниченный набор типов данных: объекты, массивы, числа, строки и логические значения. В 1С же существуют десятки специфических типов. Метод ЗаписатьJSON ориентирован на создание «чистого» JSON, который будет понятен любому веб-сервису. Поэтому, когда он встречает ТаблицуЗначений, он «не знает», как превратить её в стандартный массив или объект, и прерывает работу с ошибкой. Аналогичная ситуация происходит со ссылками на объекты метаданных: для 1С это сложный объект с УИД, а для внешнего мира — просто непонятный набор внутренних данных.
Если ваша задача — передать данные между двумя базами 1С или если принимающая сторона готова обрабатывать дополнительные метаданные, самым быстрым способом будет использование СериализаторXDTO. Рассмотрим пример реализации этого метода:
Процедура ВыгрузитьДанныеЧерезXDTO(пДанные, ИмяФайла)
ПараметрыЗаписи = Новый ПараметрыЗаписиJSON;
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписи);
// Используем XDTO для автоматической обработки сложных типов
СериализаторXDTO.ЗаписатьJSON(ЗаписьJSON, пДанные, НазначениеТипаXML.Явное);
Результат = ЗаписьJSON.Закрыть();
ЗаписьТекста = Новый ЗаписьТекста(ИмяФайла);
ЗаписьТекста.ЗаписатьСтроку(Результат);
ЗаписьТекста.Закрыть();
КонецПроцедуры
Преимущества этого метода: он «из коробки» умеет работать с таблицами значений и ссылками. Недостаток: в итоговом файле появятся служебные поля типа #type или __type. Для сторонних систем на Python или JavaScript такой файл будет избыточным и потребует дополнительной очистки данных.
Проанализируем ситуацию, когда нам нужен максимально «чистый» файл. В этом случае мы должны привести все сложные типы 1С к простым типам JSON до того, как вызовем процедуру записи. Разберем по шагам, что нужно сделать:
Массив, состоящий из Структур. Каждая структура будет представлять собой строку таблицы, где ключи — это имена колонок.NULL, который часто возвращается запросами, нужно заменить на Неопределено или строку.Рассмотрим пример функции, которая преобразует ТаблицуЗначений в массив структур:
Функция ТЗВМассив(ТаблицаДанных)
МассивРезультат = Новый Массив;
Колонки = ТаблицаДанных.Колонки;
Для Каждого СтрокаТЗ Из ТаблицаДанных Цикл
СтруктураСтроки = Новый Структура;
Для Каждого Колонка Из Колонки Цикл
Значение = СтрокаТЗ[Колонка.Имя];
// Простейшая проверка на тип
Если ТипЗнч(Значение) = Тип("NULL") Тогда
Значение = Неопределено;
КонецЕсли;
СтруктураСтроки.Вставить(Колонка.Имя, Значение);
КонецЦикла;
МассивРезультат.Добавить(СтруктураСтроки);
КонецЦикла;
Возврат МассивРезультат;
КонецФункции
Это наиболее профессиональный и эффективный метод. В объекте ЗаписатьJSON предусмотрен специальный параметр — ФункцияПреобразованияДанных. Мы можем передать туда имя функции, которая будет автоматически вызываться сериализатором каждый раз, когда он встретит тип данных, который не может обработать самостоятельно.
Проанализируем, как это реализовать на практике. Сначала подготовим основную процедуру записи:
Процедура ЗаписатьЧистыйJSON(СтруктураДанных)
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
// Указываем обработчик для сложных типов
ЗаписатьJSON(ЗаписьJSON, СтруктураДанных, , "МояФункцияПреобразования");
Результат = ЗаписьJSON.Закрыть();
Сообщить(Результат);
КонецПроцедуры
Теперь создадим саму функцию преобразования. Важно: она должна находиться в том же модуле или быть доступна в области видимости:
Функция МояФункцияПреобразования(Значение, ДополнительныеПараметры, Отказ) Экспорт
// Обработка ссылочных типов
Если Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Значение))
Или Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Значение)) Тогда
Возврат Строка(Значение.УникальныйИдентификатор());
КонецЕсли;
// Обработка Таблицы Значений
Если ТипЗнч(Значение) = Тип("ТаблицаЗначений") Тогда
Возврат ТЗВМассив(Значение); // Используем функцию из Способа №2
КонецЕсли;
// Обработка NULL
Если Значение = NULL Тогда
Возврат Неопределено;
КонецЕсли;
// Если тип нам не знаком, просто отказываемся от обработки или возвращаем как есть
Возврат Значение;
КонецФункции
Рассмотрим подробнее настройки, которые помогут вам сделать JSON-файл корректным:
1. Настройки сериализации (НастройкиСериализацииJSON): Этот объект позволяет управлять форматом дат. По умолчанию 1С может записывать даты в специфическом виде. Если вы хотите использовать стандарт ISO, обязательно укажите это в настройках:
Настройки = Новый НастройкиСериализацииJSON;
Настройки.ВариантЗаписиДаты = ВариантЗаписиДатыJSON.ISO8601;
ЗаписатьJSON(ЗаписьJSON, Данные, Настройки);
2. Двоичные данные: Если в вашей структуре хранятся картинки или файлы (тип ДвоичныеДанные), JSON не сможет их сохранить «как есть». Вам нужно конвертировать их в строку Base64. В функции преобразования это будет выглядеть так: Возврат Base64Строка(Значение);.
3. Оптимизация объема: Если таблица значений очень большая, использование массива структур (где имена колонок повторяются в каждой строке) сильно раздувает файл. В таком случае рассмотрите вариант записи структуры с двумя полями: "Columns" (массив имен) и "Rows" (массив массивов значений).
Подведем итог нашему анализу:
СериализаторXDTO. Это сэкономит время на написание кода обхода коллекций.ЗаписатьJSON с обязательной ФункциейПреобразованияДанных. Это гарантирует, что на выходе будет чистый, валидный JSON без специфических «хвостов» платформы 1С.NULL в результатах запросов перед записью, так как это самая частая причина падения выгрузки в фоновых заданиях.Используя предложенные подходы, вы сможете гибко настраивать выгрузку любых данных из 1С, сохраняя их структуру и обеспечивая совместимость с внешними программными продуктами — для автоматизации этого процесса без кода подойдёт универсальная выгрузка документов и справочников из 1С в JSON без программирования.