Внешняя компонента для хранения данных во внешней обработке/отчете



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

Захотел решить для себя интересную задачу — хранение произвольных данных во внешней обработке/отчете. Как-то давным-давно, мне хотелось сделать такую обработку, чтобы все накапливаемые данные носить вместе с ней, но тогда не знал, как такое сделать. Я понимаю, что для большинства людей это может показаться бесполезной фиговиной, но повторюсь — писал для себя и по большей части потому, что было просто интересно реализовать такую возможность.
Внешняя компонента написана по технологии Native API, имеет всего 3 метода и 1 свойство.

Методы:
1. «SaveDataInExternalObject» («СохранитьДанныеВоВнешнийОбъект«) — сохраняет данные во внешнюю обработку/отчет. Имеет три параметра. 1-ый параметр — имя файла внешней обработки/отчета. 2-ой параметр — сами данные в виде строки. 3-й параметр — степень сжатия данных в виде числа от 0 до 9 (0 — не использовать сжатие). Значение никакое не возвращает.
2. «LoadDataFromExternalObject«, («ЗагрузитьДанныеИзВнешнегоОбъекта«) — загружает данные из внешней обработки/отчета. Имеет один параметр — имя файла внешней обработки/отчета. Возвращает сохраненные данные в виде строки.
3. «DeleteDataFromExternalObject«, («УдалитьДанныеИзВнешнегоОбъекта«) — удаляет данные из внешней обработки/отчета (приводит обработку к первоначальному состоянию). Имеет один параметр — имя файла внешней обработки/отчета. Значение никакое не возвращает.

Свойства:
1. «Version» («Версия«) — содержит версию компоненты в виде строки. Данное свойство доступно только для чтения.
Прилагаемая внешняя обработка демонстрирует сохранение содержимого свой табличной части в сам файл внешней обработки.

Естественно, размер файла обработки увеличивается или уменьшается в зависимости от объема хранимых в обработке данных. Также хочу сказать, что весь программный код без какой-либо доработки можно использовать и с внешними отчетами. Далее я приведу пример кода и обработки для обычного приложения, т.к. он более нагляден. В обработке описаны процедура и функция «обертки» для использования методов внешней компоненты:

// Получает сохраненные данные текущей внешней обработки/отчета.
// Является "оберткой" для метода "ЗагрузитьДанныеИзВнешнегоОбъекта" внешней компоненты,
// которая берет на себя всю "грязную" работу по десериализации полученных данный
// и обработке исключительных ситуаций
//
// Параметры:
// ОбъектВнешнейКомпоненты - ВнешняяКопонента - Объект внешней компоненты
//
// Возвращаемое значение:
// Произвольный - Десериализованные данные хранящиеся в обработке.
//
Функция ПолучитьДанныеИзВнешнегоОбъекта(ОбъектВнешнейКомпоненты) Экспорт
Результат = Неопределено;

ИмяФайла = ЭтотОбъект.ИспользуемоеИмяФайла;
Данные = ОбъектВнешнейКомпоненты.ЗагрузитьДанныеИзВнешнегоОбъекта(ИмяФайла);
Если Не ПустаяСтрока(Данные) Тогда
Попытка
Результат = ЗначениеИзСтрокиВнутр(Данные);
Исключение
Сообщить(ОписаниеОшибки(), СтатусСообщения.Внимание);
КонецПопытки;
КонецЕсли;

Возврат Результат;
КонецФункции

// Записывает произвольные данные в файл внешней обработки/отчета
//
// Параметры:
// ОбъектВнешнейКомпоненты - ВнешняяКопонента - Объект внешней компоненты
//  Данные - Произвольный - Данные произвольного типа который можно сериализовать с помощью функции "ЗначениеВСтрокуВнутр"
//
Процедура ЗаписатьДанныеВоВнешнийОбъект(ОбъектВнешнейКомпоненты, Данные) Экспорт
ИмяФайла = ЭтотОбъект.ИспользуемоеИмяФайла;
ОбъектВнешнейКомпоненты.СохранитьДанныеВоВнешнийОбъект(ИмяФайла, ЗначениеВСтрокуВнутр(Данные));
КонецПроцедуры
// Удаляет данные из файла внешней обработки/отчета (приводит файл к первоначальному состоянию)
//
// Параметры:
// ОбъектВнешнейКомпоненты - ВнешняяКопонента - Объект внешней компоненты
//
Процедура УдалитьДанныеИзВнешнегоОбъекта(ОбъектВнешнейКомпоненты) Экспорт
ИмяФайла = ЭтотОбъект.ИспользуемоеИмяФайла;
ОбъектВнешнейКомпоненты.УдалитьДанныеИзВнешнегоОбъекта(ИмяФайла);
КонецПроцедуры

Данные процедуры и функции лишь демонстрируют пример работы с методами внешней компоненты.
В качестве практического примера использования можно привести какой-нибудь внешний универсальный отчет, который хранит все свои настройки в себе. А вообще применение, как всегда, зависит исключительно от фантазии программиста. Недостатком такого хранения данных является то, что все данные сохраненные во внешней обработке/отчете автоматически стираются, если обработку/отчет открыть в конфигураторе и пересохранить. Как вариант можно установить обработке атрибут «только чтение», тогда конфигуратор при сохранении будет просить указать ему др. имя файла, а в обработке перед сохранением данных программно снимать атрибут «только чтение» и устанавливать его после сохранения данных.

Также упомяну, что не несу никакой ответственности за сохранность данных при использовании моей компоненты, используйте ее только на свой страх и риск. У меня вроде нормуль все работает. Если кому будет интересно, то попробую оптимизировать компоненту под работу с большими объемами данных.

В данной публикации можно скачать обработку для обычного приложения и для управляемого приложения, работающего в асинхронном режиме. Обработка для управляемого приложения написана в спешке, так что красивый код напишите сами. Обработки проверялись на платформе 8.3.6.2390.

P.S. Это моя первая публикация, прошу сильно не унижать…

Update 2024.03.02
1. Обновил внешнюю компоненту: по наводке vec435 добавил метод «УдалитьДанныеИзВнешнегоОбъекта»;
2. Обновил внешнюю компоненту: добавил возможность сжатия данных методом Deflate (3-й параметр метода «СохранитьДанныеВоВнешнийОбъект»);
3. Обновил обработки для обычного и управляемого приложения; 

Update 2024.01.16
Обновил обработку для управляемого приложения: постарался сделать код более чистым, наглядным, и исправил несколько недочетов. Сподвиг меня на это mrXoxot

32 Comments

  1. CyberCerber

    Интересная штуковина!

    А внешняя компонента идет вместе с обработкой?

    Конечно, то, что данные перезатираются при сохранении — это серьезный минус…

    А куда записываете эти данные? Не можете реализовать запись в спец макет с двоичными данными? Тогда ничего перезатираться не будет.

    P.S. Зашел из-за бутылки Клейна. Хорошая иллюстрация. 🙂

    Reply
  2. alex_4x

    Исходников самой внешней компоненты нет ?

    Reply
  3. ekaruk

    Интересная идея.

    Хороша как защита от изменения внешней обработки пользователем.

    Изменил что-то и уже не работает.

    Reply
  4. Evil Beaver

    (3) ekaruk, а ведь отличная идея же! И обфусцировать не надо!

    Запросил конфигурацию оборудования у клиента, прошил в обработке — привязал к машине 🙂 И без v8Unpack не достанешь

    Reply
  5. frkbvfnjh

    Да CyberCerber , внешняя компонента находится в макете каждой обработки. В двоичный макет пока не могу писать. Попробую разобраться с исходниками V8Unpack, возможно напишу более интересную вещь.

    Reply
  6. frkbvfnjh

    Исходник пока не буду выкладывать. возможно позже… Там все ооочень просто. Если ни у кого не будет нареканий на работу таких обработок, то позже гляди и исходник опубликую.

    Reply
  7. Davurov

    Круто! Как появятся старт мани, скачаю =)

    Reply
  8. kostik_love

    Круто! Начал думать- где я это смогу применить…

    Плюс однозначно!

    Reply
  9. Romany

    Здравствуйте. А вот скажите, будет ли работать это решение на платформе linux? Было бы замечательно, если Вы спроектировали компоненту кроссплатформенной. Или я не о том?

    Reply
  10. frkbvfnjh

    Да, думаю смогу собрать компоненту под Linux, надо только время выбрать

    Reply
  11. CyberCerber

    (4) Evil Beaver, вот только, чтобы сделать защиту, надо зашить в данные почти весь функционал обработки. Иначе можно просто закомментить эту проверку.

    Ну а тут надо протестить, не повлияет ли это на быстродейстиве и работоспособность.

    Reply
  12. klinval

    Идея прикольная, вот только где бы её применить….

    (4) Evil Beaver, (11) CyberCerber, в отладке Shift+F9 и видишь всё что вернула обработка по LoadDataFromExternalObject. Т.е. код и конфигурацию оборудования там не скроешь от программиста.

    Reply
  13. CyberCerber

    (12) klinval, и то верно… Значит, надо еще пароль накладывать или модуль исключать.Тогда при вскрытии, как я понимаю, обработку надо будет пересохранить, а следовательно весь нужный код удалится.

    Reply
  14. ekaruk

    (11) CyberCerber, Весь не обязательно.

    Можно даже не закрывать.

    Достаточно просто поместить макеты внутрь обработки.

    А проверка может быть простейшая. Например «Если ТекущаяДата()>»20160201″ Тогда Возврат»

    Как только пользователь захочет ее убрать, ему придется пересохранить обработку и макеты просто исчезнут.

    Я динамически выловить макеты не внося изменения в код не каждый сможет даже из программистов, не говоря уже о пользователях.

    Reply
  15. caponid

    (10) будем ждать… только нужно под Lin как х86 так и х64

    Reply
  16. CyberCerber

    (14) ekaruk, да, если главное в обработке — макеты, то как раз то, что нужно. Это для отчетов хорошо. А вот если весь смысл в коде…

    Reply
  17. alex_4x

    Было бы прикольно научиться записывать изменения в модуль кода внутри обработки 🙂

    Reply
  18. Lancelot-2M

    по поводу потери данных при сохранении — я с помощью v8Unpack докидывал файл в обработку и после пересохранения обработки конфигуратором ничего не терялось.

    Reply
  19. frkbvfnjh

    (18) Lancelot-2M, да, в будущем примерно так и хочу сделать

    Reply
  20. frkbvfnjh

    (14) ekaruk, идея кстати хорошая, хранимую информацию в обработке можно использовать как одноразовый «предохранитель», т.е. к примеру, можно сохранить в обработке другую обработку в виде двоичных данных в которой и будет весь нужный функционал. Эту обработку можно будет подключить как внешнюю из двоичных данных. В основной обработке, например, сделать проверку какой-нибудь лицензии для подключения хранимой в двоичных данных обработки. И все это писать наглым открытым кодом, ведь чтобы отключить проверку, нужно как минимум закоментить эту проверку и сохранить обработку. А вот тут-то «предохранитель» и сгорит. Обработку из двоичных данных к слову можно будет пересохранить в др. файл через отладку, но здесь тоже можно схитрить. Ко всему прочему во внешнюю компоненту можно добавить какое-нибудь простенькое шифрование, на случай если смогут «выкорчевать» сохраненные в обработке данные, тогда их нужно будет еще и дешифровать. Так что основной недостаток данной обработки можно использовать даже как преимущество. А обработка, в которой данные будут сохраняться после перезаписи, будет использоваться для совершенно других целей. Даже сам не думал, что данное решение можно попробовать в качестве защиты. Хотя может не все так просто и я пока что не вижу полной картины, но так или иначе все в конечном счете можно взломать…

    Reply
  21. kite2

    Не качал, но пометил звездой, просто чтобы не забыть

    Reply
  22. Ibrogim

    (16) CyberCerber,

    да, если главное в обработке — макеты, то как раз то, что нужно. Это для отчетов хорошо. А вот если весь смысл в коде…

    Можно в макете скд например хранить все запросы обработки. Без них обработка может быть бесполезна

    Reply
  23. MRAK

    (16) CyberCerber, часть кода можно хранить в текстовом макете

    Reply
  24. Рэйв

    А чего бы в макетах не хранить как двоичные данные то что гоняется через ВК? У меня так в одной внешней обработке собран весь инструментарий чтобы все в одном месте лежало. И никаких ВК не надо

    Reply
  25. ekaruk

    (24) Рэйв, Смысл в том, что ВК в процессе работы позволяет программно сохранять данные в саму обработку, т.е. в ее файл.

    Макеты нужно делать отдельно вручную в конфигураторе.

    Reply
  26. vec435

    конечно сохранение доп. данных в макета через V8Unpack — то чего так не хватает

    Reply
  27. vec435

    есть ли очистка от ненужных данных?

    Reply
  28. frkbvfnjh

    Да, о полном удалении данных чёт не подумал… В принципе можно сохранить в обработку значение «Неопределено», но это все равно будет значение, и все равно будет занимать место, хотя и совсем не много. Думаю добавлю такой метод, и пожалуй добавлю сжатие данных deflate’ом.

    Reply
  29. frkbvfnjh

    (27) vec435, добавил очистку и сжатие…

    Reply
  30. fishca

    Макеты (файлы справки к примеру, насколько я понимаю) объектов хранятся в виде сжатых данных по алгоритму Deflate в виде Base64 строки. Так что теоретически засунуть в обработку возможно все 🙂

    Reply
  31. fishca

    И вполне возможно создавать свои объекты (макеты), главное их формат сохранить

    Reply
  32. rus128

    Как истинный перфекционист — заметил опечатки в описании:

    1) «имеет всего 2 метода» — так 3 метода же! 🙂

    2) «степень сжатия данных ввиде числа» — нужен пробел для «в_виде»;

    3) в описании 3-го метода — «прЕводит»;

    4) в описании свойства «Версия» — «данноЙ свойство»;

    5) «можно использовать и с внешними отчета» — упущено «…МИ»;

    6) «лишь демонстрирую(?) пример работы» — пропущено «Т».

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *