Search code examples
c#vbscriptcom

How to correctly pass object by type from C# to VBScript?


How to pass C# object to VBScript?

My C# class, that I want return is:

namespace GSM
{

    [Guid("9E5E5FB2-219D-4ee7-AB27-E4DBED8E125E")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("GSM.ParseResult")]
    public class ParseResult
    {
        public string Status;
        public HtmlNode table;

    }
}

I've Googled a lot of sites and most of them recommend to pass object[] as C# return value. In this case VBScript iterates and reconizes object types and values well. For example, the function, that returns it is something like this:

public object[] Parse(string userid, string password, string startDate, string endDate)
        {
            ParseResult parseResult = new ParseResult();
            parseResult.Status="OK";   

            object o = (object)parseResult;
            object[] oa = new object[] { o };
            return oa;     
        }

and VBScript, that working with it well:

Dim o
Set o = CreateObject("1C_GSM.TestComClass")
Dim a
a = o.Parse("51597", "********", "01-03-2017", "31-03-2017")
For Each entry In a
                Wscript.Echo TypeName(entry)
                Wscript.Echo entry
                Wscript.Echo entry.Status
Next

In this case three messages will be shown: ParseResult, GSM.ParseResult and OK.

But when I trying to change my function to

public ParseResult Parse(string userid, string password, string startDate, string endDate)
            {
                ParseResult parseResult = new ParseResult();
                parseResult.Status="OK"; 

                return parseResult;     
            }

and trying to call it in VBScript with code

Dim o
Set o = CreateObject("1C_GSM.TestComClass")
Dim a
a = o.Parse("51597", "********", "01-03-2017", "31-03-2017")
Wscript.Echo TypeName(a)
Wscript.Echo a
Wscript.Echo a.Status

messages will be are: String, GSM.ParseResult and message about exception with code 800A01A8 for line Wscript.Echo a.Status.

Why VBScript recognizes type of returned object as String, and no as my class type, if object was returned directly, but reconizes type as ParseResult, if returned value was wrapped to object[]?

How to force VBScript to recognize the type of returned object as ParseResult without wrapping it into the object[]?

Thank you!


Solution

  • You're going to kick yourself for this, but you just need to use Set a = o.Parse(...) instead of a = o.Parse(...).

    For those wondering why: a = o.Parse(...) is implicitly Let a = o.Parse(...). Let is used when assigning values, and Set is used when assigning objects. When using Let to assign an object, it's going to convert the object to a value. I don't recall the mechanism, but it probably uses standard COM techniques involving things like IDispatch and DISPID_VALUE. When this conversion is invoked, something in the .NET framework is either returning the ProgID or the full .NET Namespace.ClassName of your object.