Страницы: 1
RSS
ООП в VBA
 
Хотел бы услышать ваше мнение насчет применения ООП в VBA.  
 
В связи с частым использованием многих функций, хотел собрать их в один объект, дабы было удобно использовать, пример:  
 
Dim x As New nerv ' имя класса - мой ник : )  
Dim col As New Collection  
 
' пример использования - формирование строки из коллекции  
MsgBox nerv.Collection.toString(col)  
 
' формирование массива из коллекции  
arr = nerv.Collection.toArray(col)  
 
 
Я уж молчу про то, что нельзя сделать просто и очевидно - добавить свои методы/свойства к предопределенным объектам:  
MsgBox col.toString()  
arr = col.toArray()  
 
но, вам не кажется, что добавлять модуль класса, просто для того, чтобы там написать Public Collection As New Collection_ - лишним?  
 
 
Это только верхушка айсберга: почему приватные поля класса видны при создании объекта в отладчике? Они ж приватные! При обращении к ним возникает ошибка. Дядя, Бил, ты перемудрил.
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
> пример:  
 
По-моему, синтаксис должен быть нескольлько другой:  
 
Dim x As New nerv ' имя класса - мой ник : )  
Dim col As New Collection  
 
' пример использования - формирование строки из коллекции  
MsgBox x.CollectionToString(col) 'CollectionToString - название метода  
 
' формирование массива из коллекции  
arr = x.CollectionToArray(col) 'CollectionToArray  - название метода  
 
> но, вам не кажется, что добавлять модуль класса, просто для того, чтобы там написать Public Collection As New Collection_ - лишним?  
 
А зачем это делать? Коллекция объявлена и заполняется в обычном модуле, потом передается как аргумент методу класса nerv, который ее обрабатывает.  
 
> Я уж молчу про то, что нельзя сделать просто и очевидно - добавить свои методы/свойства к предопределенным объектам  
 
В VBA есть механизм наследования - с помощью оператора Implements. Я никогда его не использовал, но, наверно, можно создать класс NervCollection, который унаследует свойства и методы коллекции и добавит свои. Попробуй :)
 
> почему приватные поля класса видны при создании объекта в отладчике?  
 
Что ты имеешь в виду? Вот я написал в модуле класса Class1  
 
Public x  
Private y  
 
Public Sub pubs()  
End Sub  
 
Private Sub pris()  
End Sub  
 
Теперь пишу в процедуре обычного модуля:  
 
Dim a As Class1  
a.  
 
После ввода точки выпадает только "x" и "pubs".
 
ура, Казанский ответил! : )  
 
>По-моему, синтаксис должен быть нескольлько другой:  
>MsgBox x.CollectionToString(col) 'CollectionToString - название метода  
Логику понял, но это не совсем то, что я хотел, т.к. кроме коллекции, планирую еще другие доп. функции насувать ) Т.е. мой ник как namespace (пространство имен), которое "подразделяется" на подструктуры, а-ля дерево каталогов.  
 
>В VBA есть механизм наследования - с помощью оператора Implements. Я никогда его не использовал, но, наверно, можно создать класс NervCollection, который унаследует свойства и методы коллекции и добавит свои. Попробуй :)  
можно пример?  
 
>А зачем это делать? Коллекция объявлена и заполняется в обычном модуле, потом передается как аргумент методу класса nerv, который ее обрабатывает.  
если честна, хотел бы этого избежать, т.е. вызывать методы напрямую - коллекция.метод, т.е. способ collection.toString() - предпочтительный  
 
>После ввода точки выпадает только "x" и "pubs".  
в окне локалс
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
или я что-то не понял, или от "стандартного" объекта Collection  Implements не наследует...
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
пока такая штука получается. Хочу припаять к ней тему - эмуляцией двумерного массива отсюда http://www.planetaexcel.ru/forum.php?thread_id=31716&page_forum=27&allnum_forum=397
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
Представляю вашему вниманию расширенный класс Collection.  
На данный момент он включает:  
 
Add - стандартный нативный метод  
AddUnique - новый метод  
Count - стандартное нативное свойство  
Item - расширенный стандартный метод  
Remove - расширенный стандартный метод  
RemoveAll - новый метод  
Sort - новый метод  
ToArray - новый метод  
ToString - новый метод  
 
Более подробно ниже и в файле. Проверить в файле.  
 
'===================================  
' Данная коллекция (Collection_) включает как стандартные (расширенные) _  
 методы и свойства, так и добавленные (надеюсь, полезные).  
'===================================  
   
' Расширенные св-ва/методы:  
' 1. Remove - возвращает удаленное значение _  
 (в стандартной коллекции он просто удаление). _  
 Пример:  
   
 col.Add True  
 x = col.Remove(1)     ' <--  
 Stop  
 
'-----------------------------------  
 
' 2. Item - позволяет не только читать, но и _  
 записывать значения (в стандартной реализации _  
 только чтение). Пример:  
   
' добавляем значения, так же как и в нативную коллекцию  
 col.Add 1  
 col.Add 2  
   
' меняем его  
 col.Item(2) = col.Item(2) + 5     ' <--  
 Stop  
 
'===================================  
 
' Добавленные методы:  
' 1. RemoveAll - удаляет все элементы из коллекци _  
 (аналогичен одноименному методу словаря). Пример:  
   
 col.RemoveAll     ' <--  
 MsgBox col.Count  
 Stop  
   
'-----------------------------------  
   
' 2. ToString - формирует строку из элементов коллекции. _  
 Пример:  
 
' добавляем значения  
 col.Add 1  
 col.Add 2  
 col.Add 3  
 
line = col.ToString     ' <--  
Stop  
 
' разделитель можно задавать (по умолчанию пробел)  
line = col.ToString(",")    ' <--  
Stop  
 
'-----------------------------------  
 
' 3. ToArray - формирует массив из элементов коллекции. _  
 Пример:  
   
arr = col.ToArray()     ' <--  
Stop  
 
' размерность массива можно задавать: одномерный/двумерный _  
 (по умолчанию двумерный)  
   
arr = col.ToArray(1)    ' <--  
Stop  
col.RemoveAll  
 
'-----------------------------------  
 
' 4. AddUnique - добавляет в коллекцию уникальные значения. _  
 Пример:  
   
 col.AddUnique (ActiveSheet.UsedRange.Cells)   ' <--  
 Stop  
 col.RemoveAll  
   
 ' можно добавлять прямо из массива  
 col.AddUnique (Array(1, 2, 3, 4, 5, 5, 4, 3, 2, 1)) ' <--  
 Stop  
 col.RemoveAll  
   
'-----------------------------------  
 
' 5. Sort - сортирует элементы коллекции. Пример:  
 
 col.AddUnique (ActiveSheet.UsedRange.Cells)   ' добавили уникальные  
 col.Sort  ' <-- отсортировали по возростанию  
 Stop  
   
 ' порядок сортировки пожно менять  
 col.Sort (xlDescending) ' <-- xlDescending = 2  
 Stop  
 
 
Вопросы, замечания, пожелания?
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
Отлично, Александр!  
 
Несколько замечаний:  
1. Следует сделать св-во Item свойством по умолчанию, чтобы можно было его опускать: col(1) вместо col.Item(1).  
Как это сделать - написано у Пирсона http://www.cpearson.com/excel/DefaultMember.aspx  
Я использовал этот прием тут: http://www.cyberforum.ru/vba/thread581574.html#post3063638  
 
2. Теперь нельзя использовать метод Remove как стандартный - обязательно надо присваивать его значение какой-то переменной. ИМХО это неудобно.  
Можно либо оставить прежный метод как стандартный и создать новый метод RemoveA, который возвращает удаленное значение, либо переименовать метод в функцию  
Public Function Remove(ByRef Index As Variant) As Variant  
Почему-то функцию можно использовать как процедуру, не используя возвращаемое значение, а свойство - нельзя.  
 
3. Интересно было бы иметь сортировку и по ключам, и по значениям.
 
Казанский, спасибо за замечания!  
 
1. Сделал.  
2. Поправил. Можно и так и так.  
3. Как? В ключах вся загвоздка. Ключ можно добавить, но не прочитать. Или я ошибаюсь?  
 
Сильная штука получилась : ) Вот, думаю, чтобы еще добавить и надо ли оно?  
Хочется что-то типа  
эмуляцией двумерного массива отсюда http://www.planetaexcel.ru/forum.php?thread_id=31716&page_forum=27&allnum_forum=397
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
{quote}{login=nerv}{date=22.07.2012 04:50}{thema=}{post}Сильная штука получилась : ) {/post}{/quote}  
не то слово.  
респект и уважуха.
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
> 3. Как? В ключах вся загвоздка. Ключ можно добавить, но не прочитать.  
Да. Есть вариант всегда добавлять в коллекцию пару значений: this.Add array(item, key), key  
Или параллельно вести еще одну коллекцию, у которой item равен ключу основной коллекции.  
 
> что бы еще добавить?  
Хорошо бы иметь возможность неявно добавлять несуществующий элемент, как у словаря. Например, команда dic(q)=dic(q)+1 увеличит элемент с ключом q на 1, а если такого элемента нет, то добавит элемент с ключом q и в результате этот элемент будет содержать 1. Без возникновения ошибки.  
Тогда, наверно, придется добавить и проверку существования элемента Exists.  
 
Все эти навороты, однако, сводят на нет основную прелесть коллекции - высокую скорость работы.
 
добавил Exists. Думаю, достаточно.  
 
ikki, спасибо  
 
>Все эти навороты, однако, сводят на нет основную прелесть коллекции - высокую скорость работы.  
да не. Нативные методы написаны максимально просто/быстро.  
Или ты думаешь, от того, что ты напишешь (к примеру) отдельную функцию/процедуру для преобразования коллекции в строку, она будет работать быстрее? )  
 
 
Итого:  
Add - стандартный нативный метод  
AddUnique - новый метод  
Count - стандартное нативное свойство  
Exists - новый метод  
Item - расширенный стандартный метод  
Remove - расширенный стандартный метод  
RemoveAll - новый метод  
Sort - новый метод  
ToArray - новый метод  
ToString - новый метод  
 
В архиве xls, в котором можно проверить как оно работает, а также cls, который можно подключать сразу к проекту.  
 
p.s.: всем спасибо : )
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
> Нативные методы написаны максимально просто/быстро.  
Или ты думаешь, от того, что ты напишешь (к примеру) отдельную функцию/процедуру для преобразования коллекции в строку, она будет работать быстрее?  
 
Время тратится на передачу параметров через методы объекта. То есть с коллекцией в обычном модуле работать быстрее, чем с коллекцией в классе.  
Как-то я сравнивал время доступа к переменным в классе и к локальным переменным.  
Интересно, что тема называлась так же, как эта :))  
 
http://www.cyberforum.ru/vba/thread585274.html#post3077383
 
>Интересно, что тема называлась так же, как эта :))  
^_^  
 
>Можно ли использовать методы класса внутри его самого  
сразу ответ - можно )  
 
>Время тратится на передачу параметров через методы объекта.  
Даже не собираюсь спорить. Обертки кушают, но немного.  
Ситуация двоякая: с одной стороны удобство использования, с другой скорость выполнения.  
Я бы с удовольствием унаследовал почти все родные методы, но VBA отказал. Поэтому акробатика )  
 
Здесь Range(...) тоже время тратиться, но простота использования - ключевой момент.
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
обсуждение перенес сюда  
http://www.excelworld.ru/forum/3-2045
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
http://www.excelworld.ru/publ/vba/class_module/42  
От тут кратко написал о своем отношении к ООП в vba  
Основная проблема скорость конечно
 
ratboy, спасибо, уже читал : ) 5-ку поставил )  
 
Как это ни печально, ловлю себя на мысли, что пытаюсь имитировать поведение js в VBA )))  
 
 
88799
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
Страницы: 1
Читают тему
Наверх