В настоящее время со стороны 1С существуют 3 метода сериализации значений:
- Старый способ со времен 7.7.
- Метод XML - довольно распространенный. Причём как вариант через БСП с использованием XDTO (8.1 и новее) и без него для платформы 8.0.
- Метод JSON - начиная с 8.3.6.
Однако, при знакомстве с мобильной платформой выяснились следующие проблемы: старые добрые функции для серилизации не работают - это ЗначениеИзВнутСтроки() и ЗначениеВоВнутСтроку(). Точнее их вообще нет здесь.
Так как при создании моей Консоли Запросов я использовал не только платформу 8.3, но и 8.2 - то единственным доступным вариантом в моем случае остался 2-й метод.
Универсальная Сериализация через XML
Стандартно для этих целей существуют следующие функции из БСП:
// Строка - XML-строка.
//
Функция ЗначениеВСтрокуXML(Значение) Экспорт
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, Значение);
Возврат ЗаписьXML.Закрыть();
КонецФункции
// Выполняет преобразование (десериализацию) XML-строки в значение.
// См. также ЗначениеВСтрокуXML.
//
// Параметры:
// СтрокаXML - Строка - XML-строка, с сериализованным объектом..
//
// Возвращаемое значение:
// Произвольный - значение, полученное из переданной XML-строки.
//
Функция ЗначениеИзСтрокиXML(СтрокаXML) Экспорт
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(СтрокаXML);
Значение=СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
Возврат Значение;
КонецФункции
Эти функции, взятые из БСП, - хорошие. Однако передать через них серьезные объекты (в моем случае это был тип данных РезультатЗапроса) без выгрузки или других танцев с бубном в рамках портирования консоли на мобильные платформы оказалось абсолютно невозможным, так как данные типы тип не сериализуются XDTO.
Однако для этого можно применить следующее правило, которое может работать в пределах одной базы:
- Если тип сериализуется - ничего не делаем. Сразу преобразуем.
- Если нельзя сериализовать- упаковываем в хранилище значений. Следует отметить, что хранилище значений упаковывается также, чтобы с ним не было проблем.
Итоговые правки в код дают следующие функции:
// Преобразованы в могут быть любые объекты (дополнено через ХранилищеЗначения.
// См. также ЗначениеИзСтрокиXML.
//
// Параметры:
// Значение - Произвольный - значение, которое необходимо сериализовать в XML-строку.
//
// Возвращаемое значение:
// Строка - XML-строка.
//
Функция ЗначениеВСтрокуXML(Значение) Экспорт
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
Если Значение=Тип("ХранилищеЗначения") Тогда
//Сохраняем жизнь исходному типу - через оборачивание.
ХранилищеЗначения=новый ХранилищеЗначения(Значение);
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ХранилищеЗначения);
иначе
//Выполняем Сериализацию:
попытка
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, Значение);
исключение
ХранилищеЗначения=новый ХранилищеЗначения(Значение);
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ХранилищеЗначения);
КонецПопытки;
КонецЕсли;
Возврат ЗаписьXML.Закрыть();
КонецФункции
// Выполняет преобразование (десериализацию) XML-строки в значение.
// См. также ЗначениеВСтрокуXML.
//
// Параметры:
// СтрокаXML - Строка - XML-строка, с сериализованным объектом..
//
// Возвращаемое значение:
// Произвольный - значение, полученное из переданной XML-строки.
//
Функция ЗначениеИзСтрокиXML(СтрокаXML) Экспорт
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(СтрокаXML);
ХранилищеЗначение=СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
//Восстанавливаем значение из Хранилища:
Если ХранилищеЗначение=Тип("ХранилищеЗначения") Тогда
Возврат ХранилищеЗначение.Получить();
иначе
Возврат ХранилищеЗначение;
КонецЕсли;
КонецФункции
Если есть необходимость ввести универсальную функцию, которая совместима на компьютерных платформах со старым внутренним форматом 1С (мне понадобилось для работы с Консолью Запросов на Windows), тогда полученные универсальные функции:
Функция УниверсальнаяЗначениеВСтрокуВнутр(Значение)
Попытка
возврат Вычислить("ЗначениеВСтрокуВнутр(Значение)");
Исключение
//Для мобильных приложений выполняем по правилам XMl-Функций, которые были переделаны:
возврат ЗначениеВСтрокуXML(Значение);
КонецПопытки;
КонецФункции
Функция УниверсальнаяЗначениеИзСтрокиВнутр(Значение)
Попытка
возврат Вычислить("ЗначениеИзСтрокиВнутр(Значение)");
Исключение
//Для мобильных приложений выполняем по правилам XMl-Функций, которые были переделаны:
возврат ЗначениеИзСтрокиXML(Значение);
КонецПопытки;
КонецФункции
Однако, если требуется поддержка и платформы 8.0 и мобильной платформы 8.3 (зачем прошу не спрашивать), включая многострадальный IOS (нет функции выполнить и вычислить), то гораздо проще воспользоваться следующими функциями:
//Для сложных типов данных - читаем через Хранилище Значения (метод 1с 8.0 и новее!!! - заменил БСП):
Функция ЗначениеВСтрокуXML(Значение) Экспорт
возврат XMLСтрока(новый ХранилищеЗначения(Значение));
КонецФункции
Функция ЗначениеИзСтрокиXML(СтрокаXML) Экспорт
возврат XMLЗначение(Тип("ХранилищеЗначения"),СтрокаXML).Получить();
КонецФункции
PS: приведенными функциями в пределах одной базы можно пользоваться на следующих платформах:
- Компьютерные: 1С 8.2 и 1С 8.3 - Тонкий, Толстый, ВебКлиент. Для 1с 8.0 и 8.1 - толстый клиент и сервер.
- Для одной базы данных, можно использовать функции сериализации в XML посредством методов XMLСтрока и XMLЗначение, предварительно упаковав в Хранилище значений. Последнее необходимо для сохранения данных. Тем более, что это работает для всех платформ и видов соединений с данными (Сервер, ТолстыйКлиент, Мобильные серверные части).
- На мобильных платформах 8.3 можно использовать универсальные переделанные функции БСП для аналога внутренних значений.
Тестировалось на платформах 8.2 и 8.3 для замены БСП функций. Режим совместимости с 8.1 не пострадал. Последние функции были проверены на платформе 1с 8.0.14.