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

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

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

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

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

В платформе 1С:Предприятие нет единственного «правильного» способа: выбор зависит от того, куда уходят данные. Для обмена с веб-сервисами и REST API стандартом де-факто стал JSON, для обмена между информационными базами 1С удобен механизм XDTO, а для временного хранения внутри одной базы часто используют ЗначениеВСтрокуВнутр. Каждый вариант имеет ограничения по типам данных, объёму и переносимости.

Ниже разобраны рабочие способы с примерами кода, проверкой результата и типичными ошибками. Все примеры написаны на встроенном языке 1С и выполняются как в тонком, так и в толстом клиенте, а также на сервере.

Как выбрать способ сериализации под задачу

Прежде чем писать код, ответьте на два вопроса: кто будет читать сериализованные данные и какие типы лежат в массиве. Если читатель — внешняя система (сайт, мобильное приложение, другой язык программирования), единственный осмысленный вариант — JSON или XML, потому что внутренние форматы 1С никто кроме 1С не поймёт.

Если данные остаются внутри экосистемы 1С, появляется выбор. Массив с простыми типами (строки, числа, даты, булево) сериализуется любым способом. Массив со ссылками на объекты базы данных корректно перенесёт только XDTO-сериализатор или внутренний формат — JSON без дополнительной обработки превратит ссылку в нечитаемое представление.

Маршрут решения

Как выбрать действие

Данные уходят в HTTP-API, на сайт или внешнюю системуИспользуйте ЗаписьJSON — это универсальный читаемый формат
Обмен между двумя информационными базами 1С, в массиве есть ссылкиПрименяйте СериализаторXDTO с ЗаписьXML
Нужно временно сохранить массив в хранилище значения той же базыПодойдёт ЗначениеВСтрокуВнутр или ХранилищеЗначения напрямую
Массив большой и важен размер и скоростьСравните JSON и XDTO на реальных данных, избегайте ЗначениеВСтрокуВнутр для передачи по сети

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

Объект ЗаписьJSON последовательно формирует JSON-документ. Для массива используются методы ЗаписатьНачалоМассива() и ЗаписатьКонецМассива(), а каждый элемент записывается через ЗаписатьЗначение(). Метод подходит для строк, чисел, булевых значений и дат (дата сериализуется в формате ISO 8601).

bsl
Функция МассивВJSON(МассивДанных)

	Запись = Новый ЗаписьJSON;
	Запись.УстановитьСтроку();

	Запись.ЗаписатьНачалоМассива();
	Для Каждого Элемент Из МассивДанных Цикл
		Запись.ЗаписатьЗначение(Элемент);
	КонецЦикла;
	Запись.ЗаписатьКонецМассива();

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

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

Вызов МассивВJSON(Массив) для массива из трёх строк вернёт текст вида ["Первый","Второй","Третий"]. Обратите внимание: Закрыть() одновременно завершает запись и возвращает сформированную строку — отдельно получать текст не нужно.

Сериализация массива структур

На практике в массиве чаще лежат не скалярные значения, а структуры — например, строки табличной части или результата запроса. Здесь удобна функция ЗаписатьJSON(), которая умеет сериализовать структуры и соответствия целиком:

bsl
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
ЗаписатьJSON(Запись, МассивСтруктур);
СтрокаJSON = Запись.Закрыть();

Такой вариант автоматически обходит коллекцию и формирует корректный массив объектов. Ограничение: ключи структуры должны быть допустимыми идентификаторами, а значения — сериализуемыми типами. Ссылка на объект базы данных сериализуется в нечитаемое для внешней системы представление, поэтому ссылки заранее заменяйте на GUID или наименование.

Чтение JSON обратно в массив

Десериализация выполняется объектом ЧтениеJSON. Для массива скалярных значений проще всего использовать ПрочитатьJSON(), который сам восстановит структуру данных:

bsl
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(СтрокаJSON);
Результат = ПрочитатьJSON(Чтение);
Чтение.Закрыть();

Если ТипЗнч(Результат) = Тип("Массив") Тогда
	// работаем с массивом
КонецЕсли;

Функция ПрочитатьJSON возвращает массив, структуру или скалярное значение в зависимости от содержимого строки. Всегда проверяйте тип результата через ТипЗнч(), прежде чем обращаться к элементам: если внешняя система прислала объект вместо массива, обращение по индексу вызовет ошибку исполнения.

Контрольные точки

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

Тип результата после ПрочитатьJSON
Норма

ТипЗнч возвращает Массив

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

Возвращается Структура или Неопределено — входная строка не была массивом

Количество элементов
Норма

Совпадает с количеством в исходном массиве

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

Меньше — вероятно, элементы содержали несериализуемые типы

Значения дат и чисел
Норма

Даты читаются как Дата, числа — как Число

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

Даты пришли строками — внешняя система использовала свой формат

Сериализация через XDTO для обмена между базами 1С

Объект СериализаторXDTO преобразует значения 1С, включая ссылки, таблицы значений и массивы, в XML-документ, который другая база 1С сможет прочитать без дополнительной настройки. Это стандартный способ для интеграций «1С-1С».

bsl
Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку();
СериализаторXDTO.ЗаписатьXML(Запись, МассивДанных);
СтрокаXML = Запись.Закрыть();

// Обратное чтение:
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(СтрокаXML);
ВосстановленныйМассив = СериализаторXDTO.ПрочитатьXML(Чтение);
Чтение.Закрыть();

Главное преимущество способа — полная поддержка типов платформы: ссылки восстанавливаются по GUID, если в базе-приёмнике есть те же объекты, либо превращаются в битые ссылки, что легко диагностируется. Недостаток — многословный XML и невозможность прочитать результат средствами, не знающими схему XDTO платформы.

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

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

bsl
СтрокаВнутр = ЗначениеВСтрокуВнутр(МассивДанных);
// ... сохранение в реквизит или параметр
ВосстановленныйМассив = ЗначениеИзСтрокиВнутр(СтрокаВнутр);

Если задача — просто положить массив в реквизит справочника или документа, часто вообще не нужна строка: используйте тип реквизита ХранилищеЗначения и методы Новый ХранилищеЗначения(Массив) и Получить(). Это надёжнее и не требует ручной сериализации.

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

После сериализации полезно выполнить контрольный цикл: сериализовать массив, тут же десериализовать и сравнить количество элементов и контрольные значения. Это занимает несколько строк кода и отлавливает большинство проблем до того, как данные уйдут во внешнюю систему.

Отдельно проверяйте поведение на граничных случаях: пустой массив, массив с Неопределено и NULL, массив с кириллицей и спецсимволами. JSON корректно экранирует кавычки и переводы строк автоматически, но только если вы пользуетесь объектом ЗаписьJSON, а не собираете строку конкатенацией.

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

Производительность и ограничения по объёму

Для массивов из тысяч и десятков тысяч элементов скорость сериализации становится заметной. ЗаписьJSON работает потоково и не требует промежуточных строк, поэтому масштабируется хорошо. Конкатенация строк в цикле, напротив, деградирует квадратично и на больших массивах может занять в разы больше времени.

При передаче больших объёмов по HTTP учитывайте ограничения веб-сервера и прокси на размер тела запроса. Если массив формируется из результата запроса к базе, разумнее выгружать данные порциями (пакетами) и сериализовать каждый пакет отдельно — это снижает пиковое потребление памяти на сервере.

Итог

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

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

Частые вопросы

Как сериализовать массив ссылок в JSON?

Напрямую ссылка сериализуется в служебное представление, бесполезное для внешней системы. Перед записью замените ссылку на строку GUID: Строка(Ссылка.УникальныйИдентификатор()). В системе-приёмнике объект находится методом ПолучитьСсылку(Новый УникальныйИдентификатор(СтрокаGUID)) соответствующего менеджера объекта.

Можно ли сериализовать таблицу значений теми же способами?

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

Что делать, если ПрочитатьJSON падает с ошибкой?

Чаще всего входная строка не является валидным JSON: лишние запятые, одинарные кавычки вместо двойных, обрезанный текст. Проверьте строку валидатором JSON, убедитесь, что при приёме по HTTP правильно обработана кодировка (UTF-8) и не потерян конец документа при чтении потока.

Как сериализовать массив с датами, чтобы их поняла внешняя система?

ЗаписьJSON по умолчанию пишет даты в формате ISO 8601, который понимает большинство систем. Если приёмник требует другой формат (например, Unix-время), преобразуйте даты в нужное представление до сериализации и согласуйте формат с разработчиками принимающей стороны.

Есть ли ограничение на размер массива при сериализации?

Жёсткого ограничения со стороны платформы нет, упор идёт в доступную память и лимиты канала передачи. На практике массивы из сотен тысяч элементов разумно делить на пакеты: это ускоряет обработку, упрощает повторную отправку при сбоях и снижает риск превышения лимитов HTTP-сервера.