UDT 能否以任何方式用作方法参数?

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

多年来,我一直避免在 VBA 中使用 Public Type UDT,因为它们很难传播,而且我从来没有真正费心去理解为什么……直到现在 -只需创建一个 class 模块并使用实际对象来代替就更容易了。

但最近我试了一下,一旦我认为它们必须被传递 ByRef(就像数组一样),事情开始看起来我可以开始使用它们了。

所以我在标准模块中定义了一个Public Type,得到了这个编译错误:

所以我将 Public Type 移动到 class 模块中,制作了 class PublicNotCreatable,然后得到了这个编译错误:


下面是一些重现编译错误的代码。

Class 模块“某物”:

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

如果将 TSomething 的定义移动到标准模块,您将得到另一个编译器错误,告诉您 public UDT 必须在 public 中定义对象模块(即 class 模块)...将您带回到原点。


所以如果你不能在class模块中定义一个Public Type,为什么编译器会抛出一个合适的问题甚至提到“public 在 public 对象模块中定义的用户定义类型”如果这样的东西不能合法存在?

它是否在 VB6 中工作并且编译器消息是该版本的残余?或者是 COM 工作方式的某个地方的原因?是我的问题还是两条错误消息相互矛盾?或者有什么我不明白的地方?

显然我 misusing/abusing UDT 在这里。那么,如果不是将“记录”传递给某种方法,它们应该用于什么?

从标准模块运行,没有任何错误。以下代码没有抛出任何错误。

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

UDT 的一个问题与前向引用有关。所以这不会编译,除此之外它与标准模块一起工作得很好。

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

编辑:

但是,在 class 中使用 UDT 的变通方法是 Friend

VBA 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

这里有一个类型作为参数传递给一个class方法,并被[=23]返回 =]方法。

首先是class SomeClass(不需要是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

和模块:

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