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

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

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

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

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

Как указал Джтолл, это просто невозможно в VBA / VB6. Нет идеального способа обойти это, но я лично делаю создание подзаголовка Public / Friend Initialize с параметрами, которые я хочу (в VBA / VB6 вы используете опции «Необязательный» для перегрузки), а затем быстро проверяете все уязвимые члены classа, которые генерируют исключение, если вы попытаетесь получить к ним доступ, не запуская метод 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.

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

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

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

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

EDIT: Это было редактирование onedaywhen вскоре после первоначального ответа, но я вытащил его отдельно только сейчас, так как это действительно отдельная мысль:

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

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

 Dim x As New MyClass x.Prop = 42 ' Before x.Prop is set, x is implicitly constructed 

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

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

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