Со времен вот этого поста http://www.excelworld.ru/forum/3-12909-1, подход к данному вопросу поменялся кардинальным образом. Решения, как бы поработать с массивом любого типа данных в классе и не создавать отдельные свойства-методы для каждого типа данных, я так и не нашел, но "нормальные герои, всегда идут в обход" (с) Правда, апофеозом там, помнится, было "зачем вы потащили меня в этот чертов обход?!", ну да не суть.... Класс dwArray1D - попытка решения данного вопроса с помощью определения типа данных массива, переданного по ссылке через переменную Variant, и дальнейшая работа с массивом "напрямую" в памяти. В общем, не дают мне покоя лавры класса Array в dotNet, и ему подобных. Хотя, даже не могу сказать, чего я к этим злосчастным массивам прицепился.
Начнем с самого главного. С чужих авторских прав и невольных соучастников этого, с позволения сказать, проекта
1. Класс работает только с одномерными массивами. 2. Работа с массивами пользовательских типов данных (структур) и строк фиксированной длинны (а'ля String*10) не поддерживается. Не поддерживается работа с массивами, имеющими "отрицательный Lbound". 3. Массив должен "передаваться" в класс "напрямую" (не должен находиться в Variant-переменной) 4. Динамический массив должен содержать хотя бы один элемент (тут я просто недодумал, на начальном этапе) 5. Перебор элементов в цикле For Each не поддерживается 6. Некоторые методы из "удобняшек" жрут память равную, в лучшем случае, занятой самим массивом, т.к. создают промежуточный массив значений. 7. Производительность . Конечно же, за универсальность и удобняшки, пришлось ею расплатиться. Где-то в большей степени, где-то в меньшей, но пришлось. Производительность операций с массивами типа Variant ниже, чем с другими типами данных (т.к. размер эл. больше)
Кроме пункта номер 2 - все решаемо. Конечно, при условии, востребованности этого решения вообще)
Продолжим нейтральным
Разработка имеет статус "альфы". Т.е. еще "сырая" и плохо протестированная. Могут быть падения Excel или еще что-то в этом духе. Буду рад комментариям с описанием ошибок. Документацию напишу попозже. Сейчас имеются модули с примерами почти для всего функционала + в самом классе есть описание всех методов с их параметрами, возвращаемыми значениями и прочим.
И закончим по-делу
Массив любого допустимого типа заворачивается в этот фантик достаточно просто:
[vba]
Код
'Создаем массив(ы) 'Dim ms(10) as String 'Dim ms(5 to 20) as Date 'Dim ms() as Variant
Dim ms() as Long Redim ms(0)
'Объявляем обертку Dim dwA as New dwArray1D
dwA.Array_Set ms
[/vba]
И вот... словно куклой, в час любой, теперь он может управлять тобой.
А дальше, можно использовать весь этот заявленный "массив возможностей", было бы желание и ежли, конечно, нет там багов или хотя бы есть четное их число
Общее для большинства методов: Методы работы с массивами, начинающиеся на "Arr" - как правило имеют необязательные параметры, позволяющие выбрать элементы "с... по..." массива, для применения данного метода. Так же, такие методы, которые возвращают в результате массив (конвертация, фильтры) в случае отсутствия данных, возвращают пустой массив с отрицательным Ubound (= -1)
Основные свойства и методы
[vba]
Код
Array_Set ' "подключить" массив к классу. (массивы можно, без проблем, менять в процессе работы, используя один экземпляр dwArray1D для всех). Так же, можно параллельно работать с массивом и обычными способами. Когда снова обратитесь к классу, эти изменения будут учтены). Element 'Свойство (аналог Item в Collection). Получить\задать значение элемента по его индексу ArrayLbound 'Свойство. LBound массива ArrayUbound 'Свойство. UBound массива ArrayCount 'Свойство. Кол-во элементов массива ArrayReDim 'Изменение размера массива (ReDim. Один из параметров метода отвечает за "Preserve", который по-умолчанию True) ArrayErase 'Erase
[/vba]
Расширенные методы работы с элементами массива, выполненные по заказу Британских ученых, при поддержке НИИ "Благородных девиц", и вряд ли так уж нужные в обычной работе по автоматизации
Вставка\удаление\перемещение\обмен местами элементов массива
-FL - FIFO\LIFO . Попытка заюзать массивы еще и в качестве стека\очереди Вставка элементов в начало\в конец массива, получение их значений с возможностью удаления после этого
Конвертация
ToString - в строку (с указанным разделителем) To<Byte,Boolean,Integer,Long,Single,Date,String,Variant,Object>Array - в массив выбранного типа данных
Полезняшки
Реверс, сортировка, запись на рабочий лист, удаление пустых\повторяющихся элементов, сохранение данных в файл и считывания из него, получение хеша элемента (md5,sha1), добавления элемента (по аналогии с Collection.Add)
-Search. Поиск Поиск по образцу в т.ч. во "вложенных" одномерных массивах\объектах типа Collection, бинарный поиск, поиск по кол-ву значений элементов
-Filter. Фильтры Значений (по полному\частичном совпадению, шаблонам LIKE, регулярным выражениям), по нечеткому сравнению строк, цифр\дат (больше-меньше) и по кол-ву повторов значений элементов в массиве (больше\меньше указанного)
Операции над "специфическими" типам данных\содержимым массивов
-BT - Bitwise Operation . Битовые операции над элементами типа Byte,Integer,Long (В тех случаях, когда можно использовать "маску" для метода, есть возможно задать ее в двоичном виде. По аналогии с &H - задается &B. К примеру &B1001) Установка\получение\инверсия значений битов (в т.ч. по маскам), сдвиг битов, получение значения элемента в двоичном представлении
-TX -Тext. "Текстовые" операции над элементами массива типа String, Variant Дополнение строк символом до указанной длины, получение указанной части строки, замена символов по списку (аналог функции Tranlsate в Oracle), определение "состава символов" строки (по их asc-коду)
-FS - Файловая система. Операции над элементами массива типа String, Variant, содержащими пути к дискам\файлам\папкам (идея такая - массив содержит пути к папкам-файлам, а методы по ним работают) Получение путей подпапок\файлов из указанной папки, получение хеша md5\sha1 файлов, чтение данных из файлов, получение разных частей из полного пути, получение размеров папок\файлов
На Office x64 проверил, вроде работает
Эпилог Примеры использования и тесты - в отдельных модулях, в файле. Для интересующихся - код прокомментирован, правда, в меру моего понимания и сомнительного чувства юмора. Ссылки на источники информации, которыми я пользовался, в комментариях есть.
В приложении: 1. архив с классом файлом dwArray1D.cls (к сожалению, превышает 100КБ в xlsm) 2. архив "Example" с файлом xlsm (модули с примерами) и папка для тестирования работы с файловой системой. Для работы, dwArray1D.cls необходимо импортировать в данный файл
Версия 2 - частично добавлена документация в файл "Example". Файлы обновлены
И снова здравствуйте)
Со времен вот этого поста http://www.excelworld.ru/forum/3-12909-1, подход к данному вопросу поменялся кардинальным образом. Решения, как бы поработать с массивом любого типа данных в классе и не создавать отдельные свойства-методы для каждого типа данных, я так и не нашел, но "нормальные герои, всегда идут в обход" (с) Правда, апофеозом там, помнится, было "зачем вы потащили меня в этот чертов обход?!", ну да не суть.... Класс dwArray1D - попытка решения данного вопроса с помощью определения типа данных массива, переданного по ссылке через переменную Variant, и дальнейшая работа с массивом "напрямую" в памяти. В общем, не дают мне покоя лавры класса Array в dotNet, и ему подобных. Хотя, даже не могу сказать, чего я к этим злосчастным массивам прицепился.
Начнем с самого главного. С чужих авторских прав и невольных соучастников этого, с позволения сказать, проекта
1. Класс работает только с одномерными массивами. 2. Работа с массивами пользовательских типов данных (структур) и строк фиксированной длинны (а'ля String*10) не поддерживается. Не поддерживается работа с массивами, имеющими "отрицательный Lbound". 3. Массив должен "передаваться" в класс "напрямую" (не должен находиться в Variant-переменной) 4. Динамический массив должен содержать хотя бы один элемент (тут я просто недодумал, на начальном этапе) 5. Перебор элементов в цикле For Each не поддерживается 6. Некоторые методы из "удобняшек" жрут память равную, в лучшем случае, занятой самим массивом, т.к. создают промежуточный массив значений. 7. Производительность . Конечно же, за универсальность и удобняшки, пришлось ею расплатиться. Где-то в большей степени, где-то в меньшей, но пришлось. Производительность операций с массивами типа Variant ниже, чем с другими типами данных (т.к. размер эл. больше)
Кроме пункта номер 2 - все решаемо. Конечно, при условии, востребованности этого решения вообще)
Продолжим нейтральным
Разработка имеет статус "альфы". Т.е. еще "сырая" и плохо протестированная. Могут быть падения Excel или еще что-то в этом духе. Буду рад комментариям с описанием ошибок. Документацию напишу попозже. Сейчас имеются модули с примерами почти для всего функционала + в самом классе есть описание всех методов с их параметрами, возвращаемыми значениями и прочим.
И закончим по-делу
Массив любого допустимого типа заворачивается в этот фантик достаточно просто:
[vba]
Код
'Создаем массив(ы) 'Dim ms(10) as String 'Dim ms(5 to 20) as Date 'Dim ms() as Variant
Dim ms() as Long Redim ms(0)
'Объявляем обертку Dim dwA as New dwArray1D
dwA.Array_Set ms
[/vba]
И вот... словно куклой, в час любой, теперь он может управлять тобой.
А дальше, можно использовать весь этот заявленный "массив возможностей", было бы желание и ежли, конечно, нет там багов или хотя бы есть четное их число
Общее для большинства методов: Методы работы с массивами, начинающиеся на "Arr" - как правило имеют необязательные параметры, позволяющие выбрать элементы "с... по..." массива, для применения данного метода. Так же, такие методы, которые возвращают в результате массив (конвертация, фильтры) в случае отсутствия данных, возвращают пустой массив с отрицательным Ubound (= -1)
Основные свойства и методы
[vba]
Код
Array_Set ' "подключить" массив к классу. (массивы можно, без проблем, менять в процессе работы, используя один экземпляр dwArray1D для всех). Так же, можно параллельно работать с массивом и обычными способами. Когда снова обратитесь к классу, эти изменения будут учтены). Element 'Свойство (аналог Item в Collection). Получить\задать значение элемента по его индексу ArrayLbound 'Свойство. LBound массива ArrayUbound 'Свойство. UBound массива ArrayCount 'Свойство. Кол-во элементов массива ArrayReDim 'Изменение размера массива (ReDim. Один из параметров метода отвечает за "Preserve", который по-умолчанию True) ArrayErase 'Erase
[/vba]
Расширенные методы работы с элементами массива, выполненные по заказу Британских ученых, при поддержке НИИ "Благородных девиц", и вряд ли так уж нужные в обычной работе по автоматизации
Вставка\удаление\перемещение\обмен местами элементов массива
-FL - FIFO\LIFO . Попытка заюзать массивы еще и в качестве стека\очереди Вставка элементов в начало\в конец массива, получение их значений с возможностью удаления после этого
Конвертация
ToString - в строку (с указанным разделителем) To<Byte,Boolean,Integer,Long,Single,Date,String,Variant,Object>Array - в массив выбранного типа данных
Полезняшки
Реверс, сортировка, запись на рабочий лист, удаление пустых\повторяющихся элементов, сохранение данных в файл и считывания из него, получение хеша элемента (md5,sha1), добавления элемента (по аналогии с Collection.Add)
-Search. Поиск Поиск по образцу в т.ч. во "вложенных" одномерных массивах\объектах типа Collection, бинарный поиск, поиск по кол-ву значений элементов
-Filter. Фильтры Значений (по полному\частичном совпадению, шаблонам LIKE, регулярным выражениям), по нечеткому сравнению строк, цифр\дат (больше-меньше) и по кол-ву повторов значений элементов в массиве (больше\меньше указанного)
Операции над "специфическими" типам данных\содержимым массивов
-BT - Bitwise Operation . Битовые операции над элементами типа Byte,Integer,Long (В тех случаях, когда можно использовать "маску" для метода, есть возможно задать ее в двоичном виде. По аналогии с &H - задается &B. К примеру &B1001) Установка\получение\инверсия значений битов (в т.ч. по маскам), сдвиг битов, получение значения элемента в двоичном представлении
-TX -Тext. "Текстовые" операции над элементами массива типа String, Variant Дополнение строк символом до указанной длины, получение указанной части строки, замена символов по списку (аналог функции Tranlsate в Oracle), определение "состава символов" строки (по их asc-коду)
-FS - Файловая система. Операции над элементами массива типа String, Variant, содержащими пути к дискам\файлам\папкам (идея такая - массив содержит пути к папкам-файлам, а методы по ним работают) Получение путей подпапок\файлов из указанной папки, получение хеша md5\sha1 файлов, чтение данных из файлов, получение разных частей из полного пути, получение размеров папок\файлов
На Office x64 проверил, вроде работает
Эпилог Примеры использования и тесты - в отдельных модулях, в файле. Для интересующихся - код прокомментирован, правда, в меру моего понимания и сомнительного чувства юмора. Ссылки на источники информации, которыми я пользовался, в комментариях есть.
В приложении: 1. архив с классом файлом dwArray1D.cls (к сожалению, превышает 100КБ в xlsm) 2. архив "Example" с файлом xlsm (модули с примерами) и папка для тестирования работы с файловой системой. Для работы, dwArray1D.cls необходимо импортировать в данный файл
Версия 2 - частично добавлена документация в файл "Example". Файлы обновленыDark_wave
MSOffice 2007, 32 bit - тестовые программы отработали без ругательств. Для себя (на данный момент) необходимости в столь эпохальном (7 тысяч строк) произведении не вижу, но некоторые идеи по мере необходимости извлекать буду. И ещё я не могу понять смысла оформления кода в класс. Поскольку нет необходимости во множестве объектов, не лучше ли применять просто как стандартный модуль?
MSOffice 2007, 32 bit - тестовые программы отработали без ругательств. Для себя (на данный момент) необходимости в столь эпохальном (7 тысяч строк) произведении не вижу, но некоторые идеи по мере необходимости извлекать буду. И ещё я не могу понять смысла оформления кода в класс. Поскольку нет необходимости во множестве объектов, не лучше ли применять просто как стандартный модуль?Skif-F
Насчет эпохальности - есть такая беда) С одной стороны измучен С++ , с другой - изнежен Net FrameWork-ом... К хорошему привыкаешь быстро, вот и привык, что в большинстве случаев, есть какое-то готовое решение в библиотеке. Один метод вызываешь и результат уже в кармане. А в VBA, как с серьезной задачей столкнулся, так многое самому писать. Вот и решил, на будущее.. Хотя, конечно, это уже "Остапа понесло", минимум половина функционала если и понадобится, то один раз в жизни и то можно было бы обойтись стандартными средствами)
По классу - не знаю, видать привык, после того как на ООП перебрался, что класс - это "некое законченное решение", которое инкапсулирует... и все такое прочее) И что в таком виде удобнее всего передавать "решения" между разработчиками. А так, наверное, можно было бы, действительно, модуль использовать.
Skif-F, Спасибо)
Насчет эпохальности - есть такая беда) С одной стороны измучен С++ , с другой - изнежен Net FrameWork-ом... К хорошему привыкаешь быстро, вот и привык, что в большинстве случаев, есть какое-то готовое решение в библиотеке. Один метод вызываешь и результат уже в кармане. А в VBA, как с серьезной задачей столкнулся, так многое самому писать. Вот и решил, на будущее.. Хотя, конечно, это уже "Остапа понесло", минимум половина функционала если и понадобится, то один раз в жизни и то можно было бы обойтись стандартными средствами)
По классу - не знаю, видать привык, после того как на ООП перебрался, что класс - это "некое законченное решение", которое инкапсулирует... и все такое прочее) И что в таком виде удобнее всего передавать "решения" между разработчиками. А так, наверное, можно было бы, действительно, модуль использовать.Dark_wave
На самом деле самого дела-то и нет. А наоборот, получим оборот на, и таким образом перевернем образ