Для показа пары трюков мне нужны будут три модуля: модуль класса Student, модуль класса Students и стандартный модуль CollectionTest.
Класс Student:
Класс Students:
Стандартный модуль CollectionTest:
Trick #1. Свойство по умолчанию.
Все вы знаете, что в VBA есть объекты со свойствами по умолчанию (Default). Например, свойство Item у Worksheets является свойством по умолчанию, что означает, что мы может вместо Worksheets.Item(1) написать просто Worksheets(1).
При выборке студента из коллекции Students было бы очень удобно писать так (продолжая код в CollectionTest):
вместо
Но так не получится, IntelliSense нам ничего не показывает:
А теперь вот что необходимо для создания свойства по умолчанию:
1. В Project Explorer нажимаем правую кнопку мыши на модуле Students и выбираем "Remove Students".
2. В появившемся окне на вопрос "Do you want to export Students before removing it?" отвечаем "Yes" и сохраняем его.
3. Открываем сохранённый модуль блокнотом (или другим текстовым редактором). Наше свойство Item выглядит так:
Теперь между Public Property Get и Set Item вставляем строку Attribute Item.VB_UserMemId = 0. В итоге должно получиться:
4. Сохраняем изменения.
5. Импортируем изменённый модуль обратно в VBE либо через "Правая кнопка мыши -> Import File", либо через drag'n'drop.
Теперь можно писать так:
Вот что теперь показывает IntelliSense:
А вот что показывает Object Browser:
Trick #2. Настоящая коллекция
На настоящий момент коллекция Students - не настоящая коллекция. Нельзя создать итерацию всех студентов в коллекции:
Чтобы данный код заработал, необходимо изменить класс Students. Выполняем те же действия, что и в Trick #1, только теперь необходимо в класс добавить следующую функцию (colStudents - коллекция; соответственно, необходимо вставить свою переменную):
Для теста снова запустите процедуру IterateCollection.
Класс Student:
Код |
---|
Private m_Id As Long Property Get Id() As Long Id = m_Id End Property Property Let Id(studId As Long) m_Id = studId End Property |
Класс Students:
Код |
---|
Private colStudents As Collection Private Sub Class_Initialize() Set colStudents = New Collection End Sub ' Добавляет студента в коллекцию Public Function Add(stud As Student) colStudents.Add stud, CStr(stud.Id) End Function ' Возвращает количество студентов в коллекции Public Property Get Count() As Long Count = colStudents.Count End Property ' Возвращает коллекцию студентов Public Property Get Items() As Collection Set Items = colStudents End Property ' Возвращает студента из коллекции по его ключу ' или порядковому номеру в коллекции Public Property Get Item(vItem As Variant) As Student Set Item = colStudents(vItem) End Property ' Удаляет студента из коллекции Public Sub Remove(vItem As Variant) colStudents.Remove vItem End Sub |
Стандартный модуль CollectionTest:
Код |
---|
Sub WorkWithDefaultProperty() Dim st As Student Dim sts As Students Set sts = New Students 'Создаём новую коллекцию студентов Set st = New Student 'Создаём студента st.Id = 55 sts.Add st 'Добавляем студента в коллекцию End Sub |
Trick #1. Свойство по умолчанию.
Все вы знаете, что в VBA есть объекты со свойствами по умолчанию (Default). Например, свойство Item у Worksheets является свойством по умолчанию, что означает, что мы может вместо Worksheets.Item(1) написать просто Worksheets(1).
При выборке студента из коллекции Students было бы очень удобно писать так (продолжая код в CollectionTest):
Код |
---|
MsgBox sts(1).Id |
вместо
Код |
---|
MsgBox sts.Item(1).Id |
Но так не получится, IntelliSense нам ничего не показывает:
А теперь вот что необходимо для создания свойства по умолчанию:
1. В Project Explorer нажимаем правую кнопку мыши на модуле Students и выбираем "Remove Students".
2. В появившемся окне на вопрос "Do you want to export Students before removing it?" отвечаем "Yes" и сохраняем его.
3. Открываем сохранённый модуль блокнотом (или другим текстовым редактором). Наше свойство Item выглядит так:
Код |
---|
Public Property Get Item(vItem As Variant) As Student Set Item = colStudents(vItem)End Property |
Теперь между Public Property Get и Set Item вставляем строку Attribute Item.VB_UserMemId = 0. В итоге должно получиться:
Код |
---|
Public Property Get Item(vItem As Variant) As Student Attribute Item.VB_UserMemId = 0 Set Item = colStudents(vItem) End Property |
4. Сохраняем изменения.
5. Импортируем изменённый модуль обратно в VBE либо через "Правая кнопка мыши -> Import File", либо через drag'n'drop.
Теперь можно писать так:
Код |
---|
MsgBox sts(1).Id |
Вот что теперь показывает IntelliSense:
А вот что показывает Object Browser:
Trick #2. Настоящая коллекция
На настоящий момент коллекция Students - не настоящая коллекция. Нельзя создать итерацию всех студентов в коллекции:
Код |
---|
Sub IterateCollection() Dim st As Student Dim sts As Students Set sts = New Students ' Добавляем трёх студентов Set st = New Student st.Id = 11 sts.Add st Set st = New Student st.Id = 22 sts.Add st Set st = New Student st.Id = 33 sts.Add st ' Не работает!!! For Each st In sts MsgBox st.Id Next End Sub |
Чтобы данный код заработал, необходимо изменить класс Students. Выполняем те же действия, что и в Trick #1, только теперь необходимо в класс добавить следующую функцию (colStudents - коллекция; соответственно, необходимо вставить свою переменную):
Код |
---|
Public Function NewEnum() As IUnknown Attribute NewEnum.VB_UserMemId = -4 Set NewEnum = colStudents.[_NewEnum] End F unction |
Для теста снова запустите процедуру IterateCollection.
There is no knowledge that is not power