I have recently found out about VBIDE library, but I don't quite grap all of it's capabilities yet. I want to make a method that will instantiate correct Class based on classes found in my Project. Classes that fit as candidates to be instantiated Implement
InterfaceA
, and the exact class that I want to instantiate has property MType
and it returns Enumerated Value
Correct
.
So to sumarize how do I iterate over classes defined in my project in order to find Class that returns Correct
for Property MType
, and Instantiate that Class.
Thus far I know that I can Iterate over my modules with following code:
Dim Part As VBComponent
For Each Part In Application.VBE.ActiveVBProject.VBComponents
Debug.Print Part.Name
Next Part
What I am missing now how do I iterate over methods/properties of each class to find out what these mehods return?
Here is method I need to find, it varies from class to class by value it returns:
Public Property Get InterfaceA_MType() As Model_Types
IModel_MType = Severity
End Property
So as you can see this Property is pretty simple I am to assume that it will return same value all the time.
UPDATE: Per Dough Gancy's observation part of the answer is located in here
I can use ProcBodyLine(InterfaceA_MType)
and ProcCountLines(InterfaceA_MType)
to iterate over the procedure lines, match those lines witch one that has IModel_MType = Correct
.
This leaves out only instantiating the Class based on the Code Module. how do I do that?
First off, this doesn't iterate over your classes, it iterates over all modules in your file.
Dim Part As VBComponent For Each Part In Application.VBE.ActiveVBProject.VBComponents Debug.Print Part.Name Next Part
If you want to iterate over just the class modules, you'll need to check the component type.
Dim Part As VBComponent
For Each Part In Application.VBE.ActiveVBProject.VBComponents
If Part.Type = vbext_ct_ClassModule Then
Debug.Print Part.Name
End If
End If
Now, to find any particular method in a code module, you'll need to use the Find method of the CodeModule object.
Of special note, is the fact that startline
, endline
, startcol
, and endcol
are all passed by reference and are effectively "out" parameters.
So, that code would look something like this.
Dim startLine As Long
Dim endLine As Long
Dim startCol As Long
Dim endCol As Long
startLine = 1
startCol = 1
endLine = -1
endCol = -1
If Part.Find("Public Property Get InterfaceA_MType()", startLine, startCol, endLine, endCol) Then
' do something
End If
Finally, in order to create an instance of a class, it's going to necessarily be a global instance... which kind of smells, but whatever. You've not really given us your end goal. I have a feeling that your problem is better solved via some good OOP programming, but that's not the question you asked.
To get an instance of the class to work with, you'll need to dynamically create a module and procedure that instantiates an instance of that class. Perhaps even re-writes the calling code on the fly.
So, in this dynamically generated module, you'll need to write something like this.
Public dynamic As ClassType
Public Sub InitalizeDynamic()
Set dynamic = new ClassType
End Sub
Then, somewhere else, you would call the plain jane module sub with Application.Run
.
Public Sub Test1()
Application.Run "VBAProject.Module1.IntializeDynamic"
End Sub
So, that finally you could use the instance of dynamic.
foo = dynamic.InterfaceA_MType()
If you carefully read the questions I linked to with other answers of mine, you should be able to work out a solution. Everything you need to know is in the combination of those two answers.