Home All Groups Group Topic Archive Search About

compile error Only udts defined in public object modules can be coerced ...

Author
7 Aug 2010 3:45 PM
mp
more an observation than a question, but I welcome any discussion that
follows....

seems strange i can't define a private udt inside a private class and pass
it to private/or public proceedures inside the class itself.

compile error
Only user-defined types defined in public object modules can be coerced to
or from a variant or passed to late-bound functions

the error occurs because i tried to add a udt to a collection(thus casting
to variant)
'Private Type tDims
'  DimStartPoint As Variant
'  DimEndPoint As Variant
'  DimTextOverride As String
'End Type
'Private Sub AddToDimsCollection(otDim As tDims)
      mColDims.Add otDim

i have solved my actual problem by converting the udt to a class - so this
is more a question for information sake

initially i thought i'd try a udt since there were only 3 properties and I
thought since it was all private in the same class i wouldn't get the
private/public compile error i get whenever I try to (mis-)use a udt.

the normal fix to use a udt that i've seen so far is the udt has to be
defined public in a public bas module.
in this case the error says has to be public object module which i don't
think (?)   a bas module qualifies
(and it didn't work when i tried so i think thats right)

the other fix might be to make the class instancing public/not creatable but
i don't think i want to use that, when i'm simply trying to use a simple udt
to pass a couple values
the other fix i've seen is declare the sub Friend rather than Private but
that didn't work either since the error is still trying to put the udt into
a collection

i have had almost no luck trying to use a simple udt if it has to be passed
anywhere due to all the strange(to me) limitations (really the limitations
of my knowledge)
it's just always been easier to create a class instead than try to figure
out what hoops to jump through to use a simpler(i would have thought)
construct.

thanks
mark

Author
7 Aug 2010 4:36 PM
Jim Mack
mp wrote:

Did you try 'Friend'?

--
   Jim Mack
   Twisted tees at http://www.cafepress.com/2050inc
   "We sew confusion"



Show quoteHide quote
> more an observation than a question, but I welcome any discussion
> that follows....
>
> seems strange i can't define a private udt inside a private class
> and pass it to private/or public proceedures inside the class
> itself.
>
> compile error
> Only user-defined types defined in public object modules can be
> coerced to or from a variant or passed to late-bound functions
>
> the error occurs because i tried to add a udt to a collection(thus
> casting to variant)
> 'Private Type tDims
> '  DimStartPoint As Variant
> '  DimEndPoint As Variant
> '  DimTextOverride As String
> 'End Type
> 'Private Sub AddToDimsCollection(otDim As tDims)
>       mColDims.Add otDim
>
> i have solved my actual problem by converting the udt to a class -
> so this is more a question for information sake
>
> initially i thought i'd try a udt since there were only 3
> properties and I thought since it was all private in the same class
> i wouldn't get the private/public compile error i get whenever I
> try to (mis-)use a udt.
>
> the normal fix to use a udt that i've seen so far is the udt has to
> be defined public in a public bas module.
> in this case the error says has to be public object module which i
> don't think (?)   a bas module qualifies
> (and it didn't work when i tried so i think thats right)
>
> the other fix might be to make the class instancing public/not
> creatable but i don't think i want to use that, when i'm simply
> trying to use a simple udt to pass a couple values
> the other fix i've seen is declare the sub Friend rather than
> Private but that didn't work either since the error is still trying
> to put the udt into a collection
>
> i have had almost no luck trying to use a simple udt if it has to
> be passed anywhere due to all the strange(to me) limitations
> (really the limitations of my knowledge)
> it's just always been easier to create a class instead than try to
> figure out what hoops to jump through to use a simpler(i would have
> thought) construct.
>
> thanks
> mark
Author
8 Aug 2010 3:59 PM
mp
"Jim Mack" <no-uce-***@mdxi.com> wrote in message
news:l7OdnXrOkLUTFsDRnZ2dnUVZ_sydnZ2d@giganews.com...
> mp wrote:
>
> Did you try 'Friend'?
>
> --
>   Jim Mack
>   Twisted tees at http://www.cafepress.com/2050inc
>   "We sew confusion"
>

yes, as i mentioned the collection.add still didn't like it

Show quoteHide quote
>> the other fix i've seen is declare the sub Friend rather than
>> Private but that didn't work either since the error is still trying
>> to put the udt into a collection
>
Author
7 Aug 2010 4:58 PM
Kevin Provance
Top posted (feeling lazy today):

I think I read somewhere declaring such things as Friend, versus Private or
Public solves this.

--
Customer Hatred Knows No Bounds at MSFT
Free usenet access at http://www.eternal-september.org
ClassicVB Users Regroup! comp.lang.basic.visual.misc

Bawwk!  Paulie want a dingleball, bawwk!
Show quoteHide quote
"mp" <nospam@Thanks.com> wrote in message
news:i3jv2i$c0k$1@news.eternal-september.org...
: more an observation than a question, but I welcome any discussion that
: follows....
:
: seems strange i can't define a private udt inside a private class and pass
: it to private/or public proceedures inside the class itself.
:
: compile error
: Only user-defined types defined in public object modules can be coerced to
: or from a variant or passed to late-bound functions
:
: the error occurs because i tried to add a udt to a collection(thus casting
: to variant)
: 'Private Type tDims
: '  DimStartPoint As Variant
: '  DimEndPoint As Variant
: '  DimTextOverride As String
: 'End Type
: 'Private Sub AddToDimsCollection(otDim As tDims)
:      mColDims.Add otDim
:
: i have solved my actual problem by converting the udt to a class - so this
: is more a question for information sake
:
: initially i thought i'd try a udt since there were only 3 properties and I
: thought since it was all private in the same class i wouldn't get the
: private/public compile error i get whenever I try to (mis-)use a udt.
:
: the normal fix to use a udt that i've seen so far is the udt has to be
: defined public in a public bas module.
: in this case the error says has to be public object module which i don't
: think (?)   a bas module qualifies
: (and it didn't work when i tried so i think thats right)
:
: the other fix might be to make the class instancing public/not creatable
but
: i don't think i want to use that, when i'm simply trying to use a simple
udt
: to pass a couple values
: the other fix i've seen is declare the sub Friend rather than Private but
: that didn't work either since the error is still trying to put the udt
into
: a collection
:
: i have had almost no luck trying to use a simple udt if it has to be
passed
: anywhere due to all the strange(to me) limitations (really the limitations
: of my knowledge)
: it's just always been easier to create a class instead than try to figure
: out what hoops to jump through to use a simpler(i would have thought)
: construct.
:
: thanks
: mark
:
:
Author
7 Aug 2010 5:51 PM
ralph
Show quote Hide quote
On Sat, 7 Aug 2010 10:45:21 -0500, "mp" <nospam@Thanks.com> wrote:

>more an observation than a question, but I welcome any discussion that
>follows....
>
>seems strange i can't define a private udt inside a private class and pass
>it to private/or public proceedures inside the class itself.
>
>compile error
>Only user-defined types defined in public object modules can be coerced to
>or from a variant or passed to late-bound functions
>
>the error occurs because i tried to add a udt to a collection(thus casting
>to variant)
>'Private Type tDims
>'  DimStartPoint As Variant
>'  DimEndPoint As Variant
>'  DimTextOverride As String
>'End Type
>'Private Sub AddToDimsCollection(otDim As tDims)
>      mColDims.Add otDim
>

You are sort of hammering on two separate problems.
To answer the last one first - you can not store a UDT in a VB
Collection.

One way to get around that is to write your own Collection based on an
Array. You can store UDTs in VB Arrays.

There are several examples on the web. Here is one to get you started.
http://www.mvps.org/vbvision/collections.htm

As for the first question - you need to declare/define the UDT in a
Public Module. That means using a Public Base module, or Friend, or
writing a Type Library for the UDT (the latter essentially serves as a
"Public Module".

Or you might consider combining your custom collection with an Object
in an ActiveX Dll which you could use with your project.
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q185700

Anyway, just fuel for thought.

-ralph
Author
7 Aug 2010 6:03 PM
ralph
On Sat, 07 Aug 2010 12:51:14 -0500, ralph <nt_consultin***@yahoo.net>
wrote:


>
>Anyway, just fuel for thought.
>

Forgot to mention the possiblitity of storing the UDT as an Array()
object (the VB Array object). You can store Array()s in a Variant, and
thus in a Collection.

Ugly, but have seen it done. <g>

-ralph
Author
8 Aug 2010 12:37 AM
Tom Shelton
After serious thinking ralph wrote :
Show quoteHide quote
> On Sat, 7 Aug 2010 10:45:21 -0500, "mp" <nospam@Thanks.com> wrote:
>
>> more an observation than a question, but I welcome any discussion that
>> follows....
>>
>> seems strange i can't define a private udt inside a private class and pass
>> it to private/or public proceedures inside the class itself.
>>
>> compile error
>> Only user-defined types defined in public object modules can be coerced to
>> or from a variant or passed to late-bound functions
>>
>> the error occurs because i tried to add a udt to a collection(thus casting
>> to variant)
>> 'Private Type tDims
>> '  DimStartPoint As Variant
>> '  DimEndPoint As Variant
>> '  DimTextOverride As String
>> 'End Type
>> 'Private Sub AddToDimsCollection(otDim As tDims)
>>      mColDims.Add otDim
>>
>
> You are sort of hammering on two separate problems.
> To answer the last one first - you can not store a UDT in a VB
> Collection.
>

Yes you can.  It's all about how you define it - it needs to be in a
typelib.  And the way you do that?  You define it in a public class
module in an activex dll or exe.


' in a class1.cls in an activex dll (Instancing = MultiUse)

Public Type myType1
    i As Integer
End Type

Public Sub Bar(ByRef z As myType1)
    MsgBox z.i
End Sub


' form1 of a standard exe - referencing the above:
Private Sub Form_Load()
    Dim coll As Collection
    Dim st As myType1

    Set coll = New Collection
    st.i = 10
    coll.Add st

    MsgBox coll(1).i
End Sub


> One way to get around that is to write your own Collection based on an
> Array. You can store UDTs in VB Arrays.
>

I generally did that anyway.  The collection object is sort of a hog...

> There are several examples on the web. Here is one to get you started.
> http://www.mvps.org/vbvision/collections.htm
>
> As for the first question - you need to declare/define the UDT in a
> Public Module. That means using a Public Base module, or Friend, or
> writing a Type Library for the UDT (the latter essentially serves as a
> "Public Module".
>
> Or you might consider combining your custom collection with an Object
> in an ActiveX Dll which you could use with your project.
> http://support.microsoft.com/default.aspx?scid=kb;EN-US;q185700

If you define your type in a activex dll, then you can use the regular
collection object if you like.  I prefer a custom collection usually
because I could make it faster anyway...

--
Tom Shelton
Author
8 Aug 2010 5:19 AM
ralph
On Sat, 07 Aug 2010 18:37:22 -0600, Tom Shelton
<tom_shelton@comcast.invalid> wrote:

Show quoteHide quote
>After serious thinking ralph wrote :
>> On Sat, 7 Aug 2010 10:45:21 -0500, "mp" <nospam@Thanks.com> wrote:
>>
>>> more an observation than a question, but I welcome any discussion that
>>> follows....
>>>
>>> seems strange i can't define a private udt inside a private class and pass
>>> it to private/or public proceedures inside the class itself.
>>>
>>> compile error
>>> Only user-defined types defined in public object modules can be coerced to
>>> or from a variant or passed to late-bound functions
>>>
>>> the error occurs because i tried to add a udt to a collection(thus casting
>>> to variant)
>>> 'Private Type tDims
>>> '  DimStartPoint As Variant
>>> '  DimEndPoint As Variant
>>> '  DimTextOverride As String
>>> 'End Type
>>> 'Private Sub AddToDimsCollection(otDim As tDims)
>>>      mColDims.Add otDim
>>>
>>
>> You are sort of hammering on two separate problems.
>> To answer the last one first - you can not store a UDT in a VB
>> Collection.
>>
>
>Yes you can. 

Not really. Or rather not in the way the OP was trying to do it as
demostrated or noted in the title.

The OP made it known he already knew where the problem was - "the
error is still trying to put the udt into a collection" and that is
because (like the error says) You can't coerce a UDT to Variant unless
it is defined in a Public Object, therefore he couldn't store the UDT
in a VB Collection. I expanded on that, but went back and deleted it
to make the post smaller, also unfortunately destroying the sense of
what I was trying to say.


> ... It's all about how you define it - it needs to be in a
>typelib.  And the way you do that?  You define it in a public class
>module in an activex dll or exe.
>

Ta Dah!

-ralph
Author
8 Aug 2010 7:30 AM
Larry Serflaten
"ralph" <nt_consultin***@yahoo.net> wrote

> > ... It's all about how you define it - it needs to be in a
> >typelib.  And the way you do that?  You define it in a public class
> >module in an activex dll or exe.
> >
>
> Ta Dah!


.... more Registry refuse....

<g>
LFS
Author
8 Aug 2010 12:48 AM
Kevin Provance
:
: There are several examples on the web. Here is one to get you started.
: http://www.mvps.org/vbvision/collections.htm

Bryan, um...Spafford?  There was a guy who knew his stuff.  Ken Halter too.
Two names I miss around these parts.
Author
7 Aug 2010 7:17 PM
Larry Serflaten
"mp" <nospam@Thanks.com> wrote

> initially i thought i'd try a udt since there were only 3 properties and I
> thought since it was all private in the same class i wouldn't get the
> private/public compile error i get whenever I try to (mis-)use a udt.

If you can keep it all private, you should not see a problem.

EG: A UDT declared as Private in a class can be passed to
Private routines within the class.


> i have had almost no luck trying to use a simple udt if it has to be passed
> anywhere due to all the strange(to me) limitations (really the limitations
> of my knowledge)
> it's just always been easier to create a class instead than try to figure
> out what hoops to jump through to use a simpler(i would have thought)
> construct.

I find classes are the easier of the two as well.  With a class you get to
include a (sort of) constructor, (more like initialization...) and can control
the Read/Write access of the variables.

Classes can be passed hither and yon, and you have the otpion to use
an array or collection, whichever fits the need.

LFS
Author
8 Aug 2010 4:08 PM
mp
Show quote Hide quote
"Larry Serflaten" <serfla***@gmail.com> wrote in message
news:i3kbev$v14$1@news.eternal-september.org...
>
> "mp" <nospam@Thanks.com> wrote
>
>> initially i thought i'd try a udt since there were only 3 properties and
>> I
>> thought since it was all private in the same class i wouldn't get the
>> private/public compile error i get whenever I try to (mis-)use a udt.
>
> If you can keep it all private, you should not see a problem.
>
> EG: A UDT declared as Private in a class can be passed to
> Private routines within the class.
>
>
>> i have had almost no luck trying to use a simple udt if it has to be
>> passed
>> anywhere due to all the strange(to me) limitations (really the
>> limitations
>> of my knowledge)
>> it's just always been easier to create a class instead than try to figure
>> out what hoops to jump through to use a simpler(i would have thought)
>> construct.
>
> I find classes are the easier of the two as well.  With a class you get to
> include a (sort of) constructor, (more like initialization...) and can
> control
> the Read/Write access of the variables.
>
> Classes can be passed hither and yon, and you have the otpion to use
> an array or collection, whichever fits the need.
>
> LFS
>
>
agreed, I have almost always ended up going back to a class whenever i've
tried to use a udt, thinking at first it would be simpler.  every so often
though I see a situation i think ah a udt would work here...and i'm back to
discovering all the complications required (as noted in the above thread -
activex dlls, typelibs, etc )

in my simple apps it's never warranted the extra work involved to get there.
If i needed to optimize something that used lots of simple classes for which
udt's could substitute, it might be worth it in that case.

anyhow, I knew i'd enjoy and learn from the ensuing discussion, and wasn't
disappointed.
:-)
thanks to all for their insights
mark
Author
10 Aug 2010 8:36 AM
Dee Earley
On 07/08/2010 20:17, Larry Serflaten wrote:
> "mp"<nospam@Thanks.com>  wrote
>
>> initially i thought i'd try a udt since there were only 3 properties and I
>> thought since it was all private in the same class i wouldn't get the
>> private/public compile error i get whenever I try to (mis-)use a udt.
>
> If you can keep it all private, you should not see a problem.
>
> EG: A UDT declared as Private in a class can be passed to
> Private routines within the class.

The root problem being that the collection is NOT your code, it is
effectively, a public/external class that you're trying to pass it to,
for which the udt is not available.

There are various solutions presented by the others so I won't go into
them again.

--
Dee Earley (dee.ear***@icode.co.uk)
i-Catcher Development Team

iCode Systems

(Replies direct to my email address will be ignored.
Please reply to the group.)