1

I have a function of a COM object that returns an Array.

This code works

Dim a
a = obj.Foo
MsgBox a(0)

This code says that there is no enumeration. And it is true.

MsgBox obj.Foo(0)

Also this didn't worked

MsgBox (obj.Foo)(0)

The problem is that the Foo function is a simple property.

Is there a syntax to directly access the data member?

Edit: Just to make clear that the function works correctly IsArray(obj.Foo) returns true!

xMRi
  • 14,982
  • 3
  • 26
  • 59
  • You should be able to do something like `obj.Foo(0).get()` or `obj.Foo(0).FirstOrDefault()`. I am not entirely sure about how you get the result since I am not an expert in vb but I believe there should be something that can be called as I suggest. – Ali Beyit Dec 18 '19 at 10:36
  • @AliBeyit not in VBScript you can't. – user692942 Dec 18 '19 at 11:01
  • It depends what data type the COM object returns, VBScript expects a `VT_ARRAY` so you'll need to marshal the return type visible to COM. – user692942 Dec 18 '19 at 11:03
  • Does this answer your question? [How to correctly marshal VB-Script arrays to and from a COM component written in C#](//stackoverflow.com/a/5097474) – user692942 Dec 18 '19 at 11:45
  • The Array is a SAFEARRAY of VARIANTs. Otherwise the first method wouldn't work. – xMRi Dec 18 '19 at 12:06
  • To be honest, the question isn't clear, you have an array are you asking how to access it from VBScript, because you do that in your first example? Have you used `IsArray()` to check it's a valid VBScript array? – user692942 Dec 18 '19 at 12:10
  • Just to make clear that the function works correctly IsArray(obj.Foo) returns true! Is is. I can use UBound, for each and all this stuff. – xMRi Dec 18 '19 at 13:40
  • Okay, so what are you trying to do? – user692942 Dec 18 '19 at 13:52
  • I want to use the Array directly that is returned. Foo returns the array. Foo(0) should return the first element. But it doesn't it yield into a runtime error. Please read my question! Code 1 works, Code 2+3 not! – xMRi Dec 19 '19 at 14:30
  • The duplicate has nothing to do with my questions. I already statet that the array is a simple safe array of Variants. So it is all VBScript needed IsArray returns true! – xMRi Dec 20 '19 at 06:27

1 Answers1

1

I believe the problem here is that variant array returned via COM needs to become a VB collection object, which does not happen immediately.

It happens when there is an intermediate variable, but it does not yet happen in the case of expression. In the latter case VBScript already sees what it treats as an object, but this object is a thin wrapper over variant array and it is not yet a collection object.

If you want a VBS one liner, this would work out:

Function TrueArray(ByVal Value)
  TrueArray = Value
End Function

'MsgBox obj.Foo(0) -- Object not a collection: 'obj.Foo'
MsgBox TrueArray(obj.Foo)(0)

You can also implement a collection on the other side of property implementation and return it instead of safe array (ATL C++ code would use CComEnum<IEnumVARIANT... helper, example).

I realize that your question is more about built-in scripting language capability that does the required conversion. Perhaps you could use some of the built-in functions to perform a similar trick to TrueArray above.

Roman R.
  • 68,205
  • 6
  • 94
  • 158