Search code examples
c#vbadllregistrationdynamics-sl

How can I fix Run-time error 430 from importing custom DLL in VBA project


I've struggle several hours on that and I can't find what I'm doing wrong.

I created a new C# dll project, here is the content of the only class it contain:

using System;
using System.Runtime.InteropServices;

namespace PolygonSl {

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    public class Config {

        [ComVisible(true)]
        public string GetCompany() {
            return "POL";
        }
    }
}

I basically remove everything from it trying to make it work, the only reference is System.

I checked the Make assembly COM-Visible flag on the Assembly Information and my project is signed (seams required for codebase).

It compiling fine, after that, I called RegAsm.exe, giving it my dll, I added /codebase and /tlb, the command is successful.

When I go to my VBA project, I can add my new tlb file to the references, working fine. After, I can use it in my code, the autocomplete is working and I can compile with no errors.

Then, when I execute, I got this:

Run-time error '430':
Class does not support Automation or does not support expected interface

Here is my code sample in the VBA:

Private Sub Button1_Click()
    'With CreateObject("PolygonSl.Config")
    With New PolygonSl.Config
        MessBox .GetCompany, MB_OK, "Test"
    End With
End Sub

I tried late binding and my code is running fine with it but I'd like to be able to use the autocomplete.

Anyone have a suggestion on what I could try to make it work?

Edit (Adding some details on my environment)

  • I work on VS2008 for projects related to Dynamics SL (one of the Microsoft ERPs)
  • I'm on Windows Server 2008 R8 Standard, running from VMWare
  • Compiling on Framework 3.5, Release, x86, Dynamics SL client is 32 bits
  • I tried my dll on Dynamics but also on Excel to be sure that the problem was not Dynamics ;)

Solution

  • I think you need to define an interface to be able to see getcompany.

    using System;
    using System.Runtime.InteropServices;
    
    namespace PolygonSl
    {
        [Guid("6DC1808F-81BA-4DE0-9F7C-42EA11621B7E")]
        [System.Runtime.InteropServices.ComVisible(true)]
        [System.Runtime.InteropServices.InterfaceType(ComInterfaceType.InterfaceIsDual)]
        public interface IConfig
        {
            string GetCompany();
        }
    
        [Guid("434C844C-9FA2-4EC6-AB75-45D3013D75BE")]
        [System.Runtime.InteropServices.ComVisible(true)]
        [System.Runtime.InteropServices.ClassInterface(ClassInterfaceType.None)]
        public class Config : IConfig
        {
            public string GetCompany()
            {
                return "POL";
            }
        }
    }
    

    You can generate the interface automatically by placing the cursor in the class definition and using Edit.Refactor.ExtractInterface.

    I'd have to admit that I'm at the absolute edge of my abilities here and the above is put together based on examples I've seen elsewhere.

    Edit

    The following test code works fine on my PC

    Option Explicit
    Sub polygontest()
    
        Dim my_polygon As SOPolygon.Config
        Set my_polygon = New SOPolygon.Config
        Debug.Print my_polygon.GetCompany
    
    End Sub
    

    Where SOPolygon is the project name.