Как на клиенте получить массив структур из сериализованных данных в 1С?

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

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

Разберем подробно, как эффективно передать массив структур с сервера на клиент, используя штатные механизмы сериализации платформы 1С:Предприятие 8.3.

Вариант 1. Использование штатных механизмов JSON (для платформы 8.3.6 и выше)

Наиболее универсальным и производительным способом передачи структурированных данных является формат JSON. Вопреки распространенному мнению, его не нужно «парсить вручную». На тонком клиенте доступны объекты для автоматической десериализации.

Рассмотрим алгоритм действий. На стороне сервера (внутри фонового задания) мы упаковываем наш массив структур в строку. Для этого используем объект ЗаписьJSON.


// Код на стороне СЕРВЕРА (в фоновом задании)
МассивРезультатов = Новый Массив;
СтруктураДанных = Новый Структура("ID, Статус, Описание", 1, "Успешно", "Данные обработаны");
МассивРезультатов.Добавить(СтруктураДанных);

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

// Передаем строку через механизм прогресса БСП
ДлительныеОперации.СообщитьПрогресс(Процент, "Данные:" + СтрокаJSON);

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


// Код на стороне КЛИЕНТА
// Предположим, ПереданнаяСтрока содержит наш JSON
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ПереданнаяСтрока);
МассивРезультатов = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();

Для Каждого Элемент Из МассивРезультатов Цикл
    // Теперь Элемент — это полноценная Структура
    Сообщить(Элемент.Описание);
КонецЦикла;

Этот метод хорош тем, что ПрочитатьJSON автоматически восстанавливает типы данных: числа, строки и булевы значения. Однако стоит помнить, что даты в JSON требуют дополнительной настройки через параметры СериализацияДаты.

Вариант 2. Упрощенный метод для платформы 8.3.23 и выше

Если вы работаете на современных версиях платформы (8.3.23+), задача становится еще проще. Появился глобальный метод ПрочитатьЗначениеJSON, который доступен на всех видах клиентов, включая веб-клиент.

Выясним, в чем преимущество. Нам больше не нужно явно создавать объект ЧтениеJSON. Код на клиенте сокращается до одной строки:


// Код на стороне КЛИЕНТА (8.3.23+)
МассивРезультатов = ПрочитатьЗначениеJSON(ПереданнаяСтрока);

Это максимально «нативный» способ, который требует минимум усилий и работает быстрее, чем любые самописные парсеры строк.

Вариант 3. Сериализация через XDTO (передача типизированных данных)

Если ваши структуры содержат специфические типы данных, которые JSON может интерпретировать неоднозначно, стоит рассмотреть XDTO-сериализацию. Этот механизм также доступен на тонком клиенте и позволяет передавать данные в формате XML или JSON с сохранением строгой типизации.

Посмотрим на пример реализации. На сервере мы используем глобальный объект СериализаторXDTO.


// Код на стороне СЕРВЕРА
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
СериализаторXDTO.ЗаписатьJSON(ЗаписьJSON, МассивСтруктур, НазначениеИспользованияJSON.V8);
СтрокаДанных = ЗаписьJSON.Закрыть();

На клиенте мы восстанавливаем данные аналогичным образом:


// Код на стороне КЛИЕНТА
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(СтрокаДанных);
МассивСтруктур = СериализаторXDTO.ПрочитатьJSON(ЧтениеJSON, Тип("Массив"));
ЧтениеJSON.Закрыть();

Использование НазначениеИспользованияJSON.V8 гарантирует, что 1С правильно упакует и распакует системные типы данных (например, ссылки, если они передаются внутри, хотя автор вопроса указал использование только строк и чисел).

Вариант 4. Передача через двоичные данные и Base64

Рассмотрим ситуацию, когда данных очень много. Передача огромных строк через механизмы сообщений прогресса может замедлить работу сетевого протокола. В этом случае данные можно передать как ДвоичныеДанные, упакованные в Base64.

На сервере мы можем использовать временный файл (хотя автор просил без «хаков», это иногда оправдано для объема в сотни мегабайт) или потоковую запись.

  1. Сформируйте массив на сервере.
  2. Используйте ЗначениеВФайл (на сервере это доступно).
  3. Прочитайте файл в объект ДвоичныеДанные.
  4. Преобразуйте в строку через Base64Строка().

Однако на клиенте возникнет проблема: ЗначениеИзФайла не работает в тонком клиенте. Поэтому этот путь (через Base64) имеет смысл только в сочетании с JSON или XDTO, чтобы просто уменьшить объем передаваемого трафика за счет сжатия, если это необходимо.

Важные рекомендации при работе с длительными операциями

Проанализируем несколько критических моментов, о которых нельзя забывать при использовании прогресса БСП:

Резюме: Для большинства задач оптимальным решением является использование ЗаписатьJSON на сервере и ПрочитатьJSON (или ПрочитатьЗначениеJSON для новых версий) на клиенте. Это обеспечивает высокую скорость разработки, надежность и отсутствие «ручного» парсинга строк.

← На главную