views:

167

answers:

2

ok I have couple of .NET classes that I want to use in VBA. So I must register them through COM and all that. I think I have the COM registration figured out (finally) but now I need help with the syntax of how to create the objects. Here is some pseudo code showing what I am trying to do.

EDIT: Changed Attached Objects to return an ArrayList instead of a List

The .NET classes look like this...

public class ResourceManagment
{
    public ResourceManagment()
    {
        // Default Constructor
    }

    public static List<RandomObject> AttachedObjects()
    {
        ArrayList list = new ArrayList();
        return list;
    }
}

public class RandomObject
{
    // 
    public RandomObject(int someParam)
    {

    }

}

OK, so this is what I would like to do in VBA (demonstrated in C#) but I don't know how...

public class VBAClass
{
    public void main()
    {
        ArrayList myList = ResourceManagment.AttachedObjects();
        foreach(RandomObject x in myList)
        {
            // Do something with RandomObject x like list them in a Combobox
        }
    }
}

One thing to note is that RandomObject does not have a public default constructor. So I can not create an instance of it like Dim x As New RandomObject. MSDN says that you can not instantiate an object that doesn't have a default constructor through COM but you can still use the object type if it is returned by another method... Types must have a public default constructor to be instantiated through COM. Managed, public types are visible to COM. However, without a public default constructor (a constructor without arguments), COM clients cannot create an instance of the type. COM clients can still use the type if the type is instantiated in another way and the instance is returned to the COM client. You may include overloaded constructors that accept varying arguments for these types. However, constructors that accept arguments may only be called from managed (.NET) code.

Added: Here is my attempt in VB:

Dim count As Integer
count = 0
Dim myObj As New ResourceManagment
For Each RandomObject In myObj.AttachedObjects
    count = count + 1
Next RandomObject
+1  A: 

to get around this you need to create a RandomObjectFactory in your .net code and have this create the RandomObject instance to use in VBA

so something like this:

public class RandomObjectFactory
{
     public static Create(int someParam)
     {
          return new RandomObject(someParam);
     } 
}

you can extend this class to have more overloads of create methods to create different overloads of RandomObjects

UPDATE:

based on the correct understanding of the question this question and this one will probably be useful

Sam Holder
Well I am not really trying to "create" an instance of RandomObject from VBA. I am just trying to work with a list of RandomObjects that is created within the ResourceManagement class (managed .NET).
Jordan S
oh apologies I misread the question then. you want to know the vba syntax for a loop? your first problem is going to be that you have returned a generic list to the com side, but com doesn't support generics (you should have got a compiler warning starting that this was what you were trying to do.) are you able to access the ResourceManagement class in the VBA?
Sam Holder
Yes. In the VBA project I added a reference to the .NET assembly. Then in VBA I can do this "Dim myObj As New ResourceManagment" but then how do I call the AttachedObjects method.
Jordan S
As I was saying you can't see that method as it is generic and com doesn't support that. You need to add a new method which returns something that COM understands. I think there is probably a collection you could return, but to be safe I would return RandomObject[]. you can delegate that function to the existing one and return newList.ToArray(); I've not done much using .net com from VBA, so I'm not sure if you will be able to consume the array directly, but in c++ we ahd to use SafeArrays to access the com arrays. VBA support for com is probably much better, so that might be easier
Sam Holder
What about ArrayList instead of List?
Jordan S
Seems like ArrayList should work, edited the answer to link to a couple of questions that might be useful
Sam Holder
+1  A: 

Your problem is that the AttachedObjects() method is static. COM cannot do static methods. In COM, the only "static" operation you can do is "instantiate a class".

Therefore, in order to call the AttachedObjects method from VBA, simply make it non-static (i.e. remove the static keyword in its definition). Other than that, the method may remain exactly as it is now. And your VBA code seems OK too - should work once you modify the method.

And just in case it doesn't work, here's the next question: what error do you get exactly, and at what point?

Fyodor Soikin