Может ли класс расширить объект 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", когда "Сжатие и ремонт" не исправляет для меня вещи.