При разработке мобильных приложений и клиент-серверных механизмов в платформе 1С:Предприятие часто возникает задача сохранить или передать коллекцию данных. Если таблица состоит из колонок примитивных типов, разработчики по привычке пытаются применить функцию ЗначениеВСтрокуВнутр(). Однако этот метод недоступен в мобильных приложениях и на тонком клиенте. Выясним причину такого поведения платформы и подробно разберем все рабочие способы сериализации и десериализации объекта ТаблицаЗначений в строку.
Проанализируем ключевые технические ограничения платформы, с которыми сталкиваются разработчики:
ЗначениеВСтрокуВнутр() и ЗначениеИзСтрокиВнутр() поддерживаются только в толстом клиенте, внешнем соединении и обычном серверном контексте. В мобильной платформе и тонком клиенте они не работают.ЗаписатьXML() для таблицы значений приводит к исключению, так как он рассчитан на ограниченный список типов. При этом метод объекта СериализаторXDTO.ЗаписатьXML() поддерживает работу с таблицей значений.ТаблицаЗначений доступен только на сервере (включая сервер мобильного приложения) и в толстом клиенте. Все операции по ее сериализации необходимо выполнять в соответствующем серверном контексте.Рассмотрим самый быстрый и надежный способ упаковать таблицу значений в строку, применимый в мобильных приложениях. Для этого обернем таблицу в объект ХранилищеЗначения, после чего преобразуем его двоичные данные в Base64-строку.
Разберем по шагам сериализацию таблицы значений в строку:
// Создаем хранилище значения и получаем из него строку Base64
Хранилище = Новый ХранилищеЗначения(ТаблицаДляСериализации, Новый СжатиеДанных(9));
СтрокаBase64 = Base64Строка(Хранилище.ПолучитьДвоичныеДанные());
Теперь посмотрим на пример обратного восстановления (десериализации):
// Преобразуем строку обратно в двоичные данные, затем в хранилище
Двоичные = Base64Значение(СтрокаBase64);
Хранилище = Новый ХранилищеЗначения(Двоичные);
ВосстановленнаяТЗ = Хранилище.Получить();
Данный подход отличается простотой, не требует ручного разбора колонок и компактно сжимает данные благодаря объекту СжатиеДанных.
Рассмотрим подробнее использование встроенного механизма XDTO. Для таблицы значений в пространстве имен платформы зарегистрирован специальный тип ValueTable. Чтобы сериализация прошла успешно, важно явно указывать назначение типа XML.
Посмотрим на пример сериализации таблицы значений в строку XML:
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
// Записываем таблицу через фабрику XDTO с явным указанием типа
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ТаблицаДляСериализации, НазначениеТипаXML.Явное);
СтрокаXML = ЗаписьXML.Закрыть();
Разберем процесс десериализации полученной XML-строки обратно в таблицу значений:
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(СтрокаXML);
// Считываем значение обратно в объект ТаблицаЗначений
ВосстановленнаяТЗ = СериализаторXDTO.ПрочитатьXML(ЧтениеXML, Тип("ТаблицаЗначений"));
ЧтениеXML.Закрыть();
Важный момент: если при создании колонок таблицы значений не было задано строгое ОписаниеТипов, ячейки со значением Неопределено могут потерять исходный тип при выгрузке. Всегда явно определяйте типы колонок при инициализации таблицы.
Многие разработчики по привычке обходят таблицу значений циклом, формируя массив структур для последующей записи в JSON. Однако, начиная с платформы 8.3.7, объект СериализаторXDTO умеет напрямую работать с объектом ЗаписьJSON.
Посмотрим на пример выгрузки таблицы в формат JSON без лишних циклов:
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
СериализаторXDTO.ЗаписатьJSON(ЗаписьJSON, ТаблицаДляСериализации, НазначениеТипаXML.Явное);
СтрокаJSON = ЗаписьJSON.Закрыть();
Проанализируем десериализацию данных из формата JSON:
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(СтрокаJSON);
ВосстановленнаяТЗ = СериализаторXDTO.ПрочитатьJSON(ЧтениеJSON, Тип("ТаблицаЗначений"));
ЧтениеJSON.Закрыть();
Этот способ позволяет получить человекочитаемый формат данных с сохранением информации о типах колонок и колоночной структуре таблицы.