I have a problem referencing a windows object in VBA. it throws the following error: \"Error 5 (Invalid procedure call or argument). I cannot find the cause, because I see n
Something odd with that interface, it seems to only work with a copy of the control variable so:
Set winn = wins.Item(i + 0)
or
Set winn = wins.Item((i))
I believe here is what is happening.
The Item
method accepts a Variant
parameter.
When calling an external method that accepts a Variant parameter, VB likes to create and pass Variants that provide the value by reference - that is, with the VT_BYREF flag set.
However VB does not set this flag when sending out intermediate results (temporaries, not stored in a variable), which makes sense because even if the called method updates the value, no one will be able to see it.
So when you call .Item(i)
, VB sends out a Variant of type VT_I4 | VT_BYREF
, and when you call .Item(i + 0)
, a Variant of type VT_I4
is dispatched, without the VT_BYREF
.
In most situations the difference is not significant because VARIANT-aware methods should be able to cope with either. However this particular method does different things depending on exactly which VT_
it receives, and because of this it is explicitly willing to reject any VT_
s other than the three accepted ones. So in order to call it you need to trick VB into removing the byref flag.
Interestingly, when you declare the variable as Variant
, VB still dispatches a VT_VARIANT | VT_BYREF
, but the method seems to support this situation and correctly resolves to the pointed-to inner Variant that has the non-reference type of VT_I4
.
Note this has nothing to do with VB's ByVal
/ByRef
- this is about the internal structure of the VARIANT data type.