Есть ли способ перегрузить конструктор / инициализировать процедуру для класса в VBA? - PullRequest
7 голосов
/ 13 ноября 2009

В C # я знаю, что могу перегрузить конструктор для класса, указав его в теле класса:

public class MyClass()
{
    public MyClass(String s) { ... }
}

Это переопределяет конструктор по умолчанию (у которого нет параметров) и вызывает инициализацию класса с параметром s.

Я знаю, что в VBA я могу инициализировать свой класс с Private Sub Class_Initialize(), но я не знаю, есть ли способ заставить мой класс инициализироваться с параметрами. Можно ли это сделать?

Ответы [ 4 ]

7 голосов
/ 16 ноября 2009

Как указал Jtolle, это просто невозможно в VBA / VB6. Не существует идеального способа обойти эту проблему, но лично я создаю дополнительный вызов Public / Friend. Инициализируйте с параметрами, которые я хочу (в VBA / VB6 вы используете «необязательные» параметры для перегрузки), а затем вставьте быструю проверку. все открытые члены класса, которые выдают исключение, если вы пытаетесь получить к ним доступ без запуска метода initialize. Базовый пример может выглядеть так:

Option Explicit

Private m_blnInitialized As Boolean
Private m_lngID As Long
Private m_strFirstName As String

Public Sub Initialize(ByVal ID As Long, Optional ByVal someOtherThing As String = vbNullString)
    If m_blnInitialized Then Me.Clear
    m_lngID = ID
    m_strFirstName = SomeLookUp()
    If LenB(someOtherThing) Then
        ''Do something here.
    End If
    m_blnInitialized = True
End Sub

Public Property Get ID() As Long
    If Not m_blnInitialized Then Err.Raise eStandardErrors.eNotInitialized
    ID = m_lngID
End Property

Public Property Get FirstName() As String
    If Not m_blnInitialized Then Err.Raise eStandardErrors.eNotInitialized
    FirstName = m_strFirstName
End Property

Private Function SomeLookUp() As String
    ''perform magic on Me.ID
End Function

Public Sub LoadPicture()
    If Not m_blnInitialized Then Err.Raise eStandardErrors.eNotInitialized
    ''More magic
End Sub

Public Sub Clear()
    If Not m_blnInitialized Then Err.Raise eStandardErrors.eNotInitialized
    m_strFirstName = vbNullString
    m_lngID = 0&
    m_blnInitialized = False
End Sub

Это не здорово, но примерно так же хорошо, как и с VBA / VB6.

5 голосов
/ 16 ноября 2009

У вас уже есть два правильных ответа; вы не можете буквально иметь конструктор с параметрами в VBA.

Обходной путь Oorang в основном правильный - есть отдельный метод "init". Когда я использую объектно-ориентированный подход к чему-либо в Excel / VBA, я предпочитаю скрывать создание объектов и инициализацию в обычной функции. Так что я бы взял mkFoo (parm) и вызвал бы его, чтобы получить экземпляр Foo. mkFoo () создаст экземпляр New Foo и вызовет Foo.init (). Если вы только когда-либо создавали экземпляры таким образом, вам не нужно проверять, был ли ваш экземпляр инициализирован снова и снова.

Если вы действительно пытаетесь быть корректным и не предоставляете объекту, возможно, теперь опасный метод init (), вы можете использовать интерфейс IFoo (без метода init), который реализуется Foo. Затем mkFoo () возвращает IFoo, и любые пользователи фактического Foo вообще никогда не видят метод init ().

Конечно, теперь у вас есть куча модулей только для Foo - по одному для IFoo, по одному для каждого фактического класса Foo и по одному для вашей функции "Foo factory" ... таким образом, мой комментарий, что это одна из многих причин почему ООП в VBA - это PITA, даже если иногда это полезно.

РЕДАКТИРОВАТЬ: Это было редактирование onedaywhen вскоре после первоначального ответа, но я вытащил его отдельно только сейчас, поскольку это действительно отдельная мысль:

Говоря об Excel, вы можете переместить класс Foo в надстройку .xla и сделать класс PublicNotCreateable. Открытая функция mkFoo (parm) может находиться в стандартном модуле .bas в надстройке и поэтому вызывается как статический класс в C #. Это заставляет код клиента использовать mkFoo как единственный способ создания экземпляра Foo. Без сомнения, существует аналог MS Access для надстроек Excel .xla.

1 голос
/ 13 ноября 2009

Нет, классы не могут быть инициализированы с параметрами в VBA. Это не будет допустимо из-за Dim ... As New ... statement, который неявно создает объекты при первом обращении к ним.

Dim x As New MyClass

x.Prop = 42 ' Before x.Prop is set, x is implicitly constructed
0 голосов
/ 28 мая 2011

Методы конструктора класса и перегрузка конструктора класса В Visual Basic 6.0 обработчик события класса Initialize с именем Class_Initialize используется для выполнения кода, который должен быть выполнен в момент создания объекта.

В Visual Basic 2005 один или несколько конструкторов добавляются в класс для выполнения кода и инициализации переменных. Конструкторы - это методы в классе с именем New. Метод New может быть перегружен, чтобы обеспечить несколько конструкторов с именем New в одном и том же выражении класса.

Для получения дополнительной информации см. Новый (Visual Basic) или Использование конструкторов и деструкторов . http://msdn.microsoft.com/en-us/library/55yzhfb2(v=vs.80).aspx

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