Raphaël
Raphaël

Reputation: 427

C# COM Object VBA function or interface marked as restricted or the function uses an automation type not supported

I have the following C# COM Object :

[ComVisible(true), GuidAttribute("FD87D0EA-1D00-4189-801A-987D5F8ABD2C")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IRegistration
{
    string RegisterForm(string server, string database, string username, string password, string catalogId, string date, string AxyaContextFile);
    void RegisterFormAcknowledge(string server, string database, string username, string password, long formId, bool isPrinted, string message);
}

When I call the method RegisterFormAcknowledge from Word 200, I get the following compilation exception : function or interface marked as restricted or the function uses an automation type not supported

Here is the Word macro code

    Set printer = New MyCOMObject.Registration
    printer.RegisterFormAcknowledge "test", "test", "test", "test", 12345, False, "CatalogWordTemplate Not Found"

Does anyone has an idea why ? Long type are not supported by VB6 ? The first method RegisterForm is working well.

Upvotes: 1

Views: 3144

Answers (2)

acelent
acelent

Reputation: 8135

C#'s long is a signed 64-bit integer, which is not automation-compatible. On the other hand, C#'s int is a signed 32-bit integer, which is automation-compatible.

You asked about large integers, such as 372036854775807.

This one in particular needs 49 bits to represent. C#'s double is a standard double float, which can represent integers that require up to 53 bits.

There's also C#'s decimal, which maps to e.g. VBA's Decimal (inside a VARIANT). If you wish, you can marshal it as e.g. VBA's Currency, a signed 64-bit integer, with the [MarshalAs(UnmanagedType.Currency)] attribute before the argument definition.

For larger values, you should probably be better off using a string. That is, if you can actually deal with them in VBA.

Upvotes: 2

Hans Passant
Hans Passant

Reputation: 942197

  [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

That's a mistake, VB6 and VBA require a dispatch interface. Boilerplate is to use ComInterfaceType.InterfaceIsAutoDual so that the client code can use both early and late-binding. You almost surely need to fix the [ClassInterface] attribute on the class that implements this interface as well, given that you could actually make calls, use ClassInterfaceType.None

Using long as an argument type isn't going to fly, it is not a type supported in VB6. VB1 started life as a 16-bit tool so Integer is 16-bits and Long is 32-bits. No type for 64-bit integrals. Use int if a VB6 Long was intended. If not then you'll need to consider Double, gets you up to 15 digits, or String.

Upvotes: 4

Related Questions