К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как сериализовать структуру в 1С

Практические способы сериализации структуры в 1С: ЗаписьJSON, СериализаторXDTO, ЗначениеВСтрокуВнутр. Примеры кода, ограничения, типичные ошибки и проверка результата.

Сериализация структуры в 1С — это преобразование объекта «Структура» в текстовое или двоичное представление, которое можно сохранить в файл, передать по HTTP или положить в хранилище значения. Встроенный язык не умеет сериализовать структуру «из коробки» одной универсальной командой, поэтому на практике применяют несколько подходов: запись в JSON через ЗаписьJSON, сериализацию через СериализаторXDTO и преобразование во внутреннюю строку через ЗначениеВСтрокуВнутр. Выбор зависит от того, куда уйдут данные и что за типы лежат внутри структуры.

Чаще всего задача возникает при обмене с внешними системами: нужно сформировать тело HTTP-запроса, ответ веб-сервиса или сообщение для брокера. Второй типовой сценарий — сохранение настроек между сеансами, когда структуру с параметрами нужно положить в константу или регистр. Третий — передача данных между фоновыми заданиями, где параметры должны быть сериализуемыми.

Важно понимать ограничение заранее: структура в 1С может содержать только те значения, которые умеет обрабатывать выбранный механизм. Простые типы (строка, число, булево, дата, Неопределено) сериализуются почти везде, а вот ссылки на объекты базы, таблицы значений или картинки требуют отдельной обработки — иначе получите ошибку или потерю данных.

Проверка содержимого структуры перед сериализацией

Прежде чем выбирать механизм, посмотрите, какие типы значений лежат в структуре. От этого зависит половина успеха. Пройдитесь по ключам и определите тип каждого значения через ТипЗнч() — так вы заранее увидите проблемные места, а не узнаете о них из ошибки в рабочем контуре.

Безопасно сериализуются практически везде: строки, числа, булево, даты, Неопределено, массивы и вложенные структуры из простых типов. Проблемные значения: ссылки на справочники и документы (в JSON они не превращаются в читаемый вид автоматически), таблицы значений, ХранилищеЗначения, двоичные данные и картинки. Для таких типов нужна предварительная конвертация: ссылку заменить на GUID-строку, таблицу — на массив структур, двоичные данные — на Base64.

Только простые типыСтроки, числа, даты, булево

Можно сразу писать в JSON без подготовки

Есть ссылкиСправочники, документы

Заменить на Строка(Ссылка.УникальныйИдентификатор())

Есть таблицы значенийТип ТаблицаЗначений

Преобразовать в массив структур построчно

Есть двоичные данныеФайлы, картинки

Кодировать в Base64Строка перед записью

Сериализация в JSON через ЗаписьJSON

Основной рабочий способ — глобальная функция ЗаписатьJSON, которая принимает объект ЗаписьJSON и значение. Платформа сама преобразует структуру в JSON-документ: ключи станут именами свойств, массивы — JSON-массивами, даты будут записаны в формате ISO. Результат получается методом Закрыть() объекта записи.

Функция СтруктураВJSON(СтруктураДанных)

Запись = Новый ЗаписьJSON;

Запись.УстановитьСтроку();

ЗаписатьJSON(Запись, СтруктураДанных);

Возврат Запись.Закрыть();

КонецФункции

Обратное преобразование выполняется через ПрочитатьJSON с параметром ПрочитатьВСоответствие = Ложь, чтобы получить именно структуру, а не соответствие. Учтите: при чтении даты возвращаются строками, если не настроить восстановление — платформа не знает, какие поля были датами. Для критичных случаев храните даты в ISO-формате и преобразуйте обратно явно.

Когда JSON не справляется

Если в структуре есть значения, которые ЗаписатьJSON не умеет обрабатывать, вызов завершится исключением. Типичный пример — попытка записать ссылку или результат запроса. Решение — написать функцию нормализации, которая рекурсивно обходит структуру и заменяет проблемные типы на сериализуемые представления. Это рутинная, но одноразовая работа, которая потом переиспользуется во всех обменах.

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

Сериализация через СериализаторXDTO

Объект СериализаторXDTO преобразует значения в объекты XDTO и обратно. Он удобен, когда данные перемещаются между базами 1С: ссылки сериализуются вместе с типом и GUID, и на приёмной стороне их можно восстановить. Для записи используется связка ЗаписатьXML и СериализаторXDTO.ЗаписатьXML().

Ограничение важное: структура сама по себе не является сериализуемым типом XDTO, поэтому напрямую передать её в ЗаписатьXML не получится. Обычно структуру оборачивают в ХранилищеЗначения и сериализуют его, либо сериализуют отдельные значения. Зато сами ссылки, перечисления и значения перечислений проходят через XDTO без ручной конвертации.

Хранилище = Новый ХранилищеЗначения(СтруктураДанных, Новый СжатиеДанных(9));

Запись = Новый ЗаписьXML;

Запись.УстановитьСтроку();

СериализаторXDTO.ЗаписатьXML(Запись, Хранилище);

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

ЗначениеВСтрокуВнутр для хранения внутри базы

Функция ЗначениеВСтрокуВнутр() преобразует значение во внутреннее строковое представление платформы, а ЗначениеИзСтрокиВнутр() восстанавливает его обратно. Это самый простой способ «заморозить» структуру для хранения в строковом поле справочника или константе внутри одной базы.

У способа два жёстких ограничения. Во-первых, формат внутренний и недокументированный — строку нельзя передать внешней системе или прочитать другим инструментом. Во-вторых, ссылки сериализуются как есть, и после удаления объекта из базы восстановленная структура будет содержать «битые» ссылки. Поэтому ЗначениеВСтрокуВнутр годится для настроек и кэша, но не для обмена и не для долгосрочного архива.

Сравнение способов сериализации

ЗаписатьJSON

Обмен с внешними системами, HTTP-запросы. Требует нормализации ссылок и таблиц

СериализаторXDTO

Обмен между базами 1С, веб-сервисы. Сохраняет типы и ссылки, но не работает в веб-клиенте

ЗначениеВСтрокуВнутр

Хранение настроек внутри одной базы. Не переносимо между системами, битые ссылки после удаления объектов

ХранилищеЗначения

Сохранение структуры в поле типа ХранилищеЗначения без преобразования в строку

Передача структуры в фоновое задание

При запуске фонового задания через ФоновыеЗадания.Выполнить параметры передаются массивом, и платформа требует, чтобы они были сериализуемыми. Структура из простых типов проходит напрямую — отдельная сериализация не нужна, платформа сделает её сама. Проблемы начинаются, когда в структуру кладут таблицу значений, результат запроса или COM-объект: задание упадёт при старте с ошибкой сериализации параметров.

Правильный подход — передавать в фоновое задание только «чистые» данные: идентификаторы вместо ссылок, массивы структур вместо таблиц. Если данных много, надёжнее сохранить их во временное хранилище или регистр сведений, а в задание передать только ключ записи. Фоновое задание по ключу прочитает данные уже на сервере.

Порядок безопасной сериализации структуры
  1. 1
    Переберите структуру и определите типы значений через ТипЗнч
  2. 2
    Замените ссылки на строки GUID, таблицы значений — на массивы структур
  3. 3
    Выберите механизм: JSON для внешних систем, XDTO между базами 1С, ЗначениеВСтрокуВнутр для внутреннего хранения
  4. 4
    Выполните сериализацию и сразу проверьте обратное преобразование
  5. 5
    Сравните восстановленную структуру с исходной по ключевым полям

Проверка результата и типичные ошибки

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

Отдельно проверяйте кодировку при передаче JSON по HTTP: русские буквы должны корректно читаться на приёмной стороне. ЗаписьJSON по умолчанию экранирует не-ASCII символы или записывает их как есть в зависимости от параметров — согласуйте это с форматом, который ждёт внешняя система.

Типичные ошибки
01
Попытка записать ссылку напрямую в JSON — исключение или бессмысленное значение вместо идентификатора
02
Чтение JSON в соответствие вместо структуры — обращение по ключу через точку перестаёт работать
03
Использование ЗначениеВСтрокуВнутр для обмена с внешней системой — формат никто кроме платформы не читает
04
Передача таблицы значений в фоновое задание — ошибка сериализации при старте
05
Игнорирование восстановления дат при чтении JSON — даты приходят строками и ломают сравнения
Контрольные точки

Как проверить результат

Обратное чтение JSON
Норма

Структура восстанавливается, значения совпадают по типам

Тревожный признак

Даты стали строками, часть ключей потерялась

Кириллица в JSON
Норма

Текст читается на приёмной стороне без замены символов

Тревожный признак

Кракозябры или избыточное экранирование ломают парсер

Ссылки после восстановления
Норма

По GUID находится существующий объект базы

Тревожный признак

Получена битая ссылка или пустое значение

Часто задаваемые вопросы

Можно ли сериализовать структуру с вложенными структурами и массивами?

Да, ЗаписатьJSON рекурсивно обрабатывает вложенные структуры и массивы, если все конечные значения — сериализуемых типов. Ограничение появляется только на «листьях»: ссылка или таблица значений на любом уровне вложенности вызовет ошибку.

Чем структура отличается от соответствия при сериализации?

При записи в JSON разницы почти нет — оба превращаются в объект. При чтении ПрочитатьJSON по умолчанию возвращает соответствие; чтобы получить структуру, вторым параметром передают Ложь. Структура удобнее для чтения (обращение через точку), соответствие — когда ключи содержат символы, недопустимые в именах свойств.

Как передать структуру через HTTP-сервис 1С?

В методе HTTP-сервиса сформируйте структуру ответа, запишите её в JSON через ЗаписатьJSON, поместите строку в тело HTTPСервисОтвет и установите заголовок Content-Type равным application/json. На стороне клиента ответ читается через ПрочитатьJSON.

Почему после ЗначениеВСтрокуВнутр ссылки стали битыми?

Функция сохраняет ссылку как указатель на объект базы. Если объект удалили, при восстановлении вы получите ссылку на несуществующий объект. Для долговременного хранения заменяйте ссылки на GUID-строки и восстанавливайте их через ПолучитьСсылку с проверкой существования.

Работает ли ЗаписатьJSON на клиенте?

Да, ЗаписьJSON и ЗаписатьJSON доступны в тонком и веб-клиенте, поэтому JSON-подход универсален. А вот СериализаторXDTO в веб-клиенте недоступен — учитывайте это при выборе механизма для клиент-серверных решений.

Итог

Что важно запомнить

Для обмена с внешними системами сериализуйте структуру в JSON через ЗаписатьJSON, предварительно заменив ссылки и таблицы значений на простые типы. Между базами 1С используйте СериализаторXDTO, для внутреннего хранения — ЗначениеВСтрокуВнутр или ХранилищеЗначения. Успех проверяется только обратным преобразованием и сравнением значений.