Существует ли способ перегрузиться, конструктор / инициализируют процедуру класса в VBA?

TFS не является примерно Управление исходным кодом. При использовании целого пакета, который TFS предлагает, отслеживание ошибок, сборки, отчеты, и т.д. тогда TFS является довольно серьезным выбором (конечно, лучше, чем Рациональный). TFS также интегрируется хорошо с Active Directory.

, Хотя, если Вы просто говорите о SCM, тогда я предпочитаю SubVersion. Мне действительно не нравится интеграция IDE. Мне также нравятся соглашение SVN Магистрального/Тега/Ответвления структуры и относительная простота переключения между ответвлениями. Слияние казалось легче в TFS все же. UI черепахи побеждает TFS'S БЕЗ ВСЯКИХ УСИЛИЙ хотя, особенно в отношении добавления файла к repo.

7
задан Tony Toews 17 November 2009 в 02:46
поделиться

3 ответа

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

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.

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

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.

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

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.

7
ответ дан 6 December 2019 в 19:38
поделиться

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

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

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

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

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

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

5
ответ дан 6 December 2019 в 19:38
поделиться

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

Dim x As New MyClass

x.Prop = 42 ' Before x.Prop is set, x is implicitly constructed
1
ответ дан 6 December 2019 в 19:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: