Нет, не все типы имеют элемент по умолчанию.
Любой модуль класса может иметь член по умолчанию, указав специальный атрибут участника (вам нужно будет экспортировать и отредактировать файл кода вручную, чтобы сделать это, VBE не предоставляет никаких функций для этого):
Attribute {member name}.VB_UserMemId = 0
Только один член может быть членом по умолчанию.
Вы обнаруживаете гадость членов по умолчанию и почему их следует избегать.
VBA делает много вещей, чтобы «сделать нашу жизнь проще» (например, неявные преобразования типов), а элементы по умолчанию - одна из этих вещей.
Коллекция может хранить нестатические ссылки
Я не знаю, что такой «статический справочник» есть, но при сохранении ссылкиобъекта в Collection
, вы не хранить копия объекта, но ссылка.
Cells()
и другие объекты не имеют свойств по умолчанию, таких как .value
.
Global.Cells
- это параметризированное свойство getter, которое возвращает ссылку на объект Range
; Range.Cells
также является получателем, который возвращает объект Range
; в объектной модели Excel нет класса Cell
. Элементом по умолчанию Range
является его Value
. Но тогда, когда вы сделаете это:
Dim c As Collection
Set c = New Collection
c.Add ActiveSheet.Cells(1, 1)
Затем вы добавляете Range
ссылку, которая .Cells(1, 1)
возвращается, и тогда это:
Debug.Print c.Item(1)
Выведет, что Range
значение объекта. Тем не менее это:
Debug.Print TypeName(c.Item(1))
Вывод Range
.
Confusing? Да. Вот почему вы должны всегда указывать Option Explicit
, работать с переменными, объявленными с явным типом, насколько это возможно, избегать неявных преобразований типов, ... и избегать использования элементов по умолчанию.
Написав код, который читается точно так, как он должен себя вести, вы избегаете нескольких ловушек VBA, и когда вы в конце концов захотите изучить некоторые VB.NET или C#, вы не потеряете вообще о типе безопасности и ясности.
С the latest Rubberduck build (с открытым исходным кодом VBE добавить в проект, которым я управляю), вы можете указать класс членпо умолчанию со специальным комментарием ("аннотаций"):
'@DefaultMember
Public Property Get Foo()
End Property
Аннотации запускают результат проверки кода, который предупреждает о недостающем соответствующем атрибуте; запустив «синхронизировать аннотации/атрибуты» результата проверки, Rubberduck экспортирует модуль, добавляет атрибут VB_Attribute Foo.VB_UserMemId = 0
и повторно импортирует модуль для вас.
С другой стороны, если элемент имеет атрибут VB_UserMemId = 0
, но нет соответствующего @DefaultMember
аннотации, Rubberduck производит осмотр результат предупреждения о пропавшей аннотации, и предлагает быстро исправить, чтобы автоматически добавить ВЗ для вас.
Больше аннотаций существует, но выходит за рамки этого ответа. Просмотрите RD News сообщения блога для всей информации.
Значение по умолчанию часто зависит от контекста. Если вы добавите 'Cells (c, x)' в коллекцию, вы добавите * ссылку * к объекту Range. Если вы присваиваете 'Cells (c, x)' переменной * без *, используя 'Set', то это свойство по умолчанию будет занесено в переменную. –