Может ли класс расширить объект Collection?

Я пытаюсь расширить функциональность объекта VBA Collection в новом классе и сделать этот класс наследователем Collection, но оператор Implements Collection дает мне следующую ошибку:

Плохой интерфейс для инструментов: метод имеет название под своим именем.

Что подчеркивает?! Add, Item, Remove и Count являются единственными методами, перечисленными в документации для Collection. Все четверо без подчеркивания.

ИЗМЕНИТЬ. Чтобы уточнить, я создаю класс под названием UniformCollection (который принимает только те элементы, которые имеют одинаковый тип, вдохновленный этот подход). Я бы хотел, чтобы он реализовал Collection, так что UniformCollection является Collection и может использоваться вместо Collection при вызове методов других объектов и т.д.

Я знаю, что мне нужно написать делегирование методов/свойств для Add, Item и т.д. и свойство NewEnum для For Each для работы, и я уже сделал это.

Моя проблема в том, что оператор Implements Collection дает мне ошибку, указанную выше.

Бонусный вопрос: Count метод или свойство Collection? Помогает называть это свойством, но обозреватель объектов в редакторе VBA называет его функцией i.e. method (летающая желтая рамка).

Ответ 1

Вы используете одно из ограничений Реализации в VBA. Вы не можете реализовать другой класс, если у другого класса есть общедоступные методы или свойства с подчеркиванием в имени. Collection класс имеет _NewEnum, но любое подчеркивание вызовет проблему.

Например, если вы создали класс AddressClass, который имел следующее:

Public Address_City As String

Затем создан другой класс CustomerAddress:

Implements AddressClass

Private Property Get ClassInterface_Address_City() As String
End Property

Private Property Let ClassInterface_Address_City(ByVal RHS As String)
End Property

При компиляции вы получите сообщение об ошибке "Объектный модуль должен реализовать" Address_City "для интерфейса" AddressClass ". Изменение свойства на AddressCity приводит к ошибке.

Возможное решение:. Если я правильно понимаю, вы хотите реализовать класс коллекции, чтобы вы могли передать свой новый класс методам, принимающим коллекции в качестве параметров. Можно ли изменить эти методы? Мое предложение состояло в том, чтобы создать собственный класс коллекции MyCollection, а затем реализовать его. т.е. UniformMyCollection Таким образом, вы можете полностью избежать проблем с символами подчеркивания.

Что касается Count, я бы доверял обозревателю объектов через текст справки в любое время. С другой стороны, если вы создаете свой собственный класс коллекции, неважно, какой из них вы выберете.

Ответ 2

У VBA есть много ограничений на то, какие классы вы можете реализовать. NewEnum сбрасывает коллекцию, но даже если это не так, в этом классе может быть что-то еще, чтобы отключить ее. Я думаю, что он сообщает о первой проблеме, которую он обнаружил.

Поскольку у коллекции так мало свойств и методов, я просто переписываю их.

Private mcolParts As Collection

Public Sub Add(clsPart As CPart)
    mcolParts.Add clsPart, CStr(clsPart.PartID)
End Sub

Public Property Get Count() As Long
    Count = mcolParts.Count
End Property

Public Property Get Item(vItm As Variant) As CPart
    Set Item = mcolParts.Item(vItm)
End Property

Public Sub Remove(vIndex As Variant)
    mcolParts.Remove vIndex
End Sub

В не знаю, почему OB показывает методы (они выглядят как зеленые ящики для меня). Для моих денег методы меняют несколько свойств или взаимодействуют с чем-то вне класса. Все остальное - собственность. Я бы назвал оба свойства Count и Index.

Ответ 3

У Dick Kusleika больше всего, но если вы хотите использовать For Each в своем пользовательском классе, вам также понадобится:

'--- required additional property that allow to enumerate the collection with For Each
Public Property Get NewEnum() As IUnknown
    Set NewEnum = m_ColParts.[_NewEnum]
End Property

Это не обсуждается ни в одной из ссылок, которые я нашел в моих Избранных (этот или этот), но они оба заслуживают внимания. Если я найду сайт, который говорит о NewEnum, я сделаю Edit, чтобы добавить его.

ИЗМЕНИТЬ

Ни один из этих ссылок не тот, который я искал, но оба обсуждают свойство NewEnum (в том числе немного дополнительного voodoo, который добавляется для добавления):

Здесь и здесь.

Оба из них говорят о Excel, но VBA одинаково в других приложениях Office (в том числе необходимость импорта- > text edit- > import process для получения "Атрибутов" ).

Ответ 4

Re RolandTumble заметка на "NewEnum":

Мой собственный опыт в Access 2003 заключается в том, что "Для каждого" отлично работает, импортируя код, включая строку

Attribute NewEnum.VB_UserMemId = -4

... но после того, как я "декомпилирую" файл (переключатель командной строки), строка была удалена (проверена при экспорте), а функция "Для каждого" не работает.

К сожалению, мне нужно использовать "/decompile", когда "Сжатие и ремонт" не исправляет для меня вещи.