При разработке мобильных решений на платформе 1С часто возникает задача: сформировать аналитический отчет или график на стороне основного сервера и отобразить его на мобильном клиенте (планшете или смартфоне) через веб-сервис. Однако при попытке прямой сериализации объектов типа Диаграмма или табличных документов с внедренными графиками разработчики сталкиваются с ошибками десериализации на мобильном устройстве.
Разберем подробно, почему возникает эта проблема, как правильно настроить передачу данных через XDTO и ХранилищеЗначения, а также какие архитектурные подходы гарантируют стабильное отображение диаграмм на мобильной платформе.
Проанализируем технические особенности взаимодействия десктопной и мобильной платформ 1С:
Chart через XDTO-пакеты часто завершается ошибкой, так как сериализатор платформы не всегда может однозначно сопоставить сложный составной объект диаграммы между различными версиями и сборками платформ.ХранилищеЗначения передает внутреннее бинарное представление объекта, которое мобильный клиент не всегда может корректно прочитать.Если требуется передать стандартный табличный отчет (таблицу), наилучшим решением является сериализация объекта ТабличныйДокумент в XML с последующей упаковкой или прямая работа со строкой XML через ЗаписьXML и СериализаторXDTO.
Посмотрим на корректную реализацию сериализации и десериализации на стороне сервера и клиента.
1. Код веб-сервиса на стороне сервера:
Функция ПолучитьОтчет(Отбор) Экспорт
ОтчетОбъект = Отчеты.СчетаНаОплату.Создать();
ТабличныйДок = Новый ТабличныйДокумент;
ОтчетОбъект.СкомпоноватьРезультат(ТабличныйДок);
// Сериализуем табличный документ в строку XML
СтрокаXML = СериализоватьОбъект(ТабличныйДок);
// Возвращаем упакованное хранилище значения со сжатием
Возврат Новый ХранилищеЗначения(СтрокаXML, Новый СжатиеДанных(9));
КонецФункции
Функция СериализоватьОбъект(ОбъектСериализации)
ДеревоXDTO = СериализаторXDTO.ЗаписатьXDTO(ОбъектСериализации);
Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку(); // Обязательно инициализируем запись в строку
ФабрикаXDTO.ЗаписатьXML(Запись, ДеревоXDTO);
Возврат Запись.Закрыть();
КонецФункции
2. Получение и обработка данных на клиенте:
&НаСервере
Процедура СформироватьОтчетНаСервере()
Попытка
ВСОпределение = Новый WSОпределения("http://server/base/ws/DataTransfer?wsdl");
ВСПрокси = Новый WSПрокси(ВСОпределение, "DataTransfer", "ОбменДанными", "ОбменДаннымиSoap");
ДанныеXDTO = ВСОпределение.ФабрикаXDTO.Создать(ВСПрокси.ТочкаПодключения.Интерфейс.Операции.Получить("ПолучитьОтчет").Параметры.Получить("Отбор").Тип, "");
// Получаем хранилище значения из веб-сервиса
ХранилищеОтвет = ВСПрокси.ПолучитьОтчет(ДанныеXDTO);
Если ХранилищеОтвет <> Неопределено Тогда
СтрокаXML = ХранилищеОтвет.Получить();
ТабличныйДокумент = ДесериализоватьОбъект(СтрокаXML);
КонецЕсли;
Исключение
Сообщить("Ошибка при получении отчета: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
&НаСервере
Функция ДесериализоватьОбъект(СтрокаXML)
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(СтрокаXML);
Результат = СериализаторXDTO.ПрочитатьXML(Чтение);
Чтение.Закрыть();
Возврат Результат;
КонецФункции
Если отчет содержит сложную диаграмму, самый надежный и нетребовательный к ресурсам планшета вариант — сформировать изображение диаграммы на сервере и передать его клиенту в виде двоичных данных (тип base64Binary).
Разберем алгоритм реализации:
ТабличныйДокумент.ТабличныйДокумент.Рисунки объект диаграммы или формируем отдельный объект Диаграмма.ПолучитьКартинку() для сохранения графического представления в формате PNG или JPEG.ДвоичныеДанные картинки через веб-сервис и выводим их на форму в элемент управления с типом Картинка.
// Серверная функция веб-сервиса
Функция ПолучитьДиаграммуКартинкой() Экспорт
ТабДок = Новый ТабличныйДокумент;
ОтчетОбъект = Отчеты.ПродажиГрафик.Создать();
ОтчетОбъект.СкомпоноватьРезультат(ТабДок);
// Извлекаем диаграмму из рисунков табличного документа
Для Каждого Рисунок Из ТабДок.Рисунки Цикл
Если ТипЗнч(Рисунок.Объект) = Тип("Диаграмма") Тогда
КартинкаДиаграммы = Рисунок.Объект.ПолучитьКартинку();
Возврат КартинкаДиаграммы.ПолучитьДвоичныеДанные();
КонецЕсли;
КонецЦикла;
Возврат Неопределено;
КонецФункции
На мобильном клиенте полученные ДвоичныеДанные помещаются в реквизит формы с типом Строка (навигационная ссылка во временном хранилище) или преобразуются в объект Картинка:
&НаКлиенте
Процедура ОтобразитьГрафик(ДвоичныеДанныеКартинки)
АдресКартинки = ПоместитьВоВременноеХранилище(ДвоичныеДанныеКартинки, УникальныйИдентификатор);
Элементы.ПолеКартинкиДиаграмма.Картинка = Новый Картинка(ДвоичныеДанныеКартинки);
КонецПроцедуры
Если требуется сохранить интерактивность (всплывающие подсказки, масштабирование, выделение серий), рекомендуется передавать с сервера не визуальный объект, а «сырые» данные (массив структур или JSON), после чего программно заполнять элемент формы ПолеДиаграммы непосредственно в мобильном приложении.
Посмотрим на пример заполнения диаграммы на клиенте:
&НаКлиенте
Процедура ЗаполнитьДиаграммуПоДанным(МассивТочек, МассивСерий, ТаблицаЗначенийДанных)
ДиаграммаЭлемент = Элементы.ДиаграммаОтчета;
ДиаграммаЭлемент.Обновление = Ложь; // Отключаем перерисовку на время заполнения
ДиаграммаЭлемент.Очистить();
ДиаграммаЭлемент.ТипДиаграммы = ТипДиаграммы.Гистограмма;
// Заполнение точек и серий
Для Каждого Стр Из ТаблицаЗначенийДанных Цикл
Точка = ДиаграммаЭлемент.УстановитьТочку(Стр.Период);
Серия = ДиаграммаЭлемент.УстановитьСерию(Стр.Подразделение);
ДиаграммаЭлемент.УстановитьЗначение(Точка, Серия, Стр.Сумма);
КонецЦикла;
ДиаграммаЭлемент.Обновление = Истина;
КонецПроцедуры
Если требуется сохранить оригинальное форматирование табличного документа со всеми ячейками и расшифровками, можно использовать сохранение в поток или временный файл формата MXL:
ТабличныйДокумент.Записать(ИмяВременногоФайла, ТипФайлаТабличногоДокумента.MXL).ДвоичныеДанные и передаем его через веб-сервис (тип base64Binary).ТабличныйДокумент.Прочитать(ИмяФайла).
// На стороне мобильного клиента
ИмяФайла = ПолучитьИмяВременногоФайла("mxl");
ДвоичныеДанныеОтвета.Записать(ИмяФайла);
Элементы.ПолеТабличногоДокумента.Прочитать(ИмяФайла);
УдалитьФайлы(ИмяФайла);
Современным и гибким подходом для мобильных приложений 1С является формирование графика с помощью JavaScript-библиотек (например, Chart.js или CanvasJS) внутри элемента формы Поле HTML документа:
Подведем итоги выбора технологии передачи графиков:
ДвоичныеДанные — это исключает любые ошибки несовместимости платформ.ХранилищеЗначения со сжатием.Поле диаграммы либо Поле HTML документа программно на стороне мобильного клиента.