Разработка и Конфигурация · 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 не умеет обрабатывать, вызов завершится исключением. Типичный пример — попытка записать ссылку или результат запроса. Решение — написать функцию нормализации, которая рекурсивно обходит структуру и заменяет проблемные типы на сериализуемые представления. Это рутинная, но одноразовая работа, которая потом переиспользуется во всех обменах.
Функция Нормализовать(Значение)
Если ТипЗнч(Значение) = Тип("Структура") Тогда
Результат = Новый Структура;
Для Каждого КлючЗначение Из Значение Цикл
Результат.Вставить(КлючЗначение.Ключ, Нормализовать(КлючЗначение.Значение));
КонецЦикла;
Возврат Результат;
ИначеЕсли ТипЗнч(Значение) = Тип("Массив") Тогда
Результат = Новый Массив;
Для Каждого Элемент Из Значение Цикл
Результат.Добавить(Нормализовать(Элемент));
КонецЦикла;
Возврат Результат;
ИначеЕсли ОбщегоНазначения.ЭтоСсылка(ТипЗнч(Значение)) Тогда
Возврат Строка(Значение.УникальныйИдентификатор());
Иначе
Возврат Значение;
КонецЕсли;
КонецФункцииСериализация через СериализаторXDTO
Объект СериализаторXDTO преобразует значения в объекты XDTO и обратно. Он удобен, когда данные перемещаются между базами 1С: ссылки сериализуются вместе с типом и GUID, и на приёмной стороне их можно восстановить. Для записи используется связка ЗаписатьXML и СериализаторXDTO.ЗаписатьXML().
Ограничение важное: структура сама по себе не является сериализуемым типом XDTO, поэтому напрямую передать её в ЗаписатьXML не получится. Обычно структуру оборачивают в ХранилищеЗначения и сериализуют его, либо сериализуют отдельные значения. Зато сами ссылки, перечисления и значения перечислений проходят через XDTO без ручной конвертации.
Хранилище = Новый ХранилищеЗначения(СтруктураДанных, Новый СжатиеДанных(9));
Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку();
СериализаторXDTO.ЗаписатьXML(Запись, Хранилище);
СтрокаXML = Запись.Закрыть();
ЗначениеВСтрокуВнутр для хранения внутри базы
Функция ЗначениеВСтрокуВнутр() преобразует значение во внутреннее строковое представление платформы, а ЗначениеИзСтрокиВнутр() восстанавливает его обратно. Это самый простой способ «заморозить» структуру для хранения в строковом поле справочника или константе внутри одной базы.
У способа два жёстких ограничения. Во-первых, формат внутренний и недокументированный — строку нельзя передать внешней системе или прочитать другим инструментом. Во-вторых, ссылки сериализуются как есть, и после удаления объекта из базы восстановленная структура будет содержать «битые» ссылки. Поэтому ЗначениеВСтрокуВнутр годится для настроек и кэша, но не для обмена и не для долгосрочного архива.
Сравнение способов сериализации
Обмен с внешними системами, HTTP-запросы. Требует нормализации ссылок и таблиц
Обмен между базами 1С, веб-сервисы. Сохраняет типы и ссылки, но не работает в веб-клиенте
Хранение настроек внутри одной базы. Не переносимо между системами, битые ссылки после удаления объектов
Сохранение структуры в поле типа ХранилищеЗначения без преобразования в строку
Передача структуры в фоновое задание
При запуске фонового задания через ФоновыеЗадания.Выполнить параметры передаются массивом, и платформа требует, чтобы они были сериализуемыми. Структура из простых типов проходит напрямую — отдельная сериализация не нужна, платформа сделает её сама. Проблемы начинаются, когда в структуру кладут таблицу значений, результат запроса или COM-объект: задание упадёт при старте с ошибкой сериализации параметров.
Правильный подход — передавать в фоновое задание только «чистые» данные: идентификаторы вместо ссылок, массивы структур вместо таблиц. Если данных много, надёжнее сохранить их во временное хранилище или регистр сведений, а в задание передать только ключ записи. Фоновое задание по ключу прочитает данные уже на сервере.
- 1Переберите структуру и определите типы значений через ТипЗнч
- 2Замените ссылки на строки GUID, таблицы значений — на массивы структур
- 3Выберите механизм: JSON для внешних систем, XDTO между базами 1С, ЗначениеВСтрокуВнутр для внутреннего хранения
- 4Выполните сериализацию и сразу проверьте обратное преобразование
- 5Сравните восстановленную структуру с исходной по ключевым полям
Проверка результата и типичные ошибки
Сериализация считается успешной только после обратного преобразования. Запишите структуру в JSON, тут же прочитайте её через ПрочитатьJSON и сравните ключевые значения. Если даты вернулись строками, числа потеряли точность, а вложенные массивы пришли пустыми — значит, нормализация или чтение настроены неверно.
Отдельно проверяйте кодировку при передаче JSON по HTTP: русские буквы должны корректно читаться на приёмной стороне. ЗаписьJSON по умолчанию экранирует не-ASCII символы или записывает их как есть в зависимости от параметров — согласуйте это с форматом, который ждёт внешняя система.
Как проверить результат
Структура восстанавливается, значения совпадают по типам
Даты стали строками, часть ключей потерялась
Текст читается на приёмной стороне без замены символов
Кракозябры или избыточное экранирование ломают парсер
По 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, для внутреннего хранения — ЗначениеВСтрокуВнутр или ХранилищеЗначения. Успех проверяется только обратным преобразованием и сравнением значений.