Данный материал является переводом оригинальной статьи "Christopher J. McClellan : VB Attributes: What are they and why should we use them?".
Знаете ли вы, что в ваших проектах Visual Basic есть код, который вы не видите в редакторе? Хотите увидеть его? (Конечно же, хотите!)
Итак, просто щелкните правой кнопкой мыши любой модуль и выберите пункт меню "Export File…".
Сохраните файл в удобном месте и откройте его в любом текстовом редакторе, например Notepad++.
И здесь мы видим скрытый заголовок, который есть во всех ваших классах и модулях VBA. Однако, насколько известно, только три из них делают что-либо в Visual Basic.
- VB_Name
- VB_PredeclaredId
- VB_Exposed
VB_Name говорит само за себя, он хранит имя, которое вы ему дали, в окне свойств. VB_PredeclaredId намного интереснее. Если вы измените значение VB_PredeclaredId на true в файле класса, этот класс получит глобальный экземпляр по-умолчанию, когда ваш код запускается. Нынче, global - это плохо, все об этом знают, так что пользуйтесь с осторожностью, но эта возможность дает нам симулировать методы статического класса в нашем коде VBA. Что всё это значит? То, что мы можем получить доступ к методам класса без создания сперва нового экземпляра класса. Мы можем получить доступ к методам через наш глобальный дефолтный экземпляр.
Так, вместо:
Dim math As New clsMath
math.Add 1, 2
Можно сделать:
Math.Add 1, 2
Понятно, что пример так себе. Мы могли бы выполнить приведенный выше фрагмент кода с помощью обычного модуля, но он действительно позволяет нам делать несколько прикольных вещей.
Я не буду особо касаться оставшегося атрибута VB_Exposed, кроме как скажу, что он содержит значение свойство экземпляра класса. 1 == false. 2 == true. В VBA нет других значений. Они не были перенесены из VB6.
Но подождите, есть еще кое-что...
Это только заголовок, атрибуты уровня модуля. Существует также ряд атрибутов, которые можно применять к переменным (полям), свойствам и процедурам модуля. Синтаксис переменных немного отличается, так что начнем с него.
VB_VarUserMemId: Определяет порядок переменных в Object Broswer. Значение 0 (ноль) объявляет переменную членом класса по умолчанию.
VB_VarDescription: Значение этого атрибута будет отображаться в Object Broswer.
Итак, поместив этот код в наш модуль и повторно импортируя его обратно в наш проект, мы получим это в Object Browser:
Public FooCount As Integer
Attribute FooCount.VB_VarDescription = "Specifies the number of Foos"
Это позволяет нам разместить нашу документацию на видном месте, и то же самое работает для свойств и процедур, только мы убираем "Var" из атрибутов. Итак, измените наше общедоступное поле на доступное только для чтения свойство по умолчанию.
private pFooCount As Integer
Property Get FooCount() As Integer
Attribute FooCount.VB_Description = "Returns the number of Foos"
Attribute FooCount.VB_UserMemId = 0
FooCount = pFooCount
End Property
Теперь, когда у нас есть объект Class1, он по умолчанию вернет FooCount.
Dim cls As New Class1
Dim i As Integer
i = cls
' is equivalent to
i = cls.FooCount
Когда вы можете захотеть так сделать? Ну, например, когда вы хотите создать строго типизированную коллекцию. Это подводит нас к последней детали. Есть еще одно специальное значение для VB_UserMemId, это значение -4. Отрицательное 4 всегда означает, что помечаемая функция должна возвращать перечислитель [_NewEnum]. Этот образец взят из приведенной выше ссылки на переполнение стека (исправлено, чтобы сделать Item членом класса по умолчанию).
Public Property Get Item(index As Long) As cShape
Attribute Item.VB_UserMemId = 0
Set Item = myCustomCollection.Item(index)
End Property
Public Property Get NewEnum() As IUnknown
Attribute NewEnum.VB_UserMemId = -4
Attribute NewEnum.VB_MemberFlags = "40"
Set NewEnum = myCustomCollection.[_NewEnum]
End Property
Ниже приводится сводка синтаксиса и значений.
' Header
Attribute VB_Name = "ClassOrModuleName"
Attribute VB_GlobalNameSpace = False ' ignored
Attribute VB_Creatable = False ' ignored
Attribute VB_PredeclaredId = False ' a Value of True creates a default global instance
Attribute VB_Exposed = True ' Controls how the class can be instanced.
'Module Scoped Variables
Attribute variableName.VB_VarUserMemId = 0 ' Zero indicates that this is the default member of the class.
Attribute variableName.VB_VarDescription = "some string" ' Adds the text to the Object Browser information for this variable.
'Procedures
Attribute procName.VB_Description = "some string" ' Adds the text to the Object Browser information for the procedure.
Attribute procName.VB_UserMemId = someInteger
' 0: Makes the function the default member of the class.
' -4: Specifies that the function returns an Enumerator.
Обратите внимание, что в любом классе может быть только один член по умолчанию. У вас не может быть одновременно переменной-члена по умолчанию и процедуры по умолчанию.
Добавить комментарий