Сжатие данных в мобильном приложении 1С:Предприятие

Публикация № 1067294

Учет и отчетность - Розничная торговля

сжатие данных мобильное приложение

41
Эту небольшую статью я планировал опубликовать у себя на сайте, чтобы такие любители мобильного приложения от 1С:Предприятие, как я, могли использовать её без дополнительно потраченных двух дней на поиски вариантов написания алгоритма. Во-первых, хотел сказать, что я небольшой разработчик, который начинал делать свои первые шаги ещё на заре правления "Семерки". Новая платформа версии 8 была как глоток свежего воздуха - бодрящий и легко воспринимаемый организмом. Я был очень удивлен, да что сказать, до сих пор удивляюсь как элементарные вещи можно делать на 1С, и как это стремно делается на других языках программирования. Во-вторых, обилие разнообразных интерпретаций платформы позволяет развернуться на все 360 градусов, захватив своими проектами, наверное, любые ветки бизнеса. Так вот, о небольшом нюансе работы с новой мобильной платформой я и хотел рассказать... Сам додумался, так сказать.

Я начал разрабатывать свой аналог мобильного приложения 1С:Заказы еще два года назад, но две версии программного продукта канули в лету: жесткий диск первого раза, а во второй раз проект убила моя лень.

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

Идея программы была простая и аналогична уже существующему приложению 1С:Заказы, за исключением несколько иного принципа обмена данными между самим приложением и учетной системой. Как правило, учетной системой на другой стороне обмена выступала такая же 1С, но с огромным функционалом типовых конфигураций. Сейчас приложение, пока что, работает только с УТП для Украины, но не суть...

На стороне учетной системы постоянно работает обработка, которая "мониторит" почтовый ящик на наличие определенных писем. Получая письмо "запрос", обработка отправляет письмо "ответ" и так бесконечно. Я планирую написать параллельную обработку писем, чтобы ускорить обработку запросов, но об этом чуть позже.

Что касается приложения, то мы имеем примерно вот такую структуру...

Основные опции:

1. Обмен заказами;

2. Обмен товарами, остатками, ценами;

3. Обмен параметрами работы менеджеров.

4. Пару документов, типа задачи, обмен координатами, показатели одометра и прочее.

Весь этот список, состоящий из пары пунктов привел к тому, что из учетной системы на КПК прилетал по почте файл размером более 20 Мб. Это при условии, что товаров около 14000 шт. Иные программы, которые использовались компаниями просто выпадали в осадок при таком количестве товаров с их 10 разными ценами и остатками по 5-6 складах.

Меня не устраивал тот факт, что элементарного обмена по ФТП в 1С до сих пор нет. И это просто громадная печаль! При этом обмен по почте был для меня единственным вариантом обмена. Я понимаю, что можно было бы сделать обмен по прямому подключению к web-серверу, но не у всех клиентов имеется в наличии опубликованная в Веб учетная система. И как правило, предложение осуществить подобное, вызывало массу недовольства у клиентов. Поэтому обмен по Web был исключен. Оставалась только почта.

Но, как я указал выше, есть недостаток - отсутствие сжатия данных! Кто знает почему нет возможности использовать Zip?

Использование внешних программ в моем приложении было бы неверным решением. Я очень хотел все сделать только средствами самой платформы 1С. Использование Acode Tools приводило к сбоям в самой программе. Ведь не у всех был мощный Samsung. В основном Xiaomi или менее мощные смартфоны.

Сжатие я сделал очень просто. В 1С есть ХранилищеЗначения" со степенью сжатия. Формируем в виде структуры в структуре данные, далее записываем его в хранилище значения со степенью сжатия, далее это хранилище записываем с структуру JSON в виде XMLСтрока. Именно эта строка и давала возможность сериализовать ХранилищеЗначения. В противном случае возникала проблема конвертации структуры в JSON. Да, я очень люблю структуры преобразовывать...
 

//Создадим структуру в качестве примера
СтруктураВыгрузки = Новый Структура();
СтруктураВыгрузки.Вставить("КоличествоЭлементовВыгрузки",1234);
	
Сообщить("Всего в файл записано: "+СтруктураВыгрузки.КоличествоЭлементовВыгрузки+" элементов.");
			
// Упакуем данные в аналог ZIP
ХранилищеЗначения = Новый ХранилищеЗначения(СтруктураВыгрузки, Новый СжатиеДанных(9));	
ДанныеВXMLСтроку = XMLСтрока(ХранилищеЗначения);

// Пересоздадим структуру для очистки памяти
СтруктураВыгрузки = Новый Структура();
СтруктураВыгрузки.Вставить("Данные", ДанныеВXMLСтроку);
	    		
// Готовим имя файла для дальнейшего сохранения и выгрузки
АйдиПользователя = ТекПользователь.УникальныйИдентификатор();
ИмяФайла = АйдиПользователя;
ПолноеИмяФайла = КаталогВременныхФайлов() + "update_"+ИмяФайла;
ПолноеИмяФайлаСРасширением = ПолноеИмяФайла + ".json";
	
// Запишем все данные в формате JSON
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьФайл(ПолноеИмяФайлаСРасширением);       
ЗаписатьJSON(ЗаписьJSON,СтруктураВыгрузки,,);
ЗаписьJSON.Закрыть();


Распаковка данных происходит достаточно быстро и даже 20 мб обмена не влияет на время выполнения кода. Я признаться, не замерял отладчиком, но визуально такие обмены происходят в допустимых скоростях. При этом использовались исключительно средства самой 1С, чего было достаточно, что бы обмен успешно отработал в тестовом режиме уже более 2 месяцев. Без ошибок в упаковке-распаковке.
 

// Чтение файла обновления
ЧтениеJSON = Новый ЧтениеJSON(); 
ЧтениеJSON.ОткрытьФайл(ФайлДанных); 
СтруктураОтвета = ПрочитатьJSON(ЧтениеJSON); 
ЧтениеJSON.Закрыть();

// Данные упакованы в хранилище значения со степенью сжатия 9. Аналог ZIP	
ХранилищеЗначения = XMLЗначение(Тип("ХранилищеЗначения"),СтруктураОтвета.Данные);	
СтруктураОтвета = ХранилищеЗначения.Получить();
	
// Проверка перед началом работы
Если ТипЗнч(СтруктураОтвета) <> Тип("Структура") Тогда
    Ответ = Общий.ВернутьРезультатПользователю("Файл обновления поврежден!",Ложь,Истина, Истина);			
    Возврат Ответ;		
КонецЕсли;

// Далее уже работа по обработке данных файла обмена


Можно сказать, что это очень легко и можно таких примеров кода найти кучу, но поверьте я искал и именно для мобильного приложения не нашел даже пары строк в подобной интерпретации. Что бы было понятно, легко и быстро в интеграции. Все в основной массе предлагали записывать с Zip какими-то путями потом его распаковывать, а тут способ легкий и без проблем исполняемый.

Лучшего способа я не нашел, а потому принимаю любую критику в обмен на мою благодарность. :)

41

См. также

Специальные предложения

Комментарии
Избранное Подписка Сортировка: Древо
1. script 205 27.05.19 11:02 Сейчас в теме
Понравилась переменная АйдиПользователя.
И способ рабочий даже для обмена по HTTP.
2. mevgenym 84 27.05.19 16:13 Сейчас в теме
имхо проще можно

ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ПолноеИмяФайлаСРасширением, "UTF-8");
ЗаписатьXML(ЗаписьXML, ХранилищеЗначения);
ЗаписьXML.Закрыть();


обратно через ПрочитатьXML

через JSON
СтруктураВыгрузки = Новый Структура("Данные", ХранилищеЗначения); //вроде должен сериализовать
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьФайл(ПолноеИмяФайлаСРасширением, "UTF-8");
ЗаписатьJSON(ЗаписьJSON, СтруктураВыгрузки);
ЗаписьJSON.Закрыть();


минус случайно поставился, не виноватая я
3. YPermitin 3958 27.05.19 16:27 Сейчас в теме
(2) так уберите случайный минус. Статья то хорошая :)
4. yarsort 27.05.19 16:42 Сейчас в теме
(2) Вы правы, можно через XML, но я не любитель этого формата. JSON последнее время зашел мне не по-детски. Тащусь от его простоты и возможности конвертации данных из JSON в структуру с массивами и обратно. Просто и безо всяких веток и деревьев. :)
izidakg; TreeDogNight; 🅵🅾️🆇; vovaikilko; CyberCerber; +5 Ответить
5. V1V 112 27.05.19 18:03 Сейчас в теме
столько слов чтобы рассказать о параметре СжатиеДанных. Н-да... Без комментариев.
androidT1C; GreenDragon; SirStefan; Dream_kz; +4 Ответить
6. Dream_kz 93 27.05.19 18:24 Сейчас в теме
Эмм, вся статья о втором параметре объекта ХранилищеЗначения? Это есть в бесплатном курсе по разработке мобильных приложений (2014 года).

По поводу ftp, устаревший протокол, мобильная платформа прекрасно работает с webdav, можно работать через яндекс диск, или гугл драйв, одной строкой кода
8. vsesam80 27.05.19 19:59 Сейчас в теме
(6)Можете скинуть пример работы с webdav Яндекс диска? Записать у меня получилось на ЯД, а скопировать на диск никак.
9. yarsort 27.05.19 20:07 Сейчас в теме
(6)
webdav
За webdav не слышал. Есть примеры кода обмена?
10. Dream_kz 93 27.05.19 20:14 Сейчас в теме
(9)
(8)

ЯндексДискСтрокаПодключения = "https://%user%:%password%@webdav.yandex.ru/";
    ЯндексДискСтрокаПодключения = СтрЗаменить(ЯндексДискСтрокаПодключения, "%user%", "login");
    ЯндексДискСтрокаПодключения = СтрЗаменить(ЯндексДискСтрокаПодключения, "%password%", КодироватьСтроку("password", СпособКодированияСтроки.КодировкаURL));

    
    Файл = "C:\123.xml";
        
    НовыйФАйл = ЯндексДискСтрокаПодключения + "123.xml";
    
    КопироватьФайл(Файл, НовыйФАйл);
Показать


пути компьютерные, на мобильном надо использовать относительные (КаталогДокументов(), КаталогВременныхФайлов() и т.д)
freed; TreeDogNight; siddy; Serj1C; Aleskey_K; yarsort; +6 Ответить
7. KereberoS 3 27.05.19 19:38 Сейчас в теме
Вы ещё добавили в УТП путевые листы?

Бекап - то, что требуем с пользователей, но не думаем о себе :)

Мобильное приложение по заказам для УТП заинтересовало, можно в личку условия?
11. yarsort 27.05.19 20:20 Сейчас в теме
(7) Путевые листы в разработке. Как раз идет обсуждение принципа обмена. Но в приложении собирать данные о перемещении в ручном режиме уже можно. GPS позиционирование в теории может собирать метки, но механизм пока не нашел применение, а потому надо допиливать. В целом базовый принцип уже есть.
12. yarsort 120 27.05.19 20:47 Сейчас в теме
(7) По поводу приложения: я разрабатывал для типовой конфигурации УТП для Украины. Есть заказы, возвраты, оплаты. Все работает в связке со специальной обработкой. Каждому пользователю настройка и общий обмен через почтовый ящик. Тестируют пока что 10 человек. На данный момент безошибочно работает уже неделю на полную катушку - около 100 заказов в сутки. Если хотите быть тестером - буду рад. По поводу оплаты пока не думал. В будущем будет демократическая цена и надеюсь заработать на массовости использования.
19. script 205 28.05.19 14:15 Сейчас в теме
(7) Вот я когда-то делал путевые листы для бух 8.2
https://infostart.ru/public/151143/
Т.к. доработка модульная, легко перекинуть в УТП.

Недавно переделал ее для Бух 2.0. - скоро тоже выложу.
13. 🅵🅾️🆇 424 28.05.19 01:38 Сейчас в теме
(0) Могу предложить более оригинальный подход: используйте побитовые операции.
В 1 байте (букве) можно уместить аж 8 булевых. Два числа или перечисления до 15 или одно число до 255, а в двух буквах уже число от 0 до 65 тысяч.
И отправлять это дело двоичными данными (ну или в base64).

А вообще на носу http/2 и grpc - вот где прагматическая емкость со скоростью во все поля)
14. SirStefan 37 28.05.19 05:56 Сейчас в теме
15. yarsort 120 28.05.19 08:28 Сейчас в теме
(14) Может быть. Но я после разговора с владельцем этого форума и понимания что его владелец ненормальный человек, я больше туда не хожу. Поэтому не читаю Мисту. Но с другой стороны, видимо зря не ходил, а так нашел бы Вашу заметку. :)
16. yarsort 120 28.05.19 08:32 Сейчас в теме
(14) Значит я актуализировал Ваши знания с небольшой доработкой в JSON.
17. SirStefan 37 28.05.19 08:59 Сейчас в теме
(16) , Почти. У меня нет промежуточного сохранения файла на диск. Все в памяти. А СжатиеДанных(9) лучше не ставить. Скорость обработки замедляется, но выигрыш в размере не сильно больше чем у СжатиеДанных(1). Попробуйте сравнить...
18. asdf_88 28.05.19 14:11 Сейчас в теме
(17)
Почти. У меня нет промежуточного сохранения файла на диск. Все в памяти.

С операциями в памяти надо быть внимательным, иначе можно много памяти съесть за вызов, если на вход придет очень много данных.
20. SirStefan 37 28.05.19 14:35 Сейчас в теме
(18) Так он все равно создаётся, распаковывается, обрабатывается в памяти.
21. asdf_88 28.05.19 16:12 Сейчас в теме
(20) Ну да, только у вас еще весь файл в памяти, а не на диске. В угоду скорости вполне хорошее решение.
ЧтениеJSON с диска читает блоками, а не полностью файл поднимает с диска в память. Или я ошибаюсь?
22. SirStefan 37 28.05.19 17:47 Сейчас в теме
(21) вроде блоками. А запись будет блоками или сперва сформирует, потом запишет? Хотя для обмена у меня файлы больше 40 мегабайт не выходили вроде. А на планшетах по 3Gb оперативки. Должно хватать.
23. palsergeich 28.05.19 23:26 Сейчас в теме
Откажитесь от штатного сериализатора и напишите свой json формат. В штатном механизме слишком много мусора.
Упаковывая структуру в хранилище значений чуда не происходит)
Я именно так 2 года назад сделал, что то похожее на КД3, только на JSON. Результат фантастический.
Если XML сериализация за год - только сериализация занимала минуту, то свой велосипед - 10 секунд сериализация + передача+десериализация. Объем уменьшился в сотни раз.
TreeDogNight; acanta; +2 Ответить
24. androidT1C 72 29.05.19 16:16 Сейчас в теме
(23) Это же под каждый объект свой велосипед изобретать? И это быстрее? Как?
25. palsergeich 29.05.19 16:28 Сейчас в теме
(24)
(23) Это же под каждый объект свой велосипед изобретать? И это быстрее? Как?

не, велосипед один, но каждый объект - декларативно описывается, да
27. androidT1C 72 30.05.19 10:12 Сейчас в теме
(25) Как самописные циклы, например, по ТаблицеЗначений из 100000 строк, с анализом типов и пр., могут работать быстрее, чем платформенная сериализация в XML этой же ТЗ?
26. yarsort 120 29.05.19 17:26 Сейчас в теме
У меня и так свой формат JSON. Я не сериализирую объекты из учетной системы в том виде, в каком их хранит 1С.
Оставьте свое сообщение