Как записать структуру с таблицами значений и ссылками в JSON?

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

При разработке интеграций в системе 1С:Предприятие 8.3 программисты часто сталкиваются с задачей выгрузки данных во внешние системы через формат JSON — для этого есть готовое решение для автоматической выгрузки данных из 1С через REST API и JSON. Стандартный метод ЗаписатьJSON отлично справляется с простыми типами (строки, числа, булево), но мгновенно выдает ошибку, если в структуре попадается ТаблицаЗначений, СправочникСсылка или NULL. Разберем подробно, как обойти эти ограничения и какими инструментами лучше воспользоваться в зависимости от ваших целей.

Выясняем причину: почему возникает ошибка недопустимого типа?

Формат JSON (JavaScript Object Notation) по своей природе очень прост. Он поддерживает ограниченный набор типов данных: объекты, массивы, числа, строки и логические значения. В 1С же существуют десятки специфических типов. Метод ЗаписатьJSON ориентирован на создание «чистого» JSON, который будет понятен любому веб-сервису. Поэтому, когда он встречает ТаблицуЗначений, он «не знает», как превратить её в стандартный массив или объект, и прерывает работу с ошибкой. Аналогичная ситуация происходит со ссылками на объекты метаданных: для 1С это сложный объект с УИД, а для внешнего мира — просто непонятный набор внутренних данных.

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

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


Процедура ВыгрузитьДанныеЧерезXDTO(пДанные, ИмяФайла)
    ПараметрыЗаписи = Новый ПараметрыЗаписиJSON;
    ЗаписьJSON = Новый ЗаписьJSON;
    ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписи);
    
    // Используем XDTO для автоматической обработки сложных типов
    СериализаторXDTO.ЗаписатьJSON(ЗаписьJSON, пДанные, НазначениеТипаXML.Явное);
    
    Результат = ЗаписьJSON.Закрыть();
    
    ЗаписьТекста = Новый ЗаписьТекста(ИмяФайла);
    ЗаписьТекста.ЗаписатьСтроку(Результат);
    ЗаписьТекста.Закрыть();
КонецПроцедуры

Преимущества этого метода: он «из коробки» умеет работать с таблицами значений и ссылками. Недостаток: в итоговом файле появятся служебные поля типа #type или __type. Для сторонних систем на Python или JavaScript такой файл будет избыточным и потребует дополнительной очистки данных.

Способ №2: Предварительная подготовка данных (Ручная трансформация)

Проанализируем ситуацию, когда нам нужен максимально «чистый» файл. В этом случае мы должны привести все сложные типы 1С к простым типам JSON до того, как вызовем процедуру записи. Разберем по шагам, что нужно сделать:

  1. Таблица значений: Её необходимо преобразовать в Массив, состоящий из Структур. Каждая структура будет представлять собой строку таблицы, где ключи — это имена колонок.
  2. Ссылки: Ссылки на справочники или документы нужно превратить в строку (обычно используют уникальный идентификатор).
  3. Даты: Даты следует привести к формату ISO 8601.
  4. NULL: Тип NULL, который часто возвращается запросами, нужно заменить на Неопределено или строку.

Рассмотрим пример функции, которая преобразует ТаблицуЗначений в массив структур:


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

Способ №3: Использование функции преобразования данных (Callback)

Это наиболее профессиональный и эффективный метод. В объекте Записать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" (массив массивов значений).

Выясним причину выбора конкретного метода

Подведем итог нашему анализу:

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

← На главную