Как правильно сохранить Соответствие с массивами и ссылками в JSON и прочитать его обратно в 1С

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

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

Анализ проблемы: почему возникают ошибки при чтении JSON

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

Проанализируем основные причины сбоев:

  1. Недопустимые имена свойств: При использовании XDTO платформа добавляет в JSON служебные поля, такие как #type и #value. Если пытаться прочитать такой файл в объект Структура, 1С выдаст ошибку: Недопустимое имя свойства: '#type'. Это связано с тем, что ключи структуры должны соответствовать правилам именования переменных (не могут содержать спецсимволы, такие как решетка).
  2. Сложная вложенность: СериализаторXDTO превращает Соответствие в массив объектов с полями Key и Value. В итоге получается "матрёшка" из соответствий, которую крайне неудобно разбирать программно после загрузки.
  3. Ограничения стандартного метода: Глобальный метод ЗаписатьJSON не поддерживает запись Соответствия, если его ключи не являются строками. Если ключом является СправочникСсылка, система выдаст ошибку Недопустимый тип значения ключа элемента соответствия.

Способ 1: Использование Сериализатора XDTO (для сохранения ссылочных типов)

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


// Подготовка данных
Данные = Новый Соответствие;
МассивЗначений = Новый Массив;
МассивЗначений.Добавить(1);
МассивЗначений.Добавить(2);
Данные.Вставить(ВыбранныйКонтрагент, МассивЗначений);

// Запись в файл
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьФайл(ПолноеИмяФайла);
СериализаторXDTO.ЗаписатьJSON(ЗаписьJSON, Данные, НазначениеТипаXML.Явное);
ЗаписьJSON.Закрыть();

При таком подходе в файле сформируется сложная структура с указанием типов метаданных. Чтобы прочитать её обратно, мы обязательно должны использовать тот же СериализаторXDTO, но с учетом специфики возвращаемого объекта. Выясним важный нюанс: при чтении мы можем получить "Соответствие Соответствий", которое придется обходить циклом для восстановления исходного вида.

Способ 2: Универсальный подход через преобразование к примитивным типам

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

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

Шаг 1. Подготовка данных и запись. Пройдемся циклом по нашему соответствию и создадим новое, где ключом будет строка UID контрагента.


ПараметрыДляСохранения = Новый Соответствие;
Для Каждого СтрокаНастройки Из ИсходноеСоответствие Цикл
    КлючСтрока = Строка(СтрокаНастройки.Ключ.УникальныйИдентификатор());
    ПараметрыДляСохранения.Вставить(КлючСтрока, СтрокаНастройки.Значение);
КонецЦикла;

ЗаписьJSON = Новый ЗаписьJSON;
ПараметрыЗаписи = Новый ПараметрыЗаписиJSON(,,, ЭлементыЭстетическогоВыводаJSON.Авто);
ЗаписьJSON.ОткрытьФайл(ПолноеИмяФайла,,, ПараметрыЗаписи);
ЗаписатьJSON(ЗаписьJSON, ПараметрыДляСохранения);
ЗаписьJSON.Закрыть();

Шаг 2. Чтение и восстановление ссылок. При чтении крайне важно использовать второй параметр метода ПрочитатьJSON, установив его в значение Истина. Это заставит платформу прочитать объект JSON в Соответствие, а не в Структуру, что позволит избежать проблем с именами ключей.


ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.ОткрытьФайл(ПолноеИмяФайла);
// Читаем именно в Соответствие (второй параметр = Истина)
ЗагруженныеДанные = ПрочитатьJSON(ЧтениеJSON, Истина);
ЧтениеJSON.Закрыть();

// Восстанавливаем ссылки
ИтоговоеСоответствие = Новый Соответствие;
Для Каждого Элемент Из ЗагруженныеДанные Цикл
    СсылкаКонтрагент = Справочники.Контрагенты.ПолучитьСсылку(Новый УникальныйИдентификатор(Элемент.Ключ));
    ИтоговоеСоответствие.Вставить(СсылкаКонтрагент, Элемент.Значение);
КонецЦикла;

Использование Функции Восстановления (Продвинутый уровень)

Для еще более изящного решения задачи восстановления ссылок, мы можем использовать параметр ИмяФункцииВосстановления в методе ПрочитатьJSON. Это позволит нам делегировать платформе поиск ссылок непосредственно в момент парсинга текстового файла.

Разберем, как это работает: мы указываем имя функции, которая будет вызываться для каждого прочитанного значения. Внутри функции мы можем проверить, является ли строка Уникальным Идентификатором контрагента, и если да — вернуть готовую ссылку.


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

Выводы и рекомендации

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

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

← На главную