Поиск…
Синтаксис
- Атрибут VB_Name = "ClassOrModuleName"
- Атрибут VB_GlobalNameSpace = False 'Игнорируется
- Атрибут VB_Creatable = False 'Игнорируется
- Атрибут VB_PredeclaredId = {True | Ложь}
- Атрибут VB_Exposed = {True | Ложь}
- Атрибут variableName.VB_VarUserMemId = 0 'Zero указывает, что это член класса по умолчанию.
- Атрибут variableName.VB_VarDescription = "some string" 'Добавляет текст в информацию обозревателя объектов для этой переменной.
- Attribute procName.VB_Description = "some string" 'Добавляет текст в информацию обозревателя объектов для процедуры.
- Атрибут procName.VB_UserMemId = {0 | -4}
- '0: Делает функцию членом по умолчанию класса.
- '-4: Указывает, что функция возвращает Enumerator.
VB_Name
VB_Name указывает имя класса или модуля.
Attribute VB_Name = "Class1"
Новый экземпляр этого класса будет создан с помощью
Dim myClass As Class1
myClass = new Class1
VB_GlobalNameSpace
В VBA этот атрибут игнорируется. Он не был перенесен с VB6.
В VB6 он создает глобальный экземпляр по умолчанию класса («ярлык»), так что к членам класса можно получить доступ без использования имени класса. Например, DateTime
(как в DateTime.Now
) на самом деле является частью класса VBA.Conversion
.
Debug.Print VBA.Conversion.DateTime.Now
Debug.Print DateTime.Now
VB_Createable
Этот атрибут игнорируется. Он не был перенесен с VB6.
В VB6 он использовался в сочетании с атрибутом VB_Exposed
для контроля доступности классов за пределами текущего проекта.
VB_Exposed=True
VB_Creatable=True
Это приведет к Public Class
, к которому можно получить доступ из других проектов, но эта функциональность не существует в VBA.
VB_PredeclaredId
Создает глобальный экземпляр по умолчанию для класса. Экземпляр по умолчанию получает доступ через имя класса.
декларация
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "Class1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
Public Function GiveMeATwo() As Integer
GiveMeATwo = 2
End Function
Вызов
Debug.Print Class1.GiveMeATwo
В некотором смысле это моделирует поведение статических классов на других языках, но в отличие от других языков вы все равно можете создать экземпляр класса.
Dim cls As Class1
Set cls = New Class1
Debug.Print cls.GiveMeATwo
VB_Exposed
Управляет инстинктивными характеристиками класса.
Attribute VB_Exposed = False
Делает класс Private
. Он не может быть доступен за пределами текущего проекта.
Attribute VB_Exposed = True
Выдает класс Public
, вне проекта. Однако, поскольку VB_Createable
игнорируется в VBA, экземпляры класса не могут быть созданы напрямую. Это эквивалентно следующему классу VB.Net.
Public Class Foo
Friend Sub New()
End Sub
End Class
Чтобы получить экземпляр извне проекта, вы должны открыть фабрику для создания экземпляров. Один из способов сделать это - с помощью обычного Public
модуля.
Public Function CreateFoo() As Foo
CreateFoo = New Foo
End Function
Поскольку общедоступные модули доступны из других проектов, это позволяет нам создавать новые экземпляры наших классов Public - Not Createable
.
VB_Description
Добавляет текстовое описание к члену класса или модуля, который становится видимым в Проводнике объектов. В идеале все публичные члены публичного интерфейса / API должны иметь описание.
Public Function GiveMeATwo() As Integer
Attribute GiveMeATwo.VB_Description = "Returns a two!"
GiveMeATwo = 2
End Property
Примечание. Все элементы доступа к объекту ( Get
, Let
, Set
) используют одно и то же описание.
VB_ [вар] UserMemId
VB_VarUserMemId
(для переменных области модуля) и VB_UserMemId
(для процедур) используются в VBA в основном для двух вещей.
Указание члена класса по умолчанию для класса
Класс List
который будет инкапсулировать Collection
должен иметь свойство Item
, поэтому код клиента может сделать это:
For i = 1 To myList.Count 'VBA Collection Objects are 1-based
Debug.Print myList.Item(i)
Next
Но с атрибутом VB_UserMemId
установленным на 0 в свойстве Item
, код клиента может сделать это:
For i = 1 To myList.Count 'VBA Collection Objects are 1-based
Debug.Print myList(i)
Next
Только один член может юридически иметь VB_UserMemId = 0
в любом заданном классе. Для свойств укажите атрибут в Get
Access:
Option Explicit
Private internal As New Collection
Public Property Get Count() As Long
Count = internal.Count
End Property
Public Property Get Item(ByVal index As Long) As Variant
Attribute Item.VB_Description = "Gets or sets the element at the specified index."
Attribute Item.VB_UserMemId = 0
'Gets the element at the specified index.
Item = internal(index)
End Property
Public Property Let Item(ByVal index As Long, ByVal value As Variant)
'Sets the element at the specified index.
With internal
If index = .Count + 1 Then
.Add item:=value
ElseIf index = .Count Then
.Remove index
.Add item:=value
ElseIf index < .Count Then
.Remove index
.Add item:=value, before:=index
End If
End With
End Property
Создание класса с итерацией с помощью конструкции For Each
loop
С магическим значением -4
, атрибут VB_UserMemId
сообщает VBA, что этот член дает перечислитель, который позволяет клиенту сделать это:
Dim item As Variant
For Each item In myList
Debug.Print item
Next
Самый простой способ реализовать этот метод - вызвать скрытый [_NewEnum]
свойства [_NewEnum]
во внутренней / инкапсулированной Collection
; идентификатор должен быть заключен в квадратные скобки из-за ведущего подчеркивания, что делает его незаконным идентификатором VBA:
Public Property Get NewEnum() As IUnknown
Attribute NewEnum.VB_Description = "Gets an enumerator that iterates through the List."
Attribute NewEnum.VB_UserMemId = -4
Attribute NewEnum.VB_MemberFlags = "40" 'would hide the member in VB6. not supported in VBA.
'Gets an enumerator that iterates through the List.
Set NewEnum = internal.[_NewEnum]
End Property