Может ли класс расширить объект Collection? - PullRequest
10 голосов
/ 21 апреля 2011

Я пытаюсь расширить функциональность объекта 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 называет его функцией, т. Е. Методом (летящий желтый прямоугольник).

Ответы [ 4 ]

6 голосов
/ 11 ноября 2011

Вы столкнулись с одним из ограничений Агрегатов в 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, я бы доверял Обозревателю Объектов над текстом справки в любое время. С другой стороны, если вы создаете свой собственный класс коллекции, не имеет значения, какой класс вы выберете.

6 голосов
/ 22 апреля 2011

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

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

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

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

4 голосов
/ 22 апреля 2011

Дик Куслейка имеет большую часть этого, но если вы хотите использовать 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, я сделаю правку, чтобы добавить его.

РЕДАКТИРОВАТЬ

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

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

Оба они говорят об Excel, но VBA одинакова в других приложениях Office (включая необходимость процесса export-> text edit-> import для получения «Attributes»).

3 голосов
/ 21 октября 2012

Примечание Роланда Тамбла о "NewEnum":

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

Attribute NewEnum.VB_UserMemId = -4

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

К сожалению, мне нужно использовать «/ Декомпилировать», когда «Сжатие и восстановление» не решает проблему для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...