多年来,我一直避免在VBA中使用Public Type
UDT,因为他们很难传递,我从来没有真正费心去理解为什么......直到现在 - 只需创建一个类模块并使用实际对象就更容易了。
但是最近我给了它一个镜头,一旦我认为它们必须通过ByRef
(作为一个数组),事情开始看起来我可以开始使用它们了。
所以我在标准模块中定义了一个Public Type
,得到了这个编译错误:
所以我将Public Type
移到了一个类模块中,创建了类PublicNotCreatable
,然后得到了这个编译错误:
这里有一些代码可以重现编译错误。
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
的定义移动到标准模块,则会收到其他编译器错误,告诉您必须在公共对象模块(即类模块)中定义公共UDT ......让你回到原点。
因此,如果您无法在类模块中定义Public Type
,那么为什么编译器会在公共对象模块中定义适合甚至提及"公共用户定义的类型&# 34;如果这样的事情不能合法存在吗?
它在VB6中是否有效,编译器消息是该版本的残余?或者是COM如何工作的原因?它只是我或两个错误信息相互矛盾吗?还是有一些我不理解的东西?
显然我在这里滥用/滥用UDT。那么它们应该用于什么,如果不是用于传递"记录"某种方法?
答案 0 :(得分:3)
从标准模块可以正常工作,没有任何错误。以下代码没有错误。
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
编辑:
但是,在课堂上使用UDT的工作是Friend
班级的VBA代码
'/ 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
答案 1 :(得分:1)
这是一个Type作为参数传递给一个类方法,并通过类方法返回。
首先是课程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