Страницы: Пред. 1 2
RSS
Хранение файлов и файловый менеджер в файле(листе) Excel, Бинарное хранение данных в CustomProperty листа (Open FileName As Binary и Get, Put через байт-массив)
 
Виктор, хорошая мысль, немного протестирую еще (только в этой версии удалось найти из-за чего висел дескриптор, открытый процессом Excel и папку удалить было нельзя в этом же процессе) и зрелое решение можно и в копилочку! Кто пользуется - пишите сюда выявленные ошибки, баги, предложения по оптимизации, дополнения на ваш взгляд необходимые.
«Бритва Оккама» или «Принцип Калашникова»?
 
Андрей (Андрей VG) привет! нашел одну особенность в CustomProperties листа.
Он теряет нечетный байт! :) видимо данные хранятся в виде Unicode-строки, а Unicode-строка двухбайтовая! Итого режет один байт!
Вот пример:
Код
Sub CheckCustomProperties()
 Dim wksSheet1 As Worksheet, byteArrIn(2) As Byte, byteArrOut() As Byte
 Set wksSheet1 = Application.ActiveSheet
 Debug.Print "Элементов массива IN - " & UBound(byteArrIn)+1
 wksSheet1.CustomProperties.Add name:="Test", Value:=byteArrIn
 With wksSheet1.CustomProperties.Item(1): byteArrOut = .Value: .Delete: End With
 Debug.Print "Элементов массива OUT - " & UBound(byteArrOut)+1
End Sub

Это нехорошо для фалов, сейчас подумаю над заглушкой. О как)
Изменено: bedvit - 06.06.2018 17:17:29
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
bedvit написал:
Это нехорошо для фалов, сейчас подумаю над заглушкой. О как)
Сам пока не нарывался, видимо везло. Можно в качестве заглушки использовать преобразование байт-массива в base64, а потом обратно - это будет ближе к алгоритму Игоря.
 
Здравствуйте, коллеги! Можно в отдельном дополнительном ключе в CustomProperties хранить также мета-информацию о файле: длину, дату и время последнего изменения и пр.
Владимир
 
sokol92, в этом свойстве можно хранить байт-массив (или другую переменныю) и имя. В имя пихать пока не хочется инфу. А что за дополнительные ключи? Имеется ввиду выделить отдельное элемент, где хранить инфо о других элементах? Идея интересная,  пока не знаю, насколько это удобно и упрощает ли жизнь.
Изменено: bedvit - 06.06.2018 17:51:20
«Бритва Оккама» или «Принцип Калашникова»?
 
В основном ключе (имя файла) храним, как и сейчас, байт-массив (с дополненным до четности байтом, если необходимо). В дополнительном ключе (получается из основного добавлением какого-нибудь суффикса, например, знака табуляции) в значении храним дополнительную информацию о файле: длину (исходного файла, если он при помещении в хранилище архивирован), дату и время последнего изменения (пригодится для будущих функций), признак четности длины байт-массива и пр. Формат значения дополнительного ключа - на усмотрение автора. Я бы его сделал в ключевом формате для последующих расширений.
Владимир
 
Немного подумав над этой интересной задачей - сделал заглушку в самом байтовом массиве, дополнительных элементов не вводил, имена элементов не менял. Просто и эффективно. Ставим заглушку, удаляем :)
Добавил возможность указать папку, и заливать все файлы, которые есть в папке, так же как и распаковывать.
Потестировал - все отрабатывает.
Результаты:
Залить (файлов - 432 шт), выгрузить (файлов - 432 шт), удалить (файлов - 432 шт)
Размер файлов - 1 334 МБ (1,33ГБ)
Время выполнения всех трех операций в сумме - 25 сек.
По-моему неплохо.
Книга при этом весит 1,2 ГБ в формате .xlsb

Файл заменил в сообщении о 5й версии.
Буду оформлять в копилку.
Изменено: bedvit - 07.06.2018 19:44:50
«Бритва Оккама» или «Принцип Калашникова»?
 
Откопал еще одну занимательную вещь. Утечка памяти в VBA! На самом деле утечка в методе "CustomProperties.Add" (скорее всего написан он на С (Си), с ручным управлением памяти и где-то не допилили)
Простой пример, скармливаем методу .Add - строку размером 200МБ, сжирает он 400МБ оперативки (видимо есть промежуточный кусок памяти для перераспределения, который не очищается - размером как входящие данные)  и через .Delete - освобождает 200МБ. т.е. на 200МБ утекает памяти при каждой итерации!
Пример на VBA (открываем обычный диспетчер - смотрим процесс Excel - память):
Код
Sub memory_leak()
Application.ActiveSheet.CustomProperties.Add name:="Test", Value:=String$(100000000, "1") 'по 2 байта на символ это примерно 200 МБ, а сжирает 400 МБ
Application.ActiveSheet.CustomProperties.Item(1).Delete 'возвращает 200 МБ
End Sub

У всех .Add жрет в 2 раза больше?
Система: Excel2016x64 на win7x64
«Бритва Оккама» или «Принцип Калашникова»?
 
Проверил Win XP + Excel 2007 и Win10 + Excel2016(64). Эффект тот же.
Владимир
 
Владимир, благодарю за тест. Здесь тоже протестировали, утечка памяти есть, Майкрософт не допилили, разрыли их косячок. На "продукте" это сказывается в случаях пезаливки большого количества одних и тех же данных в одной сессии Excel. Что я предполагаю - редкость, т.к. заливают обычно один раз (к примеру библиотеки, программы, архивы, рисунки, формы и прочие файлы и необходимые элементы), а далее выгрузка, разархивирование, запуск/выполнение, удаление отрабатываются множество раз (и здесь мягкотелые похоже все пропилили нормально).
«Бритва Оккама» или «Принцип Калашникова»?
 
Виталий, я тоже не думаю, что в практическом плане указанная учетка памяти является проблемой.
Владимир
 
Цитата
vikttur написал:
А если создать дубль темы (такое "нарушение" только на пользу), описать и приложить файл, то можно положить и в Копику форума.
Виктор, создал дубль темы с описанием для копилки.
«Бритва Оккама» или «Принцип Калашникова»?
Страницы: Пред. 1 2
Наверх