Can UDT's be used as method parameters in any way?

非 Y 不嫁゛ 提交于 2019-12-12 14:45:38

问题


For years I've been avoiding the use of Public Type UDT's in VBA, because they're hard to pass around and I never really bothered trying to understand why.. until now - it was simply easier to just create a class module and work with actual objects instead.

But recently I gave it a shot, and once I figured they had to be passed ByRef (as an array would), things started to look like I could start using them.

So I defined a Public Type in a standard module, got this compile error:

So I moved the Public Type into a class module, made the class PublicNotCreatable, and then got this compile error:


Here's some code to reproduce the compile error.

Class module "Something":

Option Explicit
' cannot define a public user-defined type within an object module
Public Type TSomething
    Foo As Integer
End Type

Public Function Create(ByRef info As TSomething) As Something
End Function

If you move the definition of TSomething to a standard module, you'll get the other compiler error, telling you that the public UDT must be defined in a public object module (i.e. a class module)... which takes you back to square one.


So if you cannot define a Public Type in a class module, why would the compiler throw a fit and even mention "public user defined types defined in public object modules" if such a thing can't legally exist?

Did it work in VB6 and the compiler message is a remnant of that version? Or is the reason somewhere in how COM works? Is it just me or the two error messages are contradicting each other? Or there's something I'm not understanding?

Obviously I'm misusing/abusing UDT's here. So what are they supposed to be used for, if not for passing a "record" to some method?


回答1:


From standard module it works without any error. Following code threw no error.

Public Type TEST_TYPE
    Prop1   As String
End Type

Public Function fTest(ByRef param1 As TEST_TYPE) As String
    param1.Prop1 = "Hello from function"
End Function

Public Sub sTest(ByRef param1 As TEST_TYPE)
    param1.Prop1 = "Hello from Sub"
End Sub

Public Sub caller()

    Dim p   As TEST_TYPE

    '/Call Sub
    Call sTest(p)

    MsgBox p.Prop1

    '/Call Function
    Call fTest(p)

    MsgBox p.Prop1

End Sub

One issue with UDT is about Forward referencing. So this will not compile, apart from that It works perfectly fine with standard modules.

Public Type TEST_TYPE
    Prop1   As String
    Prop2   As TEST_TYPE2 '/ Fails due to Forward referencing. TEST_TYPE2 should be declared before this UDT.
End Type

Public Type TEST_TYPE2
    Prop3   As String
End Type

Edit:

However, the work around to use the UDT in class is Friend

VBA Code for Class

'/ Using UDT in VBA-Class
Private Type TEST_TYPE3
    Prop3   As String
End Type

Public Sub caller()

    Dim p As TEST_TYPE3
    p.Prop3 = "Hello from Class"
    Call testClassUDT(p)

End Sub

Friend Sub testClassUDT(p As TEST_TYPE3)
    MsgBox p.Prop3
End Sub



回答2:


Here's a Type being passed as a parameter to a class method, and being returned by a class method.

First the class SomeClass (doesn't need to be PublicNotCreatable)

Option Explicit

Sub test(foo As TFooBar)
  Dim s As String
  s = foo.foo
End Sub

Function ReturnTFoo() As TFooBar
  ReturnTFoo.bar = "bar"
  ReturnTFoo.foo = " bar"
End Function

And the Module:

Option Explicit

Public Type TFooBar
  foo As String
  bar As String
End Type

Sub test()
  Dim c As SomeClass
  Set c = New SomeClass
  Dim t1 As TFooBar
  Dim t2 As TFooBar
  t1.bar = "bar"
  t1.foo = "Foo"
  c.test t1

  t2 = c.ReturnTFoo
End Sub


来源:https://stackoverflow.com/questions/38361276/can-udts-be-used-as-method-parameters-in-any-way

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!