Вопрос по vba, excel-vba, excel – VBA - Создать новый объект, используя текстовое имя класса

4

Есть ли способ установить объект в новый экземпляр класса, используя текстовое имя класса?

У меня будет библиотека классов, и в зависимости от какой-то другой переменной я хочу получить один из этих классов во время выполнения.

Например. У меня есть "CTest1", "CTest2", "CTest3"

Я бы имел функцию, аналогичную приведенной ниже

<code>Function GetTestClass(lngClassNo as long) as Object

 Dim strClassName as String    
 strClassName = "CTest" & CStr(lngClassNo)

 Set GetTestClass = New instance of class(strClassName)

End Function
</code>

Ваш Ответ

6   ответов
2

ами, поэтому можно определить типы данных как абстрактное определение интерфейса с конкретными реализациями, используяинвентарь ключевое слово.

Чтобы получить любой вид полиморфизма, вы должны сделать это, иначе у вас будут проблемы с приведением. Это несколько сложно, но технически возможно сделать с VB. Если вы хотите углубиться в это, найдите некоторые из продвинутых книг VB Дэна Эпплмана или Мэтью Курланда. Я не уверен, что они все еще находятся в печати, но они, вероятно, доступны через Amazon Marketplace.

Это работает с VB6 и I 'mfairly уверен, что это работает с VBA.

Error: User Rate Limit Exceeded MT.
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
0

Все объекты находятся в одном массиве.

В вашем классе есть свойство .Name, и когда вы создаете его экземпляр, сделайте это:

Dim CTest() as New CTest
For n = 1 to 10
    Redim Preserve CTest(n)
    CTest(n).Name = "CTest" & CStr(n)
Next l

Быстро и грязно. Приведенный выше пример возвращает 10 объектов CTest в одном массиве объектов. Вы также можете отказаться от .Name и просто использовать CTest (n).

2

я знаю, что это старая тема, но если вам все еще нужен ответ, посмотрите здесь

http://www.codeproject.com/Articles/164036/Reflection-in-VBA-a-CreateObject-function-for-VBA

Это должно ответить на ваш вопрос.

Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededSet x = Application.Run("ClassName")Error: User Rate Limit ExceededxError: User Rate Limit Exceeded
4

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

Function GetTestClass(lngClassNo as long) as Object

    Select Case lngClassNo
    Case 1
        Set GetTestClass = New CTest1
    Case 2
        Set GetTestClass = New CTest2
    ...

    End Select

End Function

Если это не ваши классы CTest определены в COM DLL, в этом случае вы можете использовать оператор CreateObject. Вам нужно будет использовать VB6 для создания такой библиотеки DLL, однако вы не можете создавать библиотеки DLL в Excel, Access и т. Д.

Function GetTestClass(lngClassNo as long) as Object

    Set GetTestClass = CreateObject("MyDll.CTest" & lngClassNo)

End Function
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded MT.
Error: User Rate Limit Exceeded MT.
Error: User Rate Limit Exceeded
3

Вы можете использовать метапрограммирование, чтобы сделать это, хотя это кажется довольно взломать. Вот пример, который использует несколько вспомогательных функций (опущено для краткости):

Public Function CreateInstance(typeName As String) As Object
    Dim module As VBComponent
    Set module = LazilyCreateMPCache()

    If Not FunctionExists(typeName, module) Then
        Call AddInstanceCreationHelper(typeName, module)
    End If

    Dim instanceCreationHelperName As String
    instanceCreationHelperName = module.name & ".GetInstanceOf" & typeName
    Set CreateInstance = Application.Run(instanceCreationHelperName)
End Function

Sub AddInstanceCreationHelper(typeName As String, module As VBComponent)
   Dim strCode As String
   strCode = _
   "Public Function GetInstanceOf" & typeName & "() As " & typeName & vbCrLf & _
       "Set GetInstanceOf" & typeName & " = New " & typeName & vbCrLf & _
   "End Function"
   Call AddFunction(strCode, module)
End Sub
0

CallByName Функция может помочь вам. Допустим, в вашем проекте есть несколько модулей классов:clsSample0, clsSample1 а такжеclsSample2, Добавьте новый модуль класса с именемclsSpawner, который перечисляет все целевые классы как открытые переменные, имеющие одинаковые имена с e. г.instance_ префикс и объявлен сNew ключевое слово:

Public instance_clsSample1 As New clsSample1
Public instance_clsSample2 As New clsSample2

В модуль добавитьFunction Spawn() код:

Function Spawn(sClassName) As Object

    Set Spawn = CallByName(New clsSpawner, "instance_" & sClassName, VbGet)

End Function

Протестируйте его с помощью следующего кода:

Sub TestSpawn()

    Dim objSample0a As Object
    Dim objSample0b As Object
    Dim objSample1 As Object
    Dim objSample2 As Object

    Set objSample0a = Spawn("clsSample0")
    Set objSample0b = Spawn("clsSample0")
    Set objSample1 = Spawn("clsSample1")
    Set objSample2 = Spawn("clsSample2")

    Debug.Print TypeName(objSample0a)            ' clsSample0
    Debug.Print TypeName(objSample0b)            ' clsSample0
    Debug.Print objSample0a Is objSample0b       ' False
    Debug.Print TypeName(objSample1)             ' clsSample1
    Debug.Print TypeName(objSample2)             ' clsSample2

End Sub

Как это работает?Spawn функция создаетclsSpawner и называетclsSpawner экземпляр для возврата запрошенного свойства и собственноclsSpawner экземпляр создает новый экземпляр целевого класса из-за объявления сNew ключевое слово и возвращает ссылку.

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