Захотел решить для себя интересную задачу — хранение произвольных данных во внешней обработке/отчете. Как-то давным-давно, мне хотелось сделать такую обработку, чтобы все накапливаемые данные носить вместе с ней, но тогда не знал, как такое сделать. Я понимаю, что для большинства людей это может показаться бесполезной фиговиной, но повторюсь — писал для себя и по большей части потому, что было просто интересно реализовать такую возможность.
Внешняя компонента написана по технологии 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
Интересная штуковина!
А внешняя компонента идет вместе с обработкой?
Конечно, то, что данные перезатираются при сохранении — это серьезный минус…
А куда записываете эти данные? Не можете реализовать запись в спец макет с двоичными данными? Тогда ничего перезатираться не будет.
P.S. Зашел из-за бутылки Клейна. Хорошая иллюстрация. 🙂
Исходников самой внешней компоненты нет ?
Интересная идея.
Хороша как защита от изменения внешней обработки пользователем.
Изменил что-то и уже не работает.
(3) ekaruk, а ведь отличная идея же! И обфусцировать не надо!
Запросил конфигурацию оборудования у клиента, прошил в обработке — привязал к машине 🙂 И без v8Unpack не достанешь
Да CyberCerber , внешняя компонента находится в макете каждой обработки. В двоичный макет пока не могу писать. Попробую разобраться с исходниками V8Unpack, возможно напишу более интересную вещь.
Исходник пока не буду выкладывать. возможно позже… Там все ооочень просто. Если ни у кого не будет нареканий на работу таких обработок, то позже гляди и исходник опубликую.
Круто! Как появятся старт мани, скачаю =)
Круто! Начал думать- где я это смогу применить…
Плюс однозначно!
Здравствуйте. А вот скажите, будет ли работать это решение на платформе linux? Было бы замечательно, если Вы спроектировали компоненту кроссплатформенной. Или я не о том?
Да, думаю смогу собрать компоненту под Linux, надо только время выбрать
(4) Evil Beaver, вот только, чтобы сделать защиту, надо зашить в данные почти весь функционал обработки. Иначе можно просто закомментить эту проверку.
Ну а тут надо протестить, не повлияет ли это на быстродейстиве и работоспособность.
Идея прикольная, вот только где бы её применить….
(4) Evil Beaver, (11) CyberCerber, в отладке Shift+F9 и видишь всё что вернула обработка по LoadDataFromExternalObject. Т.е. код и конфигурацию оборудования там не скроешь от программиста.
(12) klinval, и то верно… Значит, надо еще пароль накладывать или модуль исключать.Тогда при вскрытии, как я понимаю, обработку надо будет пересохранить, а следовательно весь нужный код удалится.
(11) CyberCerber, Весь не обязательно.
Можно даже не закрывать.
Достаточно просто поместить макеты внутрь обработки.
А проверка может быть простейшая. Например «Если ТекущаяДата()>»20160201″ Тогда Возврат»
Как только пользователь захочет ее убрать, ему придется пересохранить обработку и макеты просто исчезнут.
Я динамически выловить макеты не внося изменения в код не каждый сможет даже из программистов, не говоря уже о пользователях.
(10) будем ждать… только нужно под Lin как х86 так и х64
(14) ekaruk, да, если главное в обработке — макеты, то как раз то, что нужно. Это для отчетов хорошо. А вот если весь смысл в коде…
Было бы прикольно научиться записывать изменения в модуль кода внутри обработки 🙂
по поводу потери данных при сохранении — я с помощью v8Unpack докидывал файл в обработку и после пересохранения обработки конфигуратором ничего не терялось.
(18) Lancelot-2M, да, в будущем примерно так и хочу сделать
(14) ekaruk, идея кстати хорошая, хранимую информацию в обработке можно использовать как одноразовый «предохранитель», т.е. к примеру, можно сохранить в обработке другую обработку в виде двоичных данных в которой и будет весь нужный функционал. Эту обработку можно будет подключить как внешнюю из двоичных данных. В основной обработке, например, сделать проверку какой-нибудь лицензии для подключения хранимой в двоичных данных обработки. И все это писать наглым открытым кодом, ведь чтобы отключить проверку, нужно как минимум закоментить эту проверку и сохранить обработку. А вот тут-то «предохранитель» и сгорит. Обработку из двоичных данных к слову можно будет пересохранить в др. файл через отладку, но здесь тоже можно схитрить. Ко всему прочему во внешнюю компоненту можно добавить какое-нибудь простенькое шифрование, на случай если смогут «выкорчевать» сохраненные в обработке данные, тогда их нужно будет еще и дешифровать. Так что основной недостаток данной обработки можно использовать даже как преимущество. А обработка, в которой данные будут сохраняться после перезаписи, будет использоваться для совершенно других целей. Даже сам не думал, что данное решение можно попробовать в качестве защиты. Хотя может не все так просто и я пока что не вижу полной картины, но так или иначе все в конечном счете можно взломать…
Не качал, но пометил звездой, просто чтобы не забыть
(16) CyberCerber,
Можно в макете скд например хранить все запросы обработки. Без них обработка может быть бесполезна
(16) CyberCerber, часть кода можно хранить в текстовом макете
А чего бы в макетах не хранить как двоичные данные то что гоняется через ВК? У меня так в одной внешней обработке собран весь инструментарий чтобы все в одном месте лежало. И никаких ВК не надо
(24) Рэйв, Смысл в том, что ВК в процессе работы позволяет программно сохранять данные в саму обработку, т.е. в ее файл.
Макеты нужно делать отдельно вручную в конфигураторе.
конечно сохранение доп. данных в макета через V8Unpack — то чего так не хватает
есть ли очистка от ненужных данных?
Да, о полном удалении данных чёт не подумал… В принципе можно сохранить в обработку значение «Неопределено», но это все равно будет значение, и все равно будет занимать место, хотя и совсем не много. Думаю добавлю такой метод, и пожалуй добавлю сжатие данных deflate’ом.
(27) vec435, добавил очистку и сжатие…
Макеты (файлы справки к примеру, насколько я понимаю) объектов хранятся в виде сжатых данных по алгоритму Deflate в виде Base64 строки. Так что теоретически засунуть в обработку возможно все 🙂
И вполне возможно создавать свои объекты (макеты), главное их формат сохранить
Как истинный перфекционист — заметил опечатки в описании:
1) «имеет всего 2 метода» — так 3 метода же! 🙂
2) «степень сжатия данных ввиде числа» — нужен пробел для «в_виде»;
3) в описании 3-го метода — «прЕводит»;
4) в описании свойства «Версия» — «данноЙ свойство»;
5) «можно использовать и с внешними отчета» — упущено «…МИ»;
6) «лишь демонстрирую(?) пример работы» — пропущено «Т».