Search code examples
.netvbacominterop

.NET types wrongly exposed in VBA


I am trying to understand this weird behaviour in VBA. I have two .NET classes, which inherit interfaces and exposed to COM. I register for COM interop and in VBA I encounter this weird behaviour where the objects show types from incorrect interface. Well explained in code as below:

C# Class:

namespace ComTest
{
    [ComDefaultInterface(typeof(ITestClass))]
    [ClassInterface(ClassInterfaceType.None)]
    public class TestClass : ITestClass
    {
        public string TestMethod()
        {
            return "Version 2-PROD Version";
        }
    }

    [ComDefaultInterface(typeof(ITestTrade))]
    [ClassInterface(ClassInterfaceType.None)]
    public class TestTrade : ITestTrade
    {
        public string TradeName { get; set; }
        public int QuantityNumber { get; set; }
    }
}

In Excel VBA:

Dim objTestClass As ComTest.TestClass
Set objTestClass = New ComTest.TestClass
Dim str As String
objTestClass. ---> I GET ITestTrade methods in objTestClass

Dim tTestTrade As ComTest.TestTrade
Set tTestTrade = New ComTest.TestTrade
tTestTrade. -----> I GET ITestClass methods in tTestTrade

But, if I remove 'ComTest' and simply use the class names, this works fine. i.e,

Dim objTestClass As TestClass
Set objTestClass = New TestClass
Dim str As String
objTestClass. ---> I GET ITestClass types

Dim tTestTrade As TestTrade
Set tTestTrade = New TestTrade
tTestTrade. -----> I GET ITestTrade

Can someone please help me understand this.


Solution

  • I didn't find exact reason as to why it happened. But apparently something had gone wrong in my tlb registration and the way in which I had my types exposed to COM. This might help for someone if you had similar issues:

    I was able to stop it by:

    • Having a assembly guid attribute for the assembly. (in the assemblyinfo.cs)
    • Specifically mentioning the GUID attribute for every class and exposes interfaces.
    • And using the below way to expose the .Net classes

      [ComVisible(true)]
      [ComDefaultInterface(typeof(IEvfExternalClient))]
      [ClassInterface(ClassInterfaceType.None)]
      public class EvfExternalClient : IEvfExternalClient
      {
      }