Create a new object using the text name of the class

后端 未结 5 1593
刺人心
刺人心 2020-12-06 07:00

Is there a way to set an object to the new instance of a class by using the text name of the class?

I will have a library of classes, and depending on some other var

相关标签:
5条回答
  • 2020-12-06 07:15

    There's no reflection in VBA, so I don't think this is possible. You'd have to do something like the following I'm afraid:

    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
    

    Unless that is your CTest classes are defined in a COM DLL, in which case you could use the CreateObject statement. You would need to use VB6 to create such a DLL though, you can't create DLLs in Excel, Access, etc.

    Function GetTestClass(lngClassNo as long) as Object
    
        Set GetTestClass = CreateObject("MyDll.CTest" & lngClassNo)
    
    End Function
    
    0 讨论(0)
  • 2020-12-06 07:15

    You might be able to do it with a collection class or object array. All the objects are in one array.

    In your class have a .Name property and when you create an instance of it do this:

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

    Quick and dirty. The above example would return 10 CTest objects in a single object array. You could also ditch the .Name and just use CTest(n).

    0 讨论(0)
  • 2020-12-06 07:22

    You can use metaprogramming to do this, although it does seem like quite a hack. Here is an example that uses a couple of helper functions (omitted for brevity):

    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 讨论(0)
  • 2020-12-06 07:29

    CallByName function can help you. Let's say there are some class modules in your project: clsSample0, clsSample1 and clsSample2. Add a new class module named clsSpawner, which lists all target classes as public variables having the same names, and declared with New keyword:

    Public clsSample0 As New clsSample0
    Public clsSample1 As New clsSample1
    Public clsSample2 As New clsSample2
    

    In a standard module add Function Spawn() code:

    Function Spawn(sClassName) As Object
    
        Set Spawn = CallByName(New clsSpawner, sClassName, VbGet)
    
    End Function
    

    Test it with some code like this:

    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
    

    How does it work? Spawn function instantiates clsSpawner and calls the clsSpawner instance to return requested property, and actually clsSpawner instance creates a new instance of the target class due to declaration with New keyword and returns the reference.

    0 讨论(0)
  • 2020-12-06 07:34

    VB class definitions are really defining COM interfaces behind the scenes, so one can define data types as an abstract interface definition with concrete implementations using the implements keyword.

    To get any sort of polymorphism you have to do this, otherwise you will have problems with casting. It is somewhat fiddly but technically possible to do this with VB. If you want to dig into it find some of the advanced VB books by Dan Appleman or Matthew Kurland. I'm not sure if they're still in print but they're probably available through Amazon Marketplace.

    This works with VB6 and I'm fairly sure it works with VBA.

    0 讨论(0)
提交回复
热议问题